1
0
forked from baron/baron-sso

custom claim 타입보정 UI. 대표테넌트 노출 보정

This commit is contained in:
2026-06-11 11:27:11 +09:00
parent 0bb3ccb850
commit f60b15a17b
37 changed files with 2952 additions and 417 deletions

View File

@@ -17,6 +17,7 @@ import (
"io"
"log/slog"
"maps"
"math"
"math/rand"
"net"
"net/http"
@@ -1646,6 +1647,154 @@ func applyConfiguredIDTokenClaims(baseClaims map[string]any, metadata map[string
return baseClaims
}
func (h *AuthHandler) withRPUserMetadataClaims(ctx context.Context, claims map[string]any, client domain.HydraClient, subject string) map[string]any {
if claims == nil {
claims = map[string]any{}
}
if h == nil || h.RPUserMetadataRepo == nil {
return claims
}
clientID := strings.TrimSpace(client.ClientID)
subject = strings.TrimSpace(subject)
if clientID == "" || subject == "" {
return claims
}
rpClaimDefinitions := extractRPClaimDefinitions(client.Metadata)
if len(rpClaimDefinitions) == 0 {
return claims
}
row, err := h.RPUserMetadataRepo.Get(ctx, clientID, subject)
if err != nil || row == nil || len(row.Metadata) == 0 {
return claims
}
rpClaims, _ := claims["rp_claims"].(map[string]any)
if rpClaims == nil {
rpClaims = map[string]any{}
}
for _, claim := range rpClaimDefinitions {
raw, ok := row.Metadata[claim.Key]
if !ok || raw == nil {
continue
}
value, ok := coerceRPUserMetadataClaimValue(raw, claim.ValueType)
if !ok {
slog.Warn("failed to coerce rp user metadata claim", "client_id", clientID, "subject", subject, "key", claim.Key, "value_type", claim.ValueType)
continue
}
rpClaims[claim.Key] = value
}
if len(rpClaims) > 0 {
claims["rp_claims"] = rpClaims
}
return claims
}
func extractRPClaimDefinitions(metadata map[string]any) []normalizedIDTokenClaim {
if metadata == nil {
return nil
}
rawClaims, ok := metadata[domain.MetadataIDTokenClaims]
if !ok || rawClaims == nil {
return nil
}
normalizedClaims, err := normalizeIDTokenClaims(rawClaims)
if err != nil {
slog.Warn("failed to normalize rp claim definitions", "error", err)
return nil
}
definitions := make([]normalizedIDTokenClaim, 0, len(normalizedClaims))
seen := make(map[string]struct{}, len(normalizedClaims))
for _, claim := range normalizedClaims {
if claim.Namespace != "rp_claims" {
continue
}
if _, exists := seen[claim.Key]; exists {
continue
}
seen[claim.Key] = struct{}{}
definitions = append(definitions, claim)
}
return definitions
}
func coerceRPUserMetadataClaimValue(raw any, valueType string) (any, bool) {
switch value := raw.(type) {
case string:
if strings.TrimSpace(value) == "" {
return nil, false
}
parsed, err := parseConfiguredClaimValue(value, valueType)
return parsed, err == nil
case []any:
if valueType == "array" {
return value, true
}
case []string:
if valueType == "array" {
items := make([]any, 0, len(value))
for _, item := range value {
items = append(items, item)
}
return items, true
}
case map[string]any:
if valueType == "object" {
return value, true
}
case bool:
if valueType == "boolean" {
return value, true
}
case float64:
if valueType == "float" {
return value, true
}
if valueType == "number" && value == math.Trunc(value) {
return value, true
}
case float32:
floatValue := float64(value)
if valueType == "float" {
return floatValue, true
}
if valueType == "number" && floatValue == math.Trunc(floatValue) {
return floatValue, true
}
case int:
if valueType == "number" {
return float64(value), true
}
if valueType == "float" {
return float64(value), true
}
case int64:
if valueType == "number" {
return float64(value), true
}
if valueType == "float" {
return float64(value), true
}
case json.Number:
if valueType == "number" {
parsed, err := value.Int64()
return float64(parsed), err == nil
}
if valueType == "float" {
parsed, err := value.Float64()
return parsed, err == nil
}
}
parsed, err := parseConfiguredClaimValue(fmt.Sprint(raw), valueType)
return parsed, err == nil
}
func (h *AuthHandler) withRPProfileClaims(ctx context.Context, claims map[string]any, client domain.HydraClient, subject string) map[string]any {
if claims == nil {
claims = map[string]any{}
@@ -6046,6 +6195,7 @@ func (h *AuthHandler) GetConsentRequest(c *fiber.Ctx) error {
currentSessionID,
)
sessionClaims = h.withHanmacFamilyTenantClaims(c.Context(), sessionClaims, identity.Traits, consentRequest.RequestedScope)
sessionClaims = h.withRPUserMetadataClaims(c.Context(), sessionClaims, consentRequest.Client, consentRequest.Subject)
sessionClaims = h.withRPProfileClaims(c.Context(), sessionClaims, consentRequest.Client, consentRequest.Subject)
acceptResp, err := h.Hydra.AcceptConsentRequest(c.Context(), challenge, consentRequest, sessionClaims)
if err == nil {
@@ -6084,6 +6234,7 @@ func (h *AuthHandler) GetConsentRequest(c *fiber.Ctx) error {
currentSessionID,
)
sessionClaims = h.withHanmacFamilyTenantClaims(c.Context(), sessionClaims, identity.Traits, consentRequest.RequestedScope)
sessionClaims = h.withRPUserMetadataClaims(c.Context(), sessionClaims, consentRequest.Client, consentRequest.Subject)
sessionClaims = h.withRPProfileClaims(c.Context(), sessionClaims, consentRequest.Client, consentRequest.Subject)
// [Debug] 실제 생성된 클레임 출력 (요청사항 확인용 - 자동 승인 시)
@@ -6275,6 +6426,7 @@ func (h *AuthHandler) AcceptConsentRequest(c *fiber.Ctx) error {
currentSessionID,
)
sessionClaims = h.withHanmacFamilyTenantClaims(c.Context(), sessionClaims, identity.Traits, consentRequest.RequestedScope)
sessionClaims = h.withRPUserMetadataClaims(c.Context(), sessionClaims, consentRequest.Client, consentRequest.Subject)
sessionClaims = h.withRPProfileClaims(c.Context(), sessionClaims, consentRequest.Client, consentRequest.Subject)
// [Debug] 실제 생성된 클레임 출력 (요청사항 확인용)