diff --git a/proto/src/oauth2.rs b/proto/src/oauth2.rs index a17305e1a..1d074ed46 100644 --- a/proto/src/oauth2.rs +++ b/proto/src/oauth2.rs @@ -433,6 +433,21 @@ pub struct OidcDiscoveryResponse { pub require_request_uri_registration: bool, pub code_challenge_methods_supported: Vec, + + // https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse + // "content type that contains a set of Claims as its members that are a subset of the Metadata + // values defined in Section 3. Other Claims MAY also be returned. " + // + // In addition, we also return the following claims in kanidm + + // rfc7009 + pub revocation_endpoint: Option, + pub revocation_endpoint_auth_methods_supported: Vec, + + // rfc7662 + pub introspection_endpoint: Option, + pub introspection_endpoint_auth_methods_supported: Vec, + pub introspection_endpoint_auth_signing_alg_values_supported: Option>, } /// The response to an OAuth2 rfc8414 metadata request diff --git a/server/lib/src/idm/oauth2.rs b/server/lib/src/idm/oauth2.rs index 8e205e7b5..c515338be 100644 --- a/server/lib/src/idm/oauth2.rs +++ b/server/lib/src/idm/oauth2.rs @@ -2473,6 +2473,20 @@ impl<'a> IdmServerProxyReadTransaction<'a> { Vec::with_capacity(0) }; + // The following are extensions allowed by the oidc specification. + + let revocation_endpoint = Some(o2rs.revocation_endpoint.clone()); + let revocation_endpoint_auth_methods_supported = vec![ + TokenEndpointAuthMethod::ClientSecretBasic, + TokenEndpointAuthMethod::ClientSecretPost, + ]; + + let introspection_endpoint = Some(o2rs.introspection_endpoint.clone()); + let introspection_endpoint_auth_methods_supported = vec![ + TokenEndpointAuthMethod::ClientSecretBasic, + TokenEndpointAuthMethod::ClientSecretPost, + ]; + Ok(OidcDiscoveryResponse { issuer, authorization_endpoint, @@ -2513,6 +2527,12 @@ impl<'a> IdmServerProxyReadTransaction<'a> { op_policy_uri: None, op_tos_uri: None, code_challenge_methods_supported, + // Extensions + revocation_endpoint, + revocation_endpoint_auth_methods_supported, + introspection_endpoint, + introspection_endpoint_auth_methods_supported, + introspection_endpoint_auth_signing_alg_values_supported: None, }) } @@ -4481,7 +4501,35 @@ mod tests { assert_eq!( discovery.code_challenge_methods_supported, vec![PkceAlg::S256] - ) + ); + + // Extensions + assert!( + discovery.revocation_endpoint + == Some(Url::parse("https://idm.example.com/oauth2/token/revoke").unwrap()) + ); + assert!( + discovery.revocation_endpoint_auth_methods_supported + == vec![ + TokenEndpointAuthMethod::ClientSecretBasic, + TokenEndpointAuthMethod::ClientSecretPost + ] + ); + + assert!( + discovery.introspection_endpoint + == Some(Url::parse("https://idm.example.com/oauth2/token/introspect").unwrap()) + ); + assert!( + discovery.introspection_endpoint_auth_methods_supported + == vec![ + TokenEndpointAuthMethod::ClientSecretBasic, + TokenEndpointAuthMethod::ClientSecretPost + ] + ); + assert!(discovery + .introspection_endpoint_auth_signing_alg_values_supported + .is_none()); } #[idm_test]