diff --git a/keycloak/client.go b/keycloak/client.go index cac7773c..7081ac9f 100644 --- a/keycloak/client.go +++ b/keycloak/client.go @@ -86,11 +86,17 @@ func NewKeycloakUser(gocloakUser *gocloak.User) *User { } type TokenIntrospectionResult struct { - Active bool `json:"active"` - Subject string `json:"sub"` - EmailVerified bool `json:"email_verified"` - ExpiresAt int64 `json:"eat"` - RealmAccess RealmAccess `json:"realm_access"` + Active bool `json:"active"` + Subject string `json:"sub"` + EmailVerified bool `json:"email_verified"` + ExpiresAt int64 `json:"eat"` + RealmAccess RealmAccess `json:"realm_access"` + IdentityProvider string `json:"identityProvider"` +} + +type AccessTokenCustomClaims struct { + jwx.Claims + IdentityProvider string `json:"identity_provider,omitempty"` } type RealmAccess struct { @@ -310,7 +316,7 @@ func (c *client) CreateUser(ctx context.Context, user *User) (*User, error) { } model.Attributes = &attrs } - + user.ID, err = c.keycloak.CreateUser(ctx, token.AccessToken, c.cfg.Realm, model) if err != nil { if e, ok := err.(*gocloak.APIError); ok && e.Code == http.StatusConflict { @@ -375,7 +381,7 @@ func (c *client) IntrospectToken(ctx context.Context, token oauth2.Token) (*Toke Active: safePBool(rtr.Active), } if result.Active { - customClaims := &jwx.Claims{} + customClaims := &AccessTokenCustomClaims{} _, err := c.keycloak.DecodeAccessTokenCustomClaims( ctx, token.AccessToken, @@ -391,6 +397,7 @@ func (c *client) IntrospectToken(ctx context.Context, token oauth2.Token) (*Toke result.RealmAccess = RealmAccess{ Roles: customClaims.RealmAccess.Roles, } + result.IdentityProvider = customClaims.IdentityProvider } return result, nil diff --git a/user/token.go b/user/token.go index 896df52a..bd7c9e46 100644 --- a/user/token.go +++ b/user/token.go @@ -26,10 +26,11 @@ type ( } TokenData struct { - IsServer bool `json:"isserver"` - UserId string `json:"userid"` - DurationSecs int64 `json:"-"` - ExpiresAt int64 `json:"expires_at"` + IsServer bool `json:"isserver"` + UserId string `json:"userid"` + DurationSecs int64 `json:"-"` + ExpiresAt int64 `json:"expires_at"` + IdentityProvider string `json:"identityProvider,omitempty"` } TokenConfig struct { @@ -50,8 +51,8 @@ var ( SessionToken_error_no_userid = errors.New("SessionToken: userId not set") SessionToken_invalid = errors.New("SessionToken: is invalid") SessionToken_error_duration_not_set = errors.New("SessionToken: duration not set") - sessionToken *SessionToken - tokenMutex = &sync.Mutex{} + sessionToken *SessionToken + tokenMutex = &sync.Mutex{} ) func CreateSessionToken(data *TokenData, config TokenConfig) (*SessionToken, error) { @@ -243,10 +244,11 @@ func TokenDataFromIntrospectionResult(introspectionResult *keycloak.TokenIntrosp } return &TokenData{ - IsServer: introspectionResult.IsServerToken(), - UserId: introspectionResult.Subject, - DurationSecs: duration, - ExpiresAt: introspectionResult.ExpiresAt, + IsServer: introspectionResult.IsServerToken(), + UserId: introspectionResult.Subject, + DurationSecs: duration, + ExpiresAt: introspectionResult.ExpiresAt, + IdentityProvider: introspectionResult.IdentityProvider, }, nil } @@ -275,7 +277,7 @@ func hasServerToken(tokenString string, tokenConfigs ...TokenConfig) bool { func GetServiceToken(cfg TokenConfig, store Storage) (*SessionToken, error) { tokenMutex.Lock() defer tokenMutex.Unlock() - if sessionToken != nil && sessionToken.ExpiresAt.After(time.Now().Add(time.Minute * 1)) { + if sessionToken != nil && sessionToken.ExpiresAt.After(time.Now().Add(time.Minute*1)) { return sessionToken, nil } @@ -289,4 +291,4 @@ func GetServiceToken(cfg TokenConfig, store Storage) (*SessionToken, error) { } sessionToken = token return sessionToken, nil -} \ No newline at end of file +}