ganymede
ganymede copied to clipboard
SSO: Invalid access token
When using SSO as authentication source, it seems that the refresh token isn't used because after about an hour or so the webpage cant do anything that requires authentication anymore and every few seconds a red message appears that says that the access toke is invalid.
What provider are you using? If you open the browser console (ctrl + shift + i) and click application > cookies, do you see a refresh token there?
I use authentik. Yes i see a refresh token
Also, is there a logout button anywhere in the frontend or am I just missing it?
There is a logout button in Profile > Logout but I just noticed I never updated the code to remove oauth cookies. You'll have to open the browser console and delete the Ganymede cookies to fully logout.
I was able to recreate the refresh token issue with the :latest
tag of Authentik. It appears Authentik is returning an invalid refresh toke (random characters that include . % $ which is invalid). I created a new Authentik instance using an older image tag 2023.1.2 and it worked without issue. So there is something with the latest release, not sure when the bug was introduced between the 2023.1.2
and latest
releases. What authentik version are you running? :latest
? I don't see any issues raised upstream, I'll take a closer look this weekend.
If you want an immediate fix you'll need to deploy an older image that works. If you do want to revert to an older version for this to work. Make a copy of your current data as rolling back could cause issues with any migrations that happened. I would make a new Authentik stack with new data folders or a copy of the old data folders.
Without SSO: Everything was working fine for a while, then suddenly I started getting this error.
Request Failed
Invalid access token
Looking at the network the Invalid access token
is a 401 error from
https://api.xxxx.com/api/v1/playback/last?limit=4
Also see another 401 error from
https://api.xxxx.com/api/v1/auth/refresh
Then tried using SSO.
Off topic, have you tried using authelia for SSO. After loggin in I just get a
{"message":"state cookie not found: http: named cookie not present"}
from
https://api.xxxx.com/api/v1/auth/oauth/callback?code=authelia_ac_sNFSO....
With all the ENV variables set according to the wiki.
Can you enable debug in ./data/config.json
(API container needs to be restart to take effect), and see if there are any errors relating to this?
Also, open a new browser, or incognito window, sign in, and see if the auth cookies are set in the "Application" tab of the browser console. The non-sso cookies are named access-token
and refresh-token
. Are the cookies for the correct domain? If you refresh, are you still logged in?
I haven't tried Authelia for SSO, did not know they had OIDC support. I'll take a look at it.
No debug messages related to any errors in logs after setting "debug": true
in the ./data/config.json
.
There are no cookies at all anymore, there was an SSO cookie related to authelia before I cleared it, for other testing purposes.
After refreshing I am no longer logged in.
Tried in normal browser, incognito and secondary browser. Same result.
Generated full origin end to end certificates from cloudflare.
Generated for xxxx.com
and *xxxx.com
.
The subdomains are
api.xxxx.com
cdn.xxxx.com
vods.xxxx.com
I'm using Nginx Proxy Manager
to pass the certificates from cloudflare.
Authelia OIDC Integration
Authelia OIDC Config
If cookies do not persist after logging in it's probably an issue with the cookie domain var. Be sure to disable SSO and use the default auth to get this working first. What's your COOKIE_DOMAIN
set to? vods.xxxx.com
? Maybe try setting it to xxxx.com
. The "recommended" way to reverse proxy Ganymede to to have a "ganymede subdomain" like vods.xxxx.com
then have subdomains of that subdomain api.vods.xxxx.net
. Though, doing it your way should still work.
Looking at the network login request in the browser console may yield some info on if the cookies are not being set for some reason.
My COOKIE_DOMAIN
was set to vods.xxxx.com
.
Setting it to xxxx.com
seems to resolve the issue.
Now I see access-token
and refresh-token
and login persists after refresh.
Only thing now is SSO using authelia, I'm getting some errors, from the API.
{"message":"failed to exchange token: oauth2: cannot fetch token: 401 Unauthorized\nResponse: {\"error\":\"invalid_client\",\"error_description\":\"Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).\"}"}
And from the logs of Authelia I get.
Access Request failed with error: Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). the passwords don't match" method=POST path=/api/oidc/token remote_ip=x.x.x.x stack="github.com/authelia/authelia/v4/internal/handlers/handler_oidc_token.go:27.....(*workerPool).getCh.func1\nruntime/asm_amd64.s:1594 goexit"
But that is an issue for tomorrow.
Solved the bigger issue.
Thanks.
One of the issues I noticed while trying to use Authelia, is that a nickname
attribute isn't sent back. I modified the oauth login to fallback to preferred_username
if a nickname
is not available https://github.com/Zibbp/ganymede/commit/27818d84ff088e7864deb37dcf278ab577616d3c. I'm able to complete the entire oauth flow with Authelia but there is still another issue, Authelia is not returning a refresh token in the response. There's an access token but not refresh token. The refresh token grant is included in the config. I'm using the sort-of default config that Authelia provides. If you want to tinker with it more, the nickname fix is pushed to the :main
tag.
identity_providers:
oidc:
hmac_secret: this_is_a_secret_abc123abc123abc
issuer_private_key: |
-----BEGIN RSA PRIVATE KEY-----
priv key
-----END RSA PRIVATE KEY-----
access_token_lifespan: 1h
authorize_code_lifespan: 1m
id_token_lifespan: 1h
refresh_token_lifespan: 90m
enable_client_debug_messages: false
enforce_pkce: public_clients_only
cors:
endpoints:
- authorization
- token
- revocation
- introspection
allowed_origins:
- https://example.com
allowed_origins_from_client_redirect_uris: false
clients:
- id: myapp
description: My Application
secret: 'demosecret'
sector_identifier: ''
public: false
authorization_policy: one_factor
consent_mode: explicit
pre_configured_consent_duration: 1w
audience: []
scopes:
- openid
- groups
- email
- profile
redirect_uris:
- http://localhost:4000/api/v1/auth/oauth/callback
grant_types:
- refresh_token
- authorization_code
response_types:
- code
response_modes:
- form_post
- query
- fragment
userinfo_signing_algorithm: none
@noraemsu Was a solution for this ever found? I too am not getting a refresh token