use of org.keycloak.protocol.oidc.representations.MTLSEndpointAliases in project keycloak by keycloak.
the class OIDCWellKnownProviderTest method testDefaultProviderCustomizations.
@Test
@AuthServerContainerExclude(REMOTE)
public void testDefaultProviderCustomizations() throws IOException {
Client client = AdminClientUtil.createResteasyClient();
try {
OIDCConfigurationRepresentation oidcConfig = getOIDCDiscoveryRepresentation(client, OAuthClient.AUTH_SERVER_ROOT);
// Assert that CustomOIDCWellKnownProvider was used as a prioritized provider over default OIDCWellKnownProvider
MTLSEndpointAliases mtlsEndpointAliases = oidcConfig.getMtlsEndpointAliases();
Assert.assertEquals("https://placeholder-host-set-by-testsuite-provider/registration", mtlsEndpointAliases.getRegistrationEndpoint());
Assert.assertEquals("bar", oidcConfig.getOtherClaims().get("foo"));
// Assert some configuration was overriden
Assert.assertEquals("some-new-property-value", oidcConfig.getOtherClaims().get("some-new-property"));
Assert.assertEquals("nested-value", ((Map) oidcConfig.getOtherClaims().get("some-new-property-compound")).get("nested1"));
Assert.assertNames(oidcConfig.getIntrospectionEndpointAuthMethodsSupported(), "private_key_jwt", "client_secret_jwt", "tls_client_auth", "custom_nonexisting_authenticator");
// Exact names already tested in OIDC
assertScopesSupportedMatchesWithRealm(oidcConfig);
// Temporarily disable client scopes
getTestingClient().testing().setSystemPropertyOnServer(CustomOIDCWellKnownProviderFactory.INCLUDE_CLIENT_SCOPES, "false");
oidcConfig = getOIDCDiscoveryRepresentation(client, OAuthClient.AUTH_SERVER_ROOT);
Assert.assertNull(oidcConfig.getScopesSupported());
} finally {
getTestingClient().testing().setSystemPropertyOnServer(CustomOIDCWellKnownProviderFactory.INCLUDE_CLIENT_SCOPES, null);
client.close();
}
}
use of org.keycloak.protocol.oidc.representations.MTLSEndpointAliases in project keycloak by keycloak.
the class OIDCWellKnownProvider method getMtlsEndpointAliases.
// Use protected method to make it easier to override in custom provider if different URLs are requested to be used as mtls_endpoint_aliases
protected MTLSEndpointAliases getMtlsEndpointAliases(OIDCConfigurationRepresentation config) {
MTLSEndpointAliases mtls_endpoints = new MTLSEndpointAliases();
mtls_endpoints.setTokenEndpoint(config.getTokenEndpoint());
mtls_endpoints.setRevocationEndpoint(config.getRevocationEndpoint());
mtls_endpoints.setIntrospectionEndpoint(config.getIntrospectionEndpoint());
mtls_endpoints.setDeviceAuthorizationEndpoint(config.getDeviceAuthorizationEndpoint());
mtls_endpoints.setRegistrationEndpoint(config.getRegistrationEndpoint());
mtls_endpoints.setUserInfoEndpoint(config.getUserinfoEndpoint());
mtls_endpoints.setBackchannelAuthenticationEndpoint(config.getBackchannelAuthenticationEndpoint());
mtls_endpoints.setPushedAuthorizationRequestEndpoint(config.getPushedAuthorizationRequestEndpoint());
return mtls_endpoints;
}
use of org.keycloak.protocol.oidc.representations.MTLSEndpointAliases in project keycloak by keycloak.
the class OIDCWellKnownProvider method getConfig.
@Override
public Object getConfig() {
UriInfo frontendUriInfo = session.getContext().getUri(UrlType.FRONTEND);
UriInfo backendUriInfo = session.getContext().getUri(UrlType.BACKEND);
RealmModel realm = session.getContext().getRealm();
UriBuilder frontendUriBuilder = RealmsResource.protocolUrl(frontendUriInfo);
UriBuilder backendUriBuilder = RealmsResource.protocolUrl(backendUriInfo);
OIDCConfigurationRepresentation config = new OIDCConfigurationRepresentation();
config.setIssuer(Urls.realmIssuer(frontendUriInfo.getBaseUri(), realm.getName()));
config.setAuthorizationEndpoint(frontendUriBuilder.clone().path(OIDCLoginProtocolService.class, "auth").build(realm.getName(), OIDCLoginProtocol.LOGIN_PROTOCOL).toString());
config.setTokenEndpoint(backendUriBuilder.clone().path(OIDCLoginProtocolService.class, "token").build(realm.getName(), OIDCLoginProtocol.LOGIN_PROTOCOL).toString());
config.setIntrospectionEndpoint(backendUriBuilder.clone().path(OIDCLoginProtocolService.class, "token").path(TokenEndpoint.class, "introspect").build(realm.getName(), OIDCLoginProtocol.LOGIN_PROTOCOL).toString());
config.setUserinfoEndpoint(backendUriBuilder.clone().path(OIDCLoginProtocolService.class, "issueUserInfo").build(realm.getName(), OIDCLoginProtocol.LOGIN_PROTOCOL).toString());
config.setLogoutEndpoint(frontendUriBuilder.clone().path(OIDCLoginProtocolService.class, "logout").build(realm.getName(), OIDCLoginProtocol.LOGIN_PROTOCOL).toString());
config.setDeviceAuthorizationEndpoint(frontendUriBuilder.clone().path(OIDCLoginProtocolService.class, "auth").path(AuthorizationEndpoint.class, "authorizeDevice").path(DeviceEndpoint.class, "handleDeviceRequest").build(realm.getName(), OIDCLoginProtocol.LOGIN_PROTOCOL).toString());
URI jwksUri = backendUriBuilder.clone().path(OIDCLoginProtocolService.class, "certs").build(realm.getName(), OIDCLoginProtocol.LOGIN_PROTOCOL);
// NOTE: Don't hardcode HTTPS checks here. JWKS URI is exposed just in the development/testing environment. For the production environment, the OIDCWellKnownProvider
// is not exposed over "http" at all.
// if (isHttps(jwksUri)) {
config.setJwksUri(jwksUri.toString());
config.setCheckSessionIframe(frontendUriBuilder.clone().path(OIDCLoginProtocolService.class, "getLoginStatusIframe").build(realm.getName(), OIDCLoginProtocol.LOGIN_PROTOCOL).toString());
config.setRegistrationEndpoint(RealmsResource.clientRegistrationUrl(backendUriInfo).path(ClientRegistrationService.class, "provider").build(realm.getName(), OIDCClientRegistrationProviderFactory.ID).toString());
config.setIdTokenSigningAlgValuesSupported(getSupportedSigningAlgorithms(false));
config.setIdTokenEncryptionAlgValuesSupported(getSupportedEncryptionAlg(false));
config.setIdTokenEncryptionEncValuesSupported(getSupportedEncryptionEnc(false));
config.setUserInfoSigningAlgValuesSupported(getSupportedSigningAlgorithms(true));
config.setRequestObjectSigningAlgValuesSupported(getSupportedClientSigningAlgorithms(true));
config.setRequestObjectEncryptionAlgValuesSupported(getSupportedEncryptionAlgorithms());
config.setRequestObjectEncryptionEncValuesSupported(getSupportedContentEncryptionAlgorithms());
config.setResponseTypesSupported(DEFAULT_RESPONSE_TYPES_SUPPORTED);
config.setSubjectTypesSupported(DEFAULT_SUBJECT_TYPES_SUPPORTED);
config.setResponseModesSupported(DEFAULT_RESPONSE_MODES_SUPPORTED);
config.setGrantTypesSupported(DEFAULT_GRANT_TYPES_SUPPORTED);
config.setAcrValuesSupported(getAcrValuesSupported(realm));
config.setTokenEndpointAuthMethodsSupported(getClientAuthMethodsSupported());
config.setTokenEndpointAuthSigningAlgValuesSupported(getSupportedClientSigningAlgorithms(false));
config.setIntrospectionEndpointAuthMethodsSupported(getClientAuthMethodsSupported());
config.setIntrospectionEndpointAuthSigningAlgValuesSupported(getSupportedClientSigningAlgorithms(false));
config.setAuthorizationSigningAlgValuesSupported(getSupportedSigningAlgorithms(false));
config.setAuthorizationEncryptionAlgValuesSupported(getSupportedEncryptionAlg(false));
config.setAuthorizationEncryptionEncValuesSupported(getSupportedEncryptionEnc(false));
config.setClaimsSupported(DEFAULT_CLAIMS_SUPPORTED);
config.setClaimTypesSupported(DEFAULT_CLAIM_TYPES_SUPPORTED);
config.setClaimsParameterSupported(true);
// Include client scopes can be disabled in the environments with thousands of client scopes to avoid potentially expensive iteration over client scopes
if (includeClientScopes) {
List<String> scopeNames = realm.getClientScopesStream().filter(clientScope -> Objects.equals(OIDCLoginProtocol.LOGIN_PROTOCOL, clientScope.getProtocol())).map(ClientScopeModel::getName).collect(Collectors.toList());
scopeNames.add(0, OAuth2Constants.SCOPE_OPENID);
config.setScopesSupported(scopeNames);
}
config.setRequestParameterSupported(true);
config.setRequestUriParameterSupported(true);
config.setRequireRequestUriRegistration(true);
// KEYCLOAK-7451 OAuth Authorization Server Metadata for Proof Key for Code Exchange
config.setCodeChallengeMethodsSupported(DEFAULT_CODE_CHALLENGE_METHODS_SUPPORTED);
// KEYCLOAK-6771 Certificate Bound Token
// https://tools.ietf.org/html/draft-ietf-oauth-mtls-08#section-6.2
config.setTlsClientCertificateBoundAccessTokens(true);
URI revocationEndpoint = frontendUriBuilder.clone().path(OIDCLoginProtocolService.class, "revoke").build(realm.getName(), OIDCLoginProtocol.LOGIN_PROTOCOL);
// NOTE: Don't hardcode HTTPS checks here. JWKS URI is exposed just in the development/testing environment. For the production environment, the OIDCWellKnownProvider
// is not exposed over "http" at all.
config.setRevocationEndpoint(revocationEndpoint.toString());
config.setRevocationEndpointAuthMethodsSupported(getClientAuthMethodsSupported());
config.setRevocationEndpointAuthSigningAlgValuesSupported(getSupportedClientSigningAlgorithms(false));
config.setBackchannelLogoutSupported(true);
config.setBackchannelLogoutSessionSupported(true);
config.setBackchannelTokenDeliveryModesSupported(CibaConfig.CIBA_SUPPORTED_MODES);
config.setBackchannelAuthenticationEndpoint(CibaGrantType.authorizationUrl(backendUriInfo.getBaseUriBuilder()).build(realm.getName()).toString());
config.setBackchannelAuthenticationRequestSigningAlgValuesSupported(getSupportedBackchannelAuthenticationRequestSigningAlgorithms());
config.setPushedAuthorizationRequestEndpoint(ParEndpoint.parUrl(backendUriInfo.getBaseUriBuilder()).build(realm.getName()).toString());
config.setRequirePushedAuthorizationRequests(Boolean.FALSE);
MTLSEndpointAliases mtlsEndpointAliases = getMtlsEndpointAliases(config);
config.setMtlsEndpointAliases(mtlsEndpointAliases);
config = checkConfigOverride(config);
return config;
}
use of org.keycloak.protocol.oidc.representations.MTLSEndpointAliases in project keycloak by keycloak.
the class OIDCWellKnownProviderTest method testDiscovery.
@Test
public void testDiscovery() {
Client client = AdminClientUtil.createResteasyClient();
try {
OIDCConfigurationRepresentation oidcConfig = getOIDCDiscoveryRepresentation(client, OAuthClient.AUTH_SERVER_ROOT);
// URIs are filled
assertEquals(oidcConfig.getAuthorizationEndpoint(), OIDCLoginProtocolService.authUrl(UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT)).build("test").toString());
assertEquals(oidcConfig.getTokenEndpoint(), oauth.getAccessTokenUrl());
assertEquals(oidcConfig.getUserinfoEndpoint(), OIDCLoginProtocolService.userInfoUrl(UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT)).build("test").toString());
assertEquals(oidcConfig.getJwksUri(), oauth.getCertsUrl("test"));
String registrationUri = UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT).path(RealmsResource.class).path(RealmsResource.class, "getClientsService").path(ClientRegistrationService.class, "provider").build("test", OIDCClientRegistrationProviderFactory.ID).toString();
assertEquals(oidcConfig.getRegistrationEndpoint(), registrationUri);
// Support standard + implicit + hybrid flow
assertContains(oidcConfig.getResponseTypesSupported(), OAuth2Constants.CODE, OIDCResponseType.ID_TOKEN, "id_token token", "code id_token", "code token", "code id_token token");
assertContains(oidcConfig.getGrantTypesSupported(), OAuth2Constants.AUTHORIZATION_CODE, OAuth2Constants.IMPLICIT, OAuth2Constants.DEVICE_CODE_GRANT_TYPE);
assertContains(oidcConfig.getResponseModesSupported(), "query", "fragment", "form_post", "jwt", "query.jwt", "fragment.jwt", "form_post.jwt");
Assert.assertNames(oidcConfig.getSubjectTypesSupported(), "pairwise", "public");
// Signature algorithms
Assert.assertNames(oidcConfig.getIdTokenSigningAlgValuesSupported(), Algorithm.PS256, Algorithm.PS384, Algorithm.PS512, Algorithm.RS256, Algorithm.RS384, Algorithm.RS512, Algorithm.ES256, Algorithm.ES384, Algorithm.ES512, Algorithm.HS256, Algorithm.HS384, Algorithm.HS512);
Assert.assertNames(oidcConfig.getUserInfoSigningAlgValuesSupported(), "none", Algorithm.PS256, Algorithm.PS384, Algorithm.PS512, Algorithm.RS256, Algorithm.RS384, Algorithm.RS512, Algorithm.ES256, Algorithm.ES384, Algorithm.ES512, Algorithm.HS256, Algorithm.HS384, Algorithm.HS512);
Assert.assertNames(oidcConfig.getRequestObjectSigningAlgValuesSupported(), "none", Algorithm.PS256, Algorithm.PS384, Algorithm.PS512, Algorithm.RS256, Algorithm.RS384, Algorithm.RS512, Algorithm.ES256, Algorithm.ES384, Algorithm.ES512, Algorithm.HS256, Algorithm.HS384, Algorithm.HS512);
Assert.assertNames(oidcConfig.getAuthorizationSigningAlgValuesSupported(), Algorithm.PS256, Algorithm.PS384, Algorithm.PS512, Algorithm.RS256, Algorithm.RS384, Algorithm.RS512, Algorithm.ES256, Algorithm.ES384, Algorithm.ES512, Algorithm.HS256, Algorithm.HS384, Algorithm.HS512);
// request object encryption algorithms
Assert.assertNames(oidcConfig.getRequestObjectEncryptionAlgValuesSupported(), JWEConstants.RSA_OAEP, JWEConstants.RSA_OAEP_256, JWEConstants.RSA1_5);
Assert.assertNames(oidcConfig.getRequestObjectEncryptionEncValuesSupported(), JWEConstants.A256GCM, JWEConstants.A192GCM, JWEConstants.A128GCM, JWEConstants.A128CBC_HS256, JWEConstants.A192CBC_HS384, JWEConstants.A256CBC_HS512);
// Encryption algorithms
Assert.assertNames(oidcConfig.getIdTokenEncryptionAlgValuesSupported(), JWEConstants.RSA1_5, JWEConstants.RSA_OAEP, JWEConstants.RSA_OAEP_256);
Assert.assertNames(oidcConfig.getIdTokenEncryptionEncValuesSupported(), JWEConstants.A128CBC_HS256, JWEConstants.A128GCM, JWEConstants.A192CBC_HS384, JWEConstants.A192GCM, JWEConstants.A256CBC_HS512, JWEConstants.A256GCM);
Assert.assertNames(oidcConfig.getAuthorizationEncryptionAlgValuesSupported(), JWEConstants.RSA1_5, JWEConstants.RSA_OAEP, JWEConstants.RSA_OAEP_256);
Assert.assertNames(oidcConfig.getAuthorizationEncryptionEncValuesSupported(), JWEConstants.A128CBC_HS256, JWEConstants.A128GCM, JWEConstants.A192CBC_HS384, JWEConstants.A192GCM, JWEConstants.A256CBC_HS512, JWEConstants.A256GCM);
// Client authentication
Assert.assertNames(oidcConfig.getTokenEndpointAuthMethodsSupported(), "client_secret_basic", "client_secret_post", "private_key_jwt", "client_secret_jwt", "tls_client_auth");
Assert.assertNames(oidcConfig.getTokenEndpointAuthSigningAlgValuesSupported(), Algorithm.PS256, Algorithm.PS384, Algorithm.PS512, Algorithm.RS256, Algorithm.RS384, Algorithm.RS512, Algorithm.ES256, Algorithm.ES384, Algorithm.ES512, Algorithm.HS256, Algorithm.HS384, Algorithm.HS512);
// NOTE: Those are overriden in "oidc-well-known-config-override.json" and they are tested in testDefaultProviderCustomizations
// Assert.assertNames(oidcConfig.getIntrospectionEndpointAuthMethodsSupported(), "private_key_jwt", "client_secret_jwt", "tls_client_auth", "custom_nonexisting_authenticator");
Assert.assertNames(oidcConfig.getIntrospectionEndpointAuthSigningAlgValuesSupported(), Algorithm.PS256, Algorithm.PS384, Algorithm.PS512, Algorithm.RS256, Algorithm.RS384, Algorithm.RS512, Algorithm.ES256, Algorithm.ES384, Algorithm.ES512, Algorithm.HS256, Algorithm.HS384, Algorithm.HS512);
// Claims
assertContains(oidcConfig.getClaimsSupported(), IDToken.NAME, IDToken.EMAIL, IDToken.PREFERRED_USERNAME, IDToken.FAMILY_NAME, IDToken.ACR);
Assert.assertNames(oidcConfig.getClaimTypesSupported(), "normal");
Assert.assertTrue(oidcConfig.getClaimsParameterSupported());
// Scopes supported
assertScopesSupportedMatchesWithRealm(oidcConfig);
// Request and Request_Uri
Assert.assertTrue(oidcConfig.getRequestParameterSupported());
Assert.assertTrue(oidcConfig.getRequestUriParameterSupported());
Assert.assertTrue(oidcConfig.getRequireRequestUriRegistration());
// KEYCLOAK-7451 OAuth Authorization Server Metadata for Proof Key for Code Exchange
// PKCE support
Assert.assertNames(oidcConfig.getCodeChallengeMethodsSupported(), OAuth2Constants.PKCE_METHOD_PLAIN, OAuth2Constants.PKCE_METHOD_S256);
// KEYCLOAK-6771 Certificate Bound Token
// https://tools.ietf.org/html/draft-ietf-oauth-mtls-08#section-6.2
Assert.assertTrue(oidcConfig.getTlsClientCertificateBoundAccessTokens());
MTLSEndpointAliases mtlsEndpointAliases = oidcConfig.getMtlsEndpointAliases();
Assert.assertEquals(oidcConfig.getTokenEndpoint(), mtlsEndpointAliases.getTokenEndpoint());
Assert.assertEquals(oidcConfig.getRevocationEndpoint(), mtlsEndpointAliases.getRevocationEndpoint());
// CIBA
assertEquals(oidcConfig.getBackchannelAuthenticationEndpoint(), oauth.getBackchannelAuthenticationUrl());
assertContains(oidcConfig.getGrantTypesSupported(), OAuth2Constants.CIBA_GRANT_TYPE);
Assert.assertNames(oidcConfig.getBackchannelTokenDeliveryModesSupported(), "poll", "ping");
Assert.assertNames(oidcConfig.getBackchannelAuthenticationRequestSigningAlgValuesSupported(), Algorithm.PS256, Algorithm.PS384, Algorithm.PS512, Algorithm.RS256, Algorithm.RS384, Algorithm.RS512, Algorithm.ES256, Algorithm.ES384, Algorithm.ES512);
Assert.assertTrue(oidcConfig.getBackchannelLogoutSupported());
Assert.assertTrue(oidcConfig.getBackchannelLogoutSessionSupported());
// Token Revocation
assertEquals(oidcConfig.getRevocationEndpoint(), oauth.getTokenRevocationUrl());
Assert.assertNames(oidcConfig.getRevocationEndpointAuthMethodsSupported(), "client_secret_basic", "client_secret_post", "private_key_jwt", "client_secret_jwt", "tls_client_auth");
Assert.assertNames(oidcConfig.getRevocationEndpointAuthSigningAlgValuesSupported(), Algorithm.PS256, Algorithm.PS384, Algorithm.PS512, Algorithm.RS256, Algorithm.RS384, Algorithm.RS512, Algorithm.ES256, Algorithm.ES384, Algorithm.ES512, Algorithm.HS256, Algorithm.HS384, Algorithm.HS512);
assertEquals(oidcConfig.getDeviceAuthorizationEndpoint(), oauth.getDeviceAuthorizationUrl());
// Pushed Authorization Request (PAR)
assertEquals(oauth.getParEndpointUrl(), oidcConfig.getPushedAuthorizationRequestEndpoint());
assertEquals(Boolean.FALSE, oidcConfig.getRequirePushedAuthorizationRequests());
// frontchannel logout
assertTrue(oidcConfig.getFrontChannelLogoutSessionSupported());
assertTrue(oidcConfig.getFrontChannelLogoutSupported());
} finally {
client.close();
}
}
use of org.keycloak.protocol.oidc.representations.MTLSEndpointAliases in project keycloak by keycloak.
the class CustomOIDCWellKnownProvider method getMtlsEndpointAliases.
@Override
protected MTLSEndpointAliases getMtlsEndpointAliases(OIDCConfigurationRepresentation config) {
MTLSEndpointAliases mtlsEndpointAliases = super.getMtlsEndpointAliases(config);
mtlsEndpointAliases.setRegistrationEndpoint("https://placeholder-host-set-by-testsuite-provider/registration");
return mtlsEndpointAliases;
}
Aggregations