1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-07-17 01:52:30 +02:00

Use nickname claim as User for GitLab

Previously this was only done in the `EnrichSession` stage
which would've missed Bearer usages & `RefreshSession`
would've overriden the User to the Subject.
This commit is contained in:
Nick Meves
2021-06-19 14:22:44 -07:00
parent c84a5a418f
commit 11c2177f18
4 changed files with 52 additions and 4 deletions

View File

@ -13,9 +13,13 @@
## Breaking Changes ## Breaking Changes
- [#1239](https://github.com/oauth2-proxy/oauth2-proxy/pull/1239) GitLab groups sent in the `X-Forwarded-Groups` header
to the upstream server will no longer be prefixed with `group:`
## Changes since v7.1.3 ## Changes since v7.1.3
- [#1337](https://github.com/oauth2-proxy/oauth2-proxy/pull/1337) Changing user field type to text when using htpasswd (@pburgisser) - [#1337](https://github.com/oauth2-proxy/oauth2-proxy/pull/1337) Changing user field type to text when using htpasswd (@pburgisser)
- [#1239](https://github.com/oauth2-proxy/oauth2-proxy/pull/1239) Base GitLab provider implementation on OIDCProvider (@NickMeves)
- [#1276](https://github.com/oauth2-proxy/oauth2-proxy/pull/1276) Update crypto and switched to new github.com/golang-jwt/jwt (@JVecsei) - [#1276](https://github.com/oauth2-proxy/oauth2-proxy/pull/1276) Update crypto and switched to new github.com/golang-jwt/jwt (@JVecsei)
- [#1264](https://github.com/oauth2-proxy/oauth2-proxy/pull/1264) Update go-oidc to v3 (@NickMeves) - [#1264](https://github.com/oauth2-proxy/oauth2-proxy/pull/1264) Update go-oidc to v3 (@NickMeves)
- [#1233](https://github.com/oauth2-proxy/oauth2-proxy/pull/1233) Extend email-domain validation with sub-domain capability (@morarucostel) - [#1233](https://github.com/oauth2-proxy/oauth2-proxy/pull/1233) Extend email-domain validation with sub-domain capability (@morarucostel)

View File

@ -15,6 +15,7 @@ import (
const ( const (
gitlabProviderName = "GitLab" gitlabProviderName = "GitLab"
gitlabDefaultScope = "openid email" gitlabDefaultScope = "openid email"
gitlabUserClaim = "nickname"
) )
// GitLabProvider represents a GitLab based Identity Provider // GitLabProvider represents a GitLab based Identity Provider
@ -29,6 +30,7 @@ var _ Provider = (*GitLabProvider)(nil)
// NewGitLabProvider initiates a new GitLabProvider // NewGitLabProvider initiates a new GitLabProvider
func NewGitLabProvider(p *ProviderData) *GitLabProvider { func NewGitLabProvider(p *ProviderData) *GitLabProvider {
p.ProviderName = gitlabProviderName p.ProviderName = gitlabProviderName
p.UserClaim = gitlabUserClaim
if p.Scope == "" { if p.Scope == "" {
p.Scope = gitlabDefaultScope p.Scope = gitlabDefaultScope
} }
@ -119,17 +121,24 @@ func (p *GitLabProvider) EnrichSession(ctx context.Context, s *sessions.SessionS
return fmt.Errorf("user email is not verified") return fmt.Errorf("user email is not verified")
} }
s.User = userinfo.Username if userinfo.Nickname != "" {
s.Email = userinfo.Email s.User = userinfo.Nickname
s.Groups = append(s.Groups, userinfo.Groups...) }
if userinfo.Email != "" {
s.Email = userinfo.Email
}
if len(userinfo.Groups) > 0 {
s.Groups = userinfo.Groups
}
// Add projects as `project:blah` to s.Groups
p.addProjectsToSession(ctx, s) p.addProjectsToSession(ctx, s)
return nil return nil
} }
type gitlabUserinfo struct { type gitlabUserinfo struct {
Username string `json:"nickname"` Nickname string `json:"nickname"`
Email string `json:"email"` Email string `json:"email"`
EmailVerified bool `json:"email_verified"` EmailVerified bool `json:"email_verified"`
Groups []string `json:"groups"` Groups []string `json:"groups"`

View File

@ -41,6 +41,7 @@ type ProviderData struct {
// Common OIDC options for any OIDC-based providers to consume // Common OIDC options for any OIDC-based providers to consume
AllowUnverifiedEmail bool AllowUnverifiedEmail bool
UserClaim string
EmailClaim string EmailClaim string
GroupsClaim string GroupsClaim string
Verifier *oidc.IDTokenVerifier Verifier *oidc.IDTokenVerifier
@ -156,6 +157,17 @@ func (p *ProviderData) buildSessionFromClaims(idToken *oidc.IDToken) (*sessions.
ss.Email = claims.Email ss.Email = claims.Email
ss.Groups = claims.Groups ss.Groups = claims.Groups
// Allow specialized providers that embed OIDCProvider to control the User
// claim. Not exposed as a configuration flag to generic OIDC provider
// users (yet).
if p.UserClaim != "" {
user, ok := claims.raw[p.UserClaim].(string)
if !ok {
return nil, fmt.Errorf("unable to extract custom UserClaim (%s)", p.UserClaim)
}
ss.User = user
}
// TODO (@NickMeves) Deprecate for dynamic claim to session mapping // TODO (@NickMeves) Deprecate for dynamic claim to session mapping
if pref, ok := claims.raw["preferred_username"].(string); ok { if pref, ok := claims.raw["preferred_username"].(string); ok {
ss.PreferredUsername = pref ss.PreferredUsername = pref

View File

@ -211,6 +211,7 @@ func TestProviderData_buildSessionFromClaims(t *testing.T) {
testCases := map[string]struct { testCases := map[string]struct {
IDToken idTokenClaims IDToken idTokenClaims
AllowUnverified bool AllowUnverified bool
UserClaim string
EmailClaim string EmailClaim string
GroupsClaim string GroupsClaim string
ExpectedError error ExpectedError error
@ -259,6 +260,27 @@ func TestProviderData_buildSessionFromClaims(t *testing.T) {
PreferredUsername: "Complex Claim", PreferredUsername: "Complex Claim",
}, },
}, },
"User Claim Switched": {
IDToken: defaultIDToken,
AllowUnverified: true,
UserClaim: "phone_number",
EmailClaim: "email",
GroupsClaim: "groups",
ExpectedSession: &sessions.SessionState{
User: "+4798765432",
Email: "janed@me.com",
Groups: []string{"test:a", "test:b"},
PreferredUsername: "Jane Dobbs",
},
},
"User Claim Invalid": {
IDToken: defaultIDToken,
AllowUnverified: true,
UserClaim: "groups",
EmailClaim: "email",
GroupsClaim: "groups",
ExpectedError: errors.New("unable to extract custom UserClaim (groups)"),
},
"Email Claim Switched": { "Email Claim Switched": {
IDToken: unverifiedIDToken, IDToken: unverifiedIDToken,
AllowUnverified: true, AllowUnverified: true,
@ -332,6 +354,7 @@ func TestProviderData_buildSessionFromClaims(t *testing.T) {
), ),
} }
provider.AllowUnverifiedEmail = tc.AllowUnverified provider.AllowUnverifiedEmail = tc.AllowUnverified
provider.UserClaim = tc.UserClaim
provider.EmailClaim = tc.EmailClaim provider.EmailClaim = tc.EmailClaim
provider.GroupsClaim = tc.GroupsClaim provider.GroupsClaim = tc.GroupsClaim