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

Add authentik oauth provider #1377

Closed
wants to merge 9 commits into from
Closed

Add authentik oauth provider #1377

wants to merge 9 commits into from

Conversation

pr0ton11
Copy link

@pr0ton11 pr0ton11 commented Dec 25, 2022

This is a PR that eventually should add a more generic oauth2 auth provider. Since I am self hosting authentik as my identity provider it only makes sense that I implement auth for it in projects I want to use in the future.

  • Implement FetchAuthUser functionality
  • Add unit tests
  • Improve UI to be more aligned with vision of pocketbase team (help needed)

@ganigeorgiev ganigeorgiev marked this pull request as draft December 27, 2022 10:59

func NewAuthentikProvider() *Authentik {
return &Authentik{&baseProvider{
scopes: []string{"profile"},
Copy link
Contributor

@mariosant mariosant Jan 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct me if I am wrong please, but I feel that scopes can be preconfigured on provider side. If that's the case, it might make sense to not request specific scopes, as it will override the provider's configuration (while pocketbase request scopes are not configurable atm).

What do you think?

Ref: https://goauthentik.io/docs/providers/oauth2/#scope-authorization

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are partially correct. This default implementation just requests a scope that is enabled by default in Authentik, but ofc this could be configured in any way on the provider side.
I am struggling at the moment to find where the frontend settings are passed into this class. If someone could give me a hint that would be very helpful for the progress of this PR.

Copy link
Member

@ganigeorgiev ganigeorgiev Jan 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am struggling at the moment to find where the frontend settings are passed into this class. If someone could give me a hint that would be very helpful for the progress of this PR.

I'm not sure if that's what you are asking, but users can't configure the default scopes from the Admin UI at the moment.
They are just minimal defaults for convenience and are used only in the login url(s) that are returned with the List auth method endpoint. Users can adjust/replace them client-side by modifing the scope query parameter in the returned provider login url(s) if they need to.

Copy link
Author

@pr0ton11 pr0ton11 Jan 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ganigeorgiev

  • What I meant is that Authenktik.go uses a *baseProvider instance, but I dont see where in the baseProvider instance I can retrieve the settings that get set in the Svelte frontend component AuthentikOptions.svelte. This is essential, since all the endpoints get configured there (and authentik is self-hosted, so I can not provide a general URL in the constructor)
  • Maybe you could also give me a hint since authentik is a very general provider, and could also allow for example Keycloak to be used, if we want to keep it named Authentik or if we want to give it a more general name.
  • I need some feedback about the frontend part, specifically if I align with quality / vision of other providers.

Copy link
Member

@ganigeorgiev ganigeorgiev Jan 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pr0ton11 The Admin UI settings API doesn't operate directly with the auth.baseProvider and instead uses the settings.AuthProviderConfig -

type AuthProviderConfig struct {
Enabled bool `form:"enabled" json:"enabled"`
ClientId string `form:"clientId" json:"clientId,omitempty"`
ClientSecret string `form:"clientSecret" json:"clientSecret,omitempty"`
AuthUrl string `form:"authUrl" json:"authUrl,omitempty"`
TokenUrl string `form:"tokenUrl" json:"tokenUrl,omitempty"`
UserApiUrl string `form:"userApiUrl" json:"userApiUrl,omitempty"`
}

You can find details about the available settings API fields in https://pocketbase.io/docs/api-settings/.

In any case, you can check the Strava PR for a simple example - #1443.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for helping with the PR, I completed the implementation and it looks like everything is working as expected now

@pr0ton11 pr0ton11 changed the title [WIP] Add authentik oauth provider Add authentik oauth provider Jan 14, 2023
@pr0ton11 pr0ton11 marked this pull request as ready for review January 14, 2023 11:08
@ganigeorgiev
Copy link
Member

ganigeorgiev commented Jan 16, 2023

@pr0ton11 Thank you for working on this but there are some minor things that need to be improved:

  1. Add the authentik in the apis/settings_test.go tests.
  2. Please copy the comments format in authentik.go to be godoc "compatible" (you can refer to the other provider as a reference).
  3. Map the email_verified field and assign the extracted email only if it is true.
  4. There is no id field in the authentik response, and you'll always get "0" at least by default. There is a sub field but I'm not sure if this is user unique since I couldn't find anywhere in the authentik docs information about it. My guess is that it comes with the openid scope but it needs to be mapped to a string. I have no experience with authentik so please verify and confirm. We need a unique user identifier so that we can link the authentik user with the PocketBase one.

@ganigeorgiev
Copy link
Member

@pr0ton11 I'll apply the changes manually to skip the back-and-forth and will merge it in the develop branch sometime later today.

@ganigeorgiev ganigeorgiev self-assigned this Jan 16, 2023
ganigeorgiev added a commit that referenced this pull request Jan 16, 2023
Co-authored-by: Marc Singer <ms@pr0.tech>
@ganigeorgiev
Copy link
Member

@pr0ton11 I've squash merged it in the develop branch - 6d08a5f.

It will be included in the next v0.12.0 release.

@pr0ton11 pr0ton11 deleted the feature/add-authetik-oauth-provider branch January 16, 2023 12:14
@pr0ton11
Copy link
Author

Thanks for your effort for the final changes 👍

@cgrs
Copy link

cgrs commented Feb 6, 2023

FYI, I've tested this OAuth2 provider with Zitadel and Keycloak and they worked successfully. I think this provider should be referred as “Generic” as long as more OAuth2 providers can plug in (I'd like to test it also with Ory, but it should work out of the box).

@pr0ton11
Copy link
Author

pr0ton11 commented Feb 7, 2023

FYI, I've tested this OAuth2 provider with Zitadel and Keycloak and they worked successfully. I think this provider should be referred as “Generic” as long as more OAuth2 providers can plug in (I'd like to test it also with Ory, but it should work out of the box).

Maybe support for the .well-known URI could be added and it could be renamed to generic.
At least the documentation should mention this as a more generic oauth2 provider

@ganigeorgiev
Copy link
Member

@cgrs, @pr0ton11 Let's keep it for now as it is.

Unfortunately, there will be always some manual mapping required when fetching the user profile data that will defer from one provider to another, and I'm not sure if we can have a truly generic provider.

Eventually, I'll consider adding a note/label in the UI mentioning that the provider could be used with other similar OAuth2 services.

@ganigeorgiev
Copy link
Member

@cgrs, @pr0ton11 On second thought having a generic OIDC provider may actually be better since the OIDC spec mentions recommended/standard scope claims and fields - https://openid.net/specs/openid-connect-core-1_0.html

After the ongoing "View" collection type, I'll consider generalizing the Authentik provider.

@ganigeorgiev
Copy link
Member

(Just for info for anyone following here)

The Authentik provider was replaced with a generic OpenID Connect in the develop branch and the changes will be available in the upcoming v0.13.0 release (most likely at the end of this week or the week following it).

If you've previously used Authentik, you'll have to rename the provider key in your code to oidc.

To enable more than one OIDC provider you can use the additional oidc2 and oidc3 provider keys (the keys are iterated to minimize the breaking changes in the Settings struct).

abdokhaire pushed a commit to abdokhaire/postgresbase that referenced this pull request Aug 7, 2024
Co-authored-by: Marc Singer <ms@pr0.tech>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants