1
0
forked from baron/baron-sso

devfront ID Token Claims 백엔드 반영

This commit is contained in:
2026-04-29 13:45:23 +09:00
parent e484d8c100
commit 0844befb35
5 changed files with 492 additions and 8 deletions

View File

@@ -363,3 +363,110 @@ func TestGetConsentRequest_Skip_DynamicClaims(t *testing.T) {
assert.Equal(t, "Security", capturedClaims["department"])
assert.Equal(t, "Officer", capturedClaims["position"])
}
func TestAcceptConsentRequest_AppliesConfiguredIDTokenClaims(t *testing.T) {
var capturedClaims map[string]interface{}
transport := roundTripFunc(func(r *http.Request) (*http.Response, error) {
if r.URL.Path == "/oauth2/auth/requests/consent" && r.URL.Query().Get("consent_challenge") == "challenge-configured-claims" {
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
"challenge": "challenge-configured-claims",
"requested_scope": []string{"openid", "profile"},
"subject": "user-789",
"client": map[string]interface{}{
"client_id": "client-configured-claims",
"metadata": map[string]interface{}{
"tenant_id": "tenant-claims",
"id_token_claims": []map[string]interface{}{
{
"namespace": "top_level",
"key": "locale",
"value": "ko-KR",
"valueType": "text",
},
{
"namespace": "top_level",
"key": "email",
"value": "should-not-override@example.com",
"valueType": "text",
},
{
"namespace": "rp_claims",
"key": "tier",
"value": "2",
"valueType": "number",
},
{
"namespace": "rp_claims",
"key": "features",
"value": "[\"sso\",\"claims\"]",
"valueType": "array",
},
},
},
},
}), nil
}
if r.URL.Path == "/oauth2/auth/requests/consent/accept" && r.URL.Query().Get("consent_challenge") == "challenge-configured-claims" {
body, _ := io.ReadAll(r.Body)
var acceptReq map[string]interface{}
json.Unmarshal(body, &acceptReq)
if session, ok := acceptReq["session"].(map[string]interface{}); ok {
capturedClaims = session["id_token"].(map[string]interface{})
}
return httpJSONAny(r, http.StatusOK, map[string]interface{}{
"redirect_to": "http://rp/cb",
}), nil
}
return httpResponse(r, http.StatusNotFound, "not found"), nil
})
client := &http.Client{Transport: transport}
origDefault := http.DefaultClient
http.DefaultClient = client
defer func() { http.DefaultClient = origDefault }()
h := &AuthHandler{
Hydra: &service.HydraAdminService{
AdminURL: "http://hydra.test",
HTTPClient: client,
},
KratosAdmin: new(MockKratosAdminService),
}
h.KratosAdmin.(*MockKratosAdminService).On("GetIdentity", mock.Anything, "user-789").Return(&service.KratosIdentity{
ID: "user-789",
Traits: map[string]interface{}{
"email": "real-user@example.com",
"name": "Configured User",
"tenant-claims": map[string]interface{}{
"department": "Platform",
},
},
}, nil)
app := fiber.New()
app.Post("/api/v1/auth/consent/accept", h.AcceptConsentRequest)
reqBody, _ := json.Marshal(map[string]interface{}{
"consent_challenge": "challenge-configured-claims",
"grant_scope": []string{"openid", "profile"},
})
req := httptest.NewRequest(http.MethodPost, "/api/v1/auth/consent/accept", bytes.NewReader(reqBody))
req.Header.Set("Content-Type", "application/json")
resp, err := app.Test(req)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
assert.NotNil(t, capturedClaims)
assert.Equal(t, "real-user@example.com", capturedClaims["email"])
assert.Equal(t, "ko-KR", capturedClaims["locale"])
assert.Equal(t, "tenant-claims", capturedClaims["tenant_id"])
rpClaims, ok := capturedClaims["rp_claims"].(map[string]interface{})
if assert.True(t, ok) {
assert.Equal(t, float64(2), rpClaims["tier"])
assert.Equal(t, []interface{}{"sso", "claims"}, rpClaims["features"])
}
}