OpenID conformance test: we get a warning for not having a value for every claim. But we can explictly list support claims. Nothing we can do about a warning in the complience.
This commit is contained in:
@@ -30,7 +30,17 @@ class OidcController < ApplicationController
|
|||||||
id_token_signing_alg_values_supported: ["RS256"],
|
id_token_signing_alg_values_supported: ["RS256"],
|
||||||
scopes_supported: ["openid", "profile", "email", "groups", "offline_access"],
|
scopes_supported: ["openid", "profile", "email", "groups", "offline_access"],
|
||||||
token_endpoint_auth_methods_supported: ["client_secret_post", "client_secret_basic"],
|
token_endpoint_auth_methods_supported: ["client_secret_post", "client_secret_basic"],
|
||||||
claims_supported: ["sub", "email", "email_verified", "name", "preferred_username", "groups", "admin", "auth_time", "acr", "azp", "at_hash"],
|
claims_supported: [
|
||||||
|
"sub", # Always included
|
||||||
|
"email", # email scope
|
||||||
|
"email_verified", # email scope
|
||||||
|
"name", # profile scope
|
||||||
|
"preferred_username", # profile scope
|
||||||
|
"updated_at", # profile scope
|
||||||
|
"groups" # groups scope
|
||||||
|
# Note: Custom claims are also supported but not listed here
|
||||||
|
# ID-token-only claims (auth_time, acr, azp, at_hash, nonce) are not listed
|
||||||
|
],
|
||||||
code_challenge_methods_supported: ["plain", "S256"],
|
code_challenge_methods_supported: ["plain", "S256"],
|
||||||
backchannel_logout_supported: true,
|
backchannel_logout_supported: true,
|
||||||
backchannel_logout_session_supported: true
|
backchannel_logout_session_supported: true
|
||||||
@@ -657,26 +667,13 @@ class OidcController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Profile claims (only if 'profile' scope requested)
|
# Profile claims (only if 'profile' scope requested)
|
||||||
# Per OIDC Core spec section 5.4, all profile claims SHOULD be returned
|
# Per OIDC Core spec section 5.4, include available profile claims
|
||||||
|
# Only include claims we have data for - omit unknown claims rather than returning null
|
||||||
if requested_scopes.include?("profile")
|
if requested_scopes.include?("profile")
|
||||||
# Use username if available, otherwise email as preferred_username
|
# Use username if available, otherwise email as preferred_username
|
||||||
claims[:preferred_username] = user.username.presence || user.email_address
|
claims[:preferred_username] = user.username.presence || user.email_address
|
||||||
# Name: use stored name or fall back to email
|
# Name: use stored name or fall back to email
|
||||||
claims[:name] = user.name.presence || user.email_address
|
claims[:name] = user.name.presence || user.email_address
|
||||||
|
|
||||||
# Standard profile claims we don't store - set to nil (optional per spec)
|
|
||||||
claims[:given_name] = nil
|
|
||||||
claims[:family_name] = nil
|
|
||||||
claims[:middle_name] = nil
|
|
||||||
claims[:nickname] = nil
|
|
||||||
claims[:profile] = nil
|
|
||||||
claims[:picture] = nil
|
|
||||||
claims[:website] = nil
|
|
||||||
claims[:gender] = nil
|
|
||||||
claims[:birthdate] = nil
|
|
||||||
claims[:zoneinfo] = nil
|
|
||||||
claims[:locale] = nil
|
|
||||||
|
|
||||||
# Time the user's information was last updated
|
# Time the user's information was last updated
|
||||||
claims[:updated_at] = user.updated_at.to_i
|
claims[:updated_at] = user.updated_at.to_i
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -23,17 +23,10 @@ class OidcJwtService
|
|||||||
iat: now
|
iat: now
|
||||||
}
|
}
|
||||||
|
|
||||||
# Email claims (only if 'email' scope requested)
|
# NOTE: Email and profile claims are NOT included in the ID token for authorization code flow
|
||||||
if requested_scopes.include?("email")
|
# Per OIDC Core spec §5.4, these claims should only be returned via the UserInfo endpoint
|
||||||
payload[:email] = user.email_address
|
# For implicit flow (response_type=id_token), claims would be included here, but we only
|
||||||
payload[:email_verified] = true
|
# support authorization code flow, so these claims are omitted from the ID token.
|
||||||
end
|
|
||||||
|
|
||||||
# Profile claims (only if 'profile' scope requested)
|
|
||||||
if requested_scopes.include?("profile")
|
|
||||||
payload[:preferred_username] = user.username.presence || user.email_address
|
|
||||||
payload[:name] = user.name.presence || user.email_address
|
|
||||||
end
|
|
||||||
|
|
||||||
# Add nonce if provided (OIDC requires this for implicit flow)
|
# Add nonce if provided (OIDC requires this for implicit flow)
|
||||||
payload[:nonce] = nonce if nonce.present?
|
payload[:nonce] = nonce if nonce.present?
|
||||||
|
|||||||
@@ -115,25 +115,10 @@ class OidcUserinfoControllerTest < ActionDispatch::IntegrationTest
|
|||||||
# Required claims
|
# Required claims
|
||||||
assert json["sub"].present?
|
assert json["sub"].present?
|
||||||
|
|
||||||
# All standard profile claims should be present (per OIDC Core spec section 5.4)
|
# Profile claims we support should be present
|
||||||
# Some may be null if we don't have the data, but the keys should exist
|
assert json["name"].present?, "Should include name with profile scope"
|
||||||
assert json.key?("name"), "Should include name claim"
|
assert json["preferred_username"].present?, "Should include preferred_username with profile scope"
|
||||||
assert json.key?("given_name"), "Should include given_name claim (may be null)"
|
assert json["updated_at"].present?, "Should include updated_at with profile scope"
|
||||||
assert json.key?("family_name"), "Should include family_name claim (may be null)"
|
|
||||||
assert json.key?("middle_name"), "Should include middle_name claim (may be null)"
|
|
||||||
assert json.key?("nickname"), "Should include nickname claim (may be null)"
|
|
||||||
assert json.key?("preferred_username"), "Should include preferred_username claim"
|
|
||||||
assert json.key?("profile"), "Should include profile claim (may be null)"
|
|
||||||
assert json.key?("picture"), "Should include picture claim (may be null)"
|
|
||||||
assert json.key?("website"), "Should include website claim (may be null)"
|
|
||||||
assert json.key?("gender"), "Should include gender claim (may be null)"
|
|
||||||
assert json.key?("birthdate"), "Should include birthdate claim (may be null)"
|
|
||||||
assert json.key?("zoneinfo"), "Should include zoneinfo claim (may be null)"
|
|
||||||
assert json.key?("locale"), "Should include locale claim (may be null)"
|
|
||||||
assert json.key?("updated_at"), "Should include updated_at claim"
|
|
||||||
|
|
||||||
# Verify preferred_username is using username or email
|
|
||||||
assert json["preferred_username"].present?, "preferred_username should have a value"
|
|
||||||
|
|
||||||
# Email claims should NOT be present
|
# Email claims should NOT be present
|
||||||
assert_nil json["email"], "Should not include email without email scope"
|
assert_nil json["email"], "Should not include email without email scope"
|
||||||
|
|||||||
Reference in New Issue
Block a user