You've already forked oauth2-proxy
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:
@ -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)
|
||||||
|
@ -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"`
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user