Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: oidc support #2792

Closed
wants to merge 18 commits into from
Closed

feat: oidc support #2792

wants to merge 18 commits into from

Conversation

ankarhem
Copy link
Contributor

@ankarhem ankarhem commented May 29, 2022

Description

  • There is no authorization of any kind, it just authenticates as a way to login / create the user. Authorizations are handled as usual per user in overseerr. So no custom scopes / roles etc.

This works when I test it with auth0 but would be nice to get some additional testing with other providers. Appreciate if I could get help setting up oidc on authelia if someone has this, or if someone could test it.

Screenshot (if UI-related)

To-Dos

  • Add api docs

  • Clean up the code

  • Refactor out popup handling stuff from plex and use that for a oidc class instead of redirecting the whole page

  • Test with other providers

  • Add validation (all fields required, domain is a domain etc.) to the oidc settings in settings page
    - [ ] Revocation logic?

  • Create account if it doesn't exist?

  • Successful build yarn build

  • Translation keys yarn i18n:extract
    - [] Database migration (if required)

Other considerations

I considered saving the token and refresh_token and add token handling / validating it for requests, but since other login methods considers you logged in as long as you have the user id in the session I didn't.

Issues Fixed or Closed

@ankarhem ankarhem marked this pull request as ready for review May 31, 2022 17:39
@penmoid

This comment was marked as spam.

@ankarhem
Copy link
Contributor Author

Would love to see this implemented. Is this on the roadmap?

Well, this is functional. It needs to be reviewed is all.

@mirisbowring

This comment was marked as spam.

@ayazgoff
Copy link

I just pulled this and tested it with OIDC from Authentik. It works as intended after a few changes:

  • This regex is overly restrictive -- it should allow for port and path specification. The OpenID spec only requires that the OIDC issuer be a "URL using the https scheme with no query or fragment component", and for Authentik it is https://{domain}/application/o/{application}/
  • There's a typo in the token request body in server/routes/auth.ts ("client_cecret").
  • That same token request uses application/json encoding, which was being rejected by Authentik's token endpoint. As far as I can tell, RFC6749 only requires OAuth providers to accept application/x-www-form-urlencoded posts.

@ankarhem
Copy link
Contributor Author

I just pulled this and tested it with OIDC from Authentik. It works as intended after a few changes:

* [This regex](https://github.com/ankarhem/overseerr/blob/oidc-support/src/components/Settings/SettingsUsers/index.tsx#:~:text=/%5E(%3F!%3A%5C/%5C/)(%5Ba%2DzA%2DZ0%2D9%2D_%5D%2B%5C.)*%5Ba%2DzA%2DZ0%2D9%5D%5Ba%2DzA%2DZ0%2D9%2D_%5D%2B%5C.%5Ba%2DzA%2DZ%5D%7B2%2C11%7D%3F%24/) is overly restrictive -- it should allow for port and path specification. The [OpenID spec](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata) only requires that the OIDC issuer be a "URL using the https scheme with no query or fragment component", and for Authentik it is `https://{domain}/application/o/{application}/`

* There's a [typo](https://github.com/ankarhem/overseerr/blob/oidc-support/server/routes/auth.ts#L485) in the token request body in server/routes/auth.ts ("client_cecret").

* That same token request uses `application/json` encoding, which was being rejected by Authentik's token endpoint. As far as I can tell, [RFC6749](https://datatracker.ietf.org/doc/html/rfc6749) only requires OAuth providers to accept `application/x-www-form-urlencoded` posts.

Thanks! I'll make the changes when I have the time.

@Mlitz

This comment was marked as spam.

@obsidiangroup
Copy link

I just pulled this and tested it with OIDC from Authentik. It works as intended after a few changes:

* [This regex](https://github.com/ankarhem/overseerr/blob/oidc-support/src/components/Settings/SettingsUsers/index.tsx#:~:text=/%5E(%3F!%3A%5C/%5C/)(%5Ba%2DzA%2DZ0%2D9%2D_%5D%2B%5C.)*%5Ba%2DzA%2DZ0%2D9%5D%5Ba%2DzA%2DZ0%2D9%2D_%5D%2B%5C.%5Ba%2DzA%2DZ%5D%7B2%2C11%7D%3F%24/) is overly restrictive -- it should allow for port and path specification. The [OpenID spec](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata) only requires that the OIDC issuer be a "URL using the https scheme with no query or fragment component", and for Authentik it is `https://{domain}/application/o/{application}/`

* There's a [typo](https://github.com/ankarhem/overseerr/blob/oidc-support/server/routes/auth.ts#L485) in the token request body in server/routes/auth.ts ("client_cecret").

* That same token request uses `application/json` encoding, which was being rejected by Authentik's token endpoint. As far as I can tell, [RFC6749](https://datatracker.ietf.org/doc/html/rfc6749) only requires OAuth providers to accept `application/x-www-form-urlencoded` posts.

Thanks! I'll make the changes when I have the time.

Thanks! I'm going to have to switch to this branch to test with Authentik as well. I currently have a policy that when a user goes to Overseerr, authentik pulls their plex_token and passes it to Overseerr. This "works" as long as the user has already associated their account with their Plex account. However, if they do not have a plex account, this doesn't work. @ayazgoff outside of the code changes you referenced, was there anything special on the Authentik side you had to do?

@ankarhem
Copy link
Contributor Author

ankarhem commented Oct 1, 2022

Fixed review comments and rebased the branch

@obsidiangroup
Copy link

@ayazgoff can you share your Authentik configs, and @ankarhem have the changes @ayazgoff stated been implemented?

@ankarhem
Copy link
Contributor Author

@ayazgoff can you share your Authentik configs, and @ankarhem have the changes @ayazgoff stated been implemented?

Yes they were addressed in ef24e30

@fabioteixei
Copy link

@lenaxia Thanks, my bad i did not see it. Configuring now and i will report back

@fabioteixei
Copy link

@lenaxia I have the same issue as @b3n3w.

In my case i use Authentik as an proxy for Azure AD authentication. My Flow:

  1. User opens Overseerr page
  2. Selects Login with authentik
  3. Popup apears
  4. Authentik transparently redirect towards Microsoft
  5. User Authenticates with his Azure AD account
  6. Microsft redirects back to Authentik
  7. Authentik redirects back to Overseerr
  8. Login screen apears inside the popup again to the start of the login loop.

Here some screenshots of my config on overseer and authentik as well the login steps:

image

image

image

image

image

image

image

image

image

Sorry about the language soup. I'm brazilian that lives in Québec, so i speek portuguese an my PC is in French, so i have a mix bag of Portuguese, French and English on my systems.

Maybe the error are on the configs or in Overseerr side or at Authentik. I had a hard time finding the right configs for OIDC domain on Overseerr and Redirect URL on authentik.

Thanks

@lenaxia
Copy link

lenaxia commented Jan 3, 2024

Thanks for the screencaps.

Can you please rerun your container with LOG_LEVEL=debug env variable and then post the log contents from your container? Specifically you can search for 'oidc-callback', and 'oidc-login'. The callback one is likely the issue. If you can also provide the authentik logs would likely be helpful too.

Having the login screen reappear after logging in is normal. I see that with authelia too.

@fabioteixei
Copy link

Thanks for the screencaps.

Can you please rerun your container with LOG_LEVEL=debug env variable and then post the log contents from your container? Specifically you can search for 'oidc-callback', and 'oidc-login'. The callback one is likely the issue. If you can also provide the authentik logs would likely be helpful too.

Authentik Container or Overseer Container?

@lenaxia
Copy link

lenaxia commented Jan 3, 2024

Overseerr container.

@fabioteixei
Copy link

fabioteixei commented Jan 3, 2024

overseerr-5674884db8-6tljd_overseerr.log
Here it is. Kinda long log so i thougt would be better to send you the whole log.

@lenaxia

@fabioteixei
Copy link

@lenaxia maybe an important information is that i use kubernetes and not Docker, so if you see anything that is not common on docker maybe thats why

@lenaxia
Copy link

lenaxia commented Jan 3, 2024

I run kubernetes too, so no worries there https://github.com/lenaxia/home-ops-prod/blob/main/cluster/apps/media/mediarequests/overseerr/helm-release.yaml

Looks like your client ID and secret may not be matching.

2024-01-03T17:03:05.898Z [^[[32minfo^[[39m]: Failed OIDC login attempt {"cause":"Invalid token response: invalid_client","ip":"::ffff:10.42.2.230","body":{"error":"invalid_client","error_description":"Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)"}}

I will spin up my own instance of authentik (won't have azure AD though), and see if I can get it working.

@fabioteixei
Copy link

I run kubernetes too, so no worries there https://github.com/lenaxia/home-ops-prod/blob/main/cluster/apps/media/mediarequests/overseerr/helm-release.yaml

Looks like your client ID and secret may not be matching.

2024-01-03T17:03:05.898Z [^[[32minfo^[[39m]: Failed OIDC login attempt {"cause":"Invalid token response: invalid_client","ip":"::ffff:10.42.2.230","body":{"error":"invalid_client","error_description":"Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)"}}

I will spin up my own instance of authentik (won't have azure AD though), and see if I can get it working.

After your testing please validate the domain url on orverseerr if it's the one I pasted here on my config and the callback url as well on authentik. It seems kinda odd the values that I placed on those fields

@lenaxia
Copy link

lenaxia commented Jan 4, 2024

I just tested with a basic Authentik implementation and it works. So it may have to do with your AD configuration. The error is pretty clear 2024-01-03T17:01:16.299Z [^[[32minfo^[[39m]: Failed OIDC login attempt {"cause":"Invalid token response: invalid_client","ip":"::ffff:10.42.2.230","body":{"error":"invalid_client","error_description":"Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)"}}, it looks like the client name is not correct, so please check that your client name and client secret match between authentik and overseerr.

If you want to compare, is here the helm release I am using: https://github.com/lenaxia/home-ops-prod/blob/2f3342b9b324d937f7c0c5b309cd687c38ec88a0/cluster/apps/networking/authentik/app/helm-release.yaml, can you try with a non AD version of Authentik first to establish a baseline for what work and what doesn,t?

@b3n3w @obsidiangroup Have either of you had a chance to test?

1

2

Authentik authenticating
image

You will see the overseerr UI show up briefly in the pop up before it closes itself
image

@fabioteixei
Copy link

fabioteixei commented Jan 4, 2024

@lenaxia can you confirm the CallBack URL?

I mean the Redirect URIs/Origins (RegEx) on authentik

image

@fabioteixei
Copy link

@lenaxia

I think we need to documment this well (by we i mean you guys 😋 )
I just changed the redirect (Callback URL) to * and is working now with my Azure AD authentication. So your implementation works, it's a matter of configuring it correctly and to do so we need good documentation.

Here are my configs:
Overseerr:
image

On Overseerr we need to check the box to enable the new method so the user are provisoned just in time and dont need to import it before. As we see here the user is newly created as an local user using the email configured on authentik

image

Authentik:
image

On authentik i used the * callback url witch is not the right way of doing this for security reasons, we need to poing the right URL, so if we can document this well i think we will be good to go.

@lenaxia
Copy link

lenaxia commented Jan 4, 2024

Yeah oidc definitely has a learning curve (less than kubernetes though 😆).

Your callback url should point to your overseer instance, so it should be something like https://overseerr.domain.com/api/v1/auth/oidc-callback.

@fabioteixei
Copy link

So @lenaxia and @sct any chance to see this merged on the official branch?

Thanks

@lenaxia
Copy link

lenaxia commented Jan 5, 2024

I opened a PR to @ankarhem 's fork but happy to just open one directly here too if I dont hear from them.

@b3n3w
Copy link

b3n3w commented Jan 8, 2024

Yeah oidc definitely has a learning curve (less than kubernetes though 😆).

Your callback url should point to your overseer instance, so it should be something like https://overseerr.domain.com/api/v1/auth/oidc-callback.

After changing the redirect URL to .* as @fabioteixei mentioned, the authentik login works now for me :)

@lenaxia
Copy link

lenaxia commented Jan 8, 2024

@b3n3w gonna strongly discourage use of a wildcard like that for oidc. That means that after logging in, a user could be directed to any site, including a malicious one. Please see if you can format your callback url to something like this: https://overseerr.domain.com/api/v1/auth/oidc-callback, otherwise I'd recommend you not expose your overseerr instance outside your network.

@lenaxia lenaxia mentioned this pull request Jan 9, 2024
2 tasks
@lenaxia
Copy link

lenaxia commented Jan 9, 2024

Opened a PR to this repo as I hadn't heard back from @ankarhem, code is rebased and works with Authelia and Authentik.

@ankarhem
Copy link
Contributor Author

ankarhem commented Jan 9, 2024

I left this with no intention on pursuing it further, as I tried over like 1,5 years keeping it up to date and working to get it merged. I didn't get the impression it was going anywhere so I left it, in case someone like youself would pick it up.

@lenaxia
Copy link

lenaxia commented Jan 9, 2024

I left this with no intention on pursuing it further, as I tried over like 1,5 years keeping it up to date and working to get it merged. I didn't get the impression it was going anywhere so I left it, in case someone like youself would pick it up.

Absolutely happy to pick up the torch. And just want to say how much I appreciate the work to get started. First time getting my hands dirty in OIDC code for me, so this was a great learning experience for me, and I'm hoping to implement it in other projects now too.

@b3n3w
Copy link

b3n3w commented Jan 10, 2024

@b3n3w gonna strongly discourage use of a wildcard like that for oidc. That means that after logging in, a user could be directed to any site, including a malicious one. Please see if you can format your callback url to something like this: https://overseerr.domain.com/api/v1/auth/oidc-callback, otherwise I'd recommend you not expose your overseerr instance outside your network.

Highly appreciate your explanation!

@lenaxia lenaxia mentioned this pull request Jan 10, 2024
2 tasks
lenaxia pushed a commit to lenaxia/overseerr-oidc that referenced this pull request Jan 10, 2024
@volitank
Copy link

volitank commented Mar 9, 2024

Hello, I am setting this up with Authentik and I'm getting the same Client authentication failed issue. if I use .* it works though I'd rather not use it.

2024-03-09T04:26:26.123Z [info]: OIDC callback without scope 
2024-03-09T04:26:26.537Z [info]: Failed OIDC login attempt {"cause":"Invalid token response: invalid_client","ip":"::ffff:10.89.5.13","body":{"error":"invalid_client","error_description":"Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)"}}

@volitank
Copy link

volitank commented Mar 9, 2024

Alright well I figured it out by checking Authentik's logs. Overseerr was actually sending http instead of https, since overseerr is behind a reverse proxy I had to enable the following setting, which should have already been enabled.

screenshot

@ankarhem ankarhem closed this Mar 21, 2024
lenaxia pushed a commit to lenaxia/overseerr-oidc that referenced this pull request Nov 9, 2024
@lmaced0
Copy link

lmaced0 commented Dec 4, 2024

This is what I'm getting when trying this with Authentik. Any clues why this is failing?

When I click on the OAuth option it goes through Authentik and goes back to the same Overseer login screen.

2024-12-04T00:12:34.323Z [info]: Failed OIDC login attempt {"cause":"Invalid JWT: email_verified is a required field","ip":"192.0.10.66","idToken":"XXXX"}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Login with other services