draft scopes claim

This commit is contained in:
Vladimir Dronnikov 2024-03-14 15:25:56 +00:00
parent d365d5fc41
commit 803fdbf3c8
7 changed files with 40 additions and 1 deletions

View File

@ -720,11 +720,13 @@ func (p *OAuthProxy) UserInfo(rw http.ResponseWriter, req *http.Request) {
Email string `json:"email"`
Groups []string `json:"groups,omitempty"`
PreferredUsername string `json:"preferredUsername,omitempty"`
Name string `json:"name"`
}{
User: session.User,
Email: session.Email,
Groups: session.Groups,
PreferredUsername: session.PreferredUsername,
Name: session.Name,
}
if err := json.NewEncoder(rw).Encode(userInfo); err != nil {

View File

@ -24,7 +24,9 @@ func CreateTokenToSessionFunc(verify VerifyFunc) TokenToSessionFunc {
Email string `json:"email"`
Verified *bool `json:"email_verified"`
PreferredUsername string `json:"preferred_username"`
Name string `json:"name"`
Groups []string `json:"groups"`
Scopes []string `json:"scopes"`
}
idToken, err := verify(ctx, token)
@ -49,6 +51,8 @@ func CreateTokenToSessionFunc(verify VerifyFunc) TokenToSessionFunc {
User: claims.Subject,
Groups: claims.Groups,
PreferredUsername: claims.PreferredUsername,
Name: claims.Name,
Scopes: claims.Scopes,
AccessToken: token,
IDToken: token,
RefreshToken: "",

View File

@ -4,8 +4,14 @@ const (
// OIDCEmailClaim is the generic email claim used by the OIDC provider.
OIDCEmailClaim = "email"
// OIDCNameClaim is the generic name claim used by the OIDC provider.
OIDCNameClaim = "name"
// OIDCGroupsClaim is the generic groups claim used by the OIDC provider.
OIDCGroupsClaim = "groups"
// OIDCScopesClaim is the generic scopes claim used by the OIDC provider.
OIDCScopesClaim = "scopes"
)
// OIDCAudienceClaims is the generic audience claim list used by the OIDC provider.
@ -228,9 +234,15 @@ type OIDCOptions struct {
// EmailClaim indicates which claim contains the user email,
// default set to 'email'
EmailClaim string `json:"emailClaim,omitempty"`
// NameClaim indicates which claim contains the user name,
// default set to 'name'
NameClaim string `json:"nameClaim,omitempty"`
// GroupsClaim indicates which claim contains the user groups
// default set to 'groups'
GroupsClaim string `json:"groupsClaim,omitempty"`
// ScopesClaim indicates which claim contains the user scopes
// default set to 'scopes'
ScopesClaim string `json:"scopesClaim,omitempty"`
// UserIDClaim indicates which claim contains the user ID
// default set to 'email'
UserIDClaim string `json:"userIDClaim,omitempty"`
@ -264,7 +276,9 @@ func providerDefaults() Providers {
SkipDiscovery: false,
UserIDClaim: OIDCEmailClaim, // Deprecated: Use OIDCEmailClaim
EmailClaim: OIDCEmailClaim,
NameClaim: OIDCNameClaim,
GroupsClaim: OIDCGroupsClaim,
ScopesClaim: OIDCScopesClaim,
AudienceClaims: OIDCAudienceClaims,
ExtraAudiences: []string{},
},

View File

@ -28,6 +28,8 @@ type SessionState struct {
User string `msgpack:"u,omitempty"`
Groups []string `msgpack:"g,omitempty"`
PreferredUsername string `msgpack:"pu,omitempty"`
Name string `msgpack:"dn,omitempty"`
Scopes []string `msgpack:"s,omitempty"`
// Internal helpers, not serialized
Clock clock.Clock `msgpack:"-"`
@ -101,7 +103,7 @@ func (s *SessionState) Age() time.Duration {
// String constructs a summary of the session state
func (s *SessionState) String() string {
o := fmt.Sprintf("Session{email:%s user:%s PreferredUsername:%s", s.Email, s.User, s.PreferredUsername)
o := fmt.Sprintf("Session{email:%s user:%s PreferredUsername:%s Name:%s", s.Email, s.User, s.PreferredUsername, s.Name)
if s.AccessToken != "" {
o += " token:true"
}
@ -120,6 +122,9 @@ func (s *SessionState) String() string {
if len(s.Groups) > 0 {
o += fmt.Sprintf(" groups:%v", s.Groups)
}
if len(s.Scopes) > 0 {
o += fmt.Sprintf(" scopes:%v", s.Scopes)
}
return o + "}"
}
@ -148,6 +153,12 @@ func (s *SessionState) GetClaim(claim string) []string {
return groups
case "preferred_username":
return []string{s.PreferredUsername}
case "name":
return []string{s.Name}
case "scopes":
scopes := make([]string, len(s.Scopes))
copy(scopes, s.Scopes)
return scopes
default:
return []string{}
}

View File

@ -178,7 +178,9 @@ func (p *OIDCProvider) redeemRefreshToken(ctx context.Context, s *sessions.Sessi
s.Email = newSession.Email
s.User = newSession.User
s.Groups = newSession.Groups
s.Scopes = newSession.Scopes
s.PreferredUsername = newSession.PreferredUsername
s.Name = newSession.Name
}
s.AccessToken = newSession.AccessToken

View File

@ -46,7 +46,9 @@ type ProviderData struct {
AllowUnverifiedEmail bool
UserClaim string
EmailClaim string
NameClaim string
GroupsClaim string
ScopesClaim string
Verifier internaloidc.IDTokenVerifier
SkipClaimsFromProfileURL bool
@ -260,6 +262,8 @@ func (p *ProviderData) buildSessionFromClaims(rawIDToken, accessToken string) (*
{p.GroupsClaim, &ss.Groups},
// TODO (@NickMeves) Deprecate for dynamic claim to session mapping
{"preferred_username", &ss.PreferredUsername},
{p.NameClaim, &ss.Name},
{p.ScopesClaim, &ss.Scopes},
} {
if _, err := extractor.GetClaimInto(c.claim, c.dst); err != nil {
return nil, err

View File

@ -137,7 +137,9 @@ func newProviderDataFromConfig(providerConfig options.Provider) (*ProviderData,
// Make the OIDC options available to all providers that support it
p.AllowUnverifiedEmail = providerConfig.OIDCConfig.InsecureAllowUnverifiedEmail
p.EmailClaim = providerConfig.OIDCConfig.EmailClaim
p.NameClaim = providerConfig.OIDCConfig.NameClaim
p.GroupsClaim = providerConfig.OIDCConfig.GroupsClaim
p.ScopesClaim = providerConfig.OIDCConfig.ScopesClaim
p.SkipClaimsFromProfileURL = providerConfig.SkipClaimsFromProfileURL
// Set PKCE enabled or disabled based on discovery and force options