diff --git a/CHANGELOG.md b/CHANGELOG.md index e5a586db..028e0931 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ - [#1709](https://github.com/oauth2-proxy/oauth2-proxy/pull/1709) Show an alert message when basic auth credentials are invalid (@aiciobanu) +- [#1720](https://github.com/oauth2-proxy/oauth2-proxy/pull/1720) Extract roles from authToken, to allow using allowed roles with Keycloak. + # V7.3.0 ## Release Highlights diff --git a/providers/keycloak_oidc.go b/providers/keycloak_oidc.go index e16b4383..28abae3a 100644 --- a/providers/keycloak_oidc.go +++ b/providers/keycloak_oidc.go @@ -43,6 +43,21 @@ func (p *KeycloakOIDCProvider) addAllowedRoles(roles []string) { } } +// CreateSessionFromToken converts Bearer IDTokens into sessions +func (p *KeycloakOIDCProvider) CreateSessionFromToken(ctx context.Context, token string) (*sessions.SessionState, error) { + ss, err := p.OIDCProvider.CreateSessionFromToken(ctx, token) + if err != nil { + return nil, fmt.Errorf("could not create session from token: %v", err) + } + + // Extract custom keycloak roles and enrich session + if err := p.extractRoles(ctx, ss); err != nil { + return nil, err + } + + return ss, nil +} + // EnrichSession is called after Redeem to allow providers to enrich session fields // such as User, Email, Groups with provider specific API calls. func (p *KeycloakOIDCProvider) EnrichSession(ctx context.Context, s *sessions.SessionState) error { diff --git a/providers/keycloak_oidc_test.go b/providers/keycloak_oidc_test.go index d1a50b2a..4f326f70 100644 --- a/providers/keycloak_oidc_test.go +++ b/providers/keycloak_oidc_test.go @@ -199,4 +199,22 @@ var _ = Describe("Keycloak OIDC Provider Tests", func() { Expect(existingSession.Groups).To(BeEquivalentTo([]string{"role:write", "role:default:read"})) }) }) + + Context("Create new session from token", func() { + It("should create a session and extract roles ", func() { + server, provider := newTestKeycloakOIDCSetup() + url, err := url.Parse(server.URL) + Expect(err).To(BeNil()) + defer server.Close() + + provider.ProfileURL = url + + session, err := provider.CreateSessionFromToken(context.Background(), getAccessToken()) + Expect(err).To(BeNil()) + Expect(session.ExpiresOn).ToNot(BeNil()) + Expect(session.CreatedAt).ToNot(BeNil()) + Expect(session.Groups).To(BeEquivalentTo([]string{"role:write", "role:default:read"})) + }) + }) + })