Added validation of configured acr values
(cherry picked from commit 0a5d74a7bb13554a41eaba3b7505d508fb53970a)
This commit is contained in:
parent
4c823a66c7
commit
012c155d2a
|
|
@ -25,6 +25,7 @@ func CreateTokenToSessionFunc(verify VerifyFunc) TokenToSessionFunc {
|
||||||
Verified *bool `json:"email_verified"`
|
Verified *bool `json:"email_verified"`
|
||||||
PreferredUsername string `json:"preferred_username"`
|
PreferredUsername string `json:"preferred_username"`
|
||||||
Groups []string `json:"groups"`
|
Groups []string `json:"groups"`
|
||||||
|
Acr string `json:"acr"`
|
||||||
}
|
}
|
||||||
|
|
||||||
idToken, err := verify(ctx, token)
|
idToken, err := verify(ctx, token)
|
||||||
|
|
@ -49,6 +50,7 @@ func CreateTokenToSessionFunc(verify VerifyFunc) TokenToSessionFunc {
|
||||||
User: claims.Subject,
|
User: claims.Subject,
|
||||||
Groups: claims.Groups,
|
Groups: claims.Groups,
|
||||||
PreferredUsername: claims.PreferredUsername,
|
PreferredUsername: claims.PreferredUsername,
|
||||||
|
Acr: claims.Acr,
|
||||||
AccessToken: token,
|
AccessToken: token,
|
||||||
IDToken: token,
|
IDToken: token,
|
||||||
RefreshToken: "",
|
RefreshToken: "",
|
||||||
|
|
|
||||||
|
|
@ -727,6 +727,7 @@ func (l *LegacyProvider) convert() (Providers, error) {
|
||||||
provider.KeycloakConfig = KeycloakOptions{
|
provider.KeycloakConfig = KeycloakOptions{
|
||||||
Groups: l.KeycloakGroups,
|
Groups: l.KeycloakGroups,
|
||||||
Roles: l.AllowedRoles,
|
Roles: l.AllowedRoles,
|
||||||
|
ACRs: l.AcrValues,
|
||||||
}
|
}
|
||||||
case "keycloak":
|
case "keycloak":
|
||||||
provider.KeycloakConfig = KeycloakOptions{
|
provider.KeycloakConfig = KeycloakOptions{
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,7 @@ type KeycloakOptions struct {
|
||||||
|
|
||||||
// Role enables to restrict login to users with role (only available when using the keycloak-oidc provider)
|
// Role enables to restrict login to users with role (only available when using the keycloak-oidc provider)
|
||||||
Roles []string `json:"roles,omitempty"`
|
Roles []string `json:"roles,omitempty"`
|
||||||
|
ACRs string `json:"acr,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AzureOptions struct {
|
type AzureOptions struct {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ type SessionState struct {
|
||||||
User string `msgpack:"u,omitempty"`
|
User string `msgpack:"u,omitempty"`
|
||||||
Groups []string `msgpack:"g,omitempty"`
|
Groups []string `msgpack:"g,omitempty"`
|
||||||
PreferredUsername string `msgpack:"pu,omitempty"`
|
PreferredUsername string `msgpack:"pu,omitempty"`
|
||||||
|
Acr string `msgpack:"acr,omitempty"`
|
||||||
|
|
||||||
// Internal helpers, not serialized
|
// Internal helpers, not serialized
|
||||||
Clock clock.Clock `msgpack:"-"`
|
Clock clock.Clock `msgpack:"-"`
|
||||||
|
|
@ -148,6 +149,8 @@ func (s *SessionState) GetClaim(claim string) []string {
|
||||||
return groups
|
return groups
|
||||||
case "preferred_username":
|
case "preferred_username":
|
||||||
return []string{s.PreferredUsername}
|
return []string{s.PreferredUsername}
|
||||||
|
case "acr":
|
||||||
|
return []string{s.Acr}
|
||||||
default:
|
default:
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ func NewKeycloakProvider(p *ProviderData, opts options.KeycloakOptions) *Keycloa
|
||||||
|
|
||||||
provider := &KeycloakProvider{ProviderData: p}
|
provider := &KeycloakProvider{ProviderData: p}
|
||||||
provider.setAllowedGroups(opts.Groups)
|
provider.setAllowedGroups(opts.Groups)
|
||||||
|
provider.setAllowedACR(opts.ACRs)
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ func NewKeycloakOIDCProvider(p *ProviderData, opts options.Provider) *KeycloakOI
|
||||||
}
|
}
|
||||||
|
|
||||||
provider.addAllowedRoles(opts.KeycloakConfig.Roles)
|
provider.addAllowedRoles(opts.KeycloakConfig.Roles)
|
||||||
|
provider.setAllowedACR(opts.KeycloakConfig.ACRs)
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ type ProviderData struct {
|
||||||
// Universal Group authorization data structure
|
// Universal Group authorization data structure
|
||||||
// any provider can set to consume
|
// any provider can set to consume
|
||||||
AllowedGroups map[string]struct{}
|
AllowedGroups map[string]struct{}
|
||||||
|
AllowedACRs map[string]struct{}
|
||||||
|
|
||||||
getAuthorizationHeaderFunc func(string) http.Header
|
getAuthorizationHeaderFunc func(string) http.Header
|
||||||
loginURLParameterDefaults url.Values
|
loginURLParameterDefaults url.Values
|
||||||
|
|
@ -181,6 +182,14 @@ func (p *ProviderData) setAllowedGroups(groups []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *ProviderData) setAllowedACR(acrs string) {
|
||||||
|
p.AllowedACRs = make(map[string]struct{})
|
||||||
|
var resultingACRs = strings.Split(acrs, ",")
|
||||||
|
for _, acr := range resultingACRs {
|
||||||
|
p.AllowedACRs[acr] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type providerDefaults struct {
|
type providerDefaults struct {
|
||||||
name string
|
name string
|
||||||
loginURL *url.URL
|
loginURL *url.URL
|
||||||
|
|
@ -258,6 +267,7 @@ func (p *ProviderData) buildSessionFromClaims(rawIDToken, accessToken string) (*
|
||||||
{p.UserClaim, &ss.User},
|
{p.UserClaim, &ss.User},
|
||||||
{p.EmailClaim, &ss.Email},
|
{p.EmailClaim, &ss.Email},
|
||||||
{p.GroupsClaim, &ss.Groups},
|
{p.GroupsClaim, &ss.Groups},
|
||||||
|
{"acr", &ss.Acr},
|
||||||
// TODO (@NickMeves) Deprecate for dynamic claim to session mapping
|
// TODO (@NickMeves) Deprecate for dynamic claim to session mapping
|
||||||
{"preferred_username", &ss.PreferredUsername},
|
{"preferred_username", &ss.PreferredUsername},
|
||||||
} {
|
} {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package providers
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
@ -116,6 +117,16 @@ func (p *ProviderData) EnrichSession(_ context.Context, _ *sessions.SessionState
|
||||||
// Authorize performs global authorization on an authenticated session.
|
// Authorize performs global authorization on an authenticated session.
|
||||||
// This is not used for fine-grained per route authorization rules.
|
// This is not used for fine-grained per route authorization rules.
|
||||||
func (p *ProviderData) Authorize(_ context.Context, s *sessions.SessionState) (bool, error) {
|
func (p *ProviderData) Authorize(_ context.Context, s *sessions.SessionState) (bool, error) {
|
||||||
|
println("ACR level is", s.Acr)
|
||||||
|
bs, _ := json.Marshal(p.AllowedACRs)
|
||||||
|
fmt.Println("Current configured acr is", string(bs))
|
||||||
|
if len(p.AllowedACRs) > 0 {
|
||||||
|
var _, ok = p.AllowedACRs[s.Acr]
|
||||||
|
if !ok {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(p.AllowedGroups) == 0 {
|
if len(p.AllowedGroups) == 0 {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue