KEYCLOAK-18636 The mtls_endpoint_aliases claim is not advertized in the discovery document

This commit is contained in:
mposolda 2021-07-28 08:22:41 +02:00 committed by Marek Posolda
parent e58eeca800
commit 05dfed721a
4 changed files with 158 additions and 0 deletions

View file

@ -0,0 +1,125 @@
/*
* Copyright 2021 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.keycloak.protocol.oidc.representations;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonProperty;
public class MTLSEndpointAliases {
@JsonProperty("token_endpoint")
private String tokenEndpoint;
@JsonProperty("revocation_endpoint")
private String revocationEndpoint;
@JsonProperty("introspection_endpoint")
private String introspectionEndpoint;
@JsonProperty("device_authorization_endpoint")
private String deviceAuthorizationEndpoint;
@JsonProperty("registration_endpoint")
private String registrationEndpoint;
@JsonProperty("userinfo_endpoint")
private String userInfoEndpoint;
@JsonProperty("pushed_authorization_request_endpoint")
private String pushedAuthorizationRequestEndpoint;
@JsonProperty("backchannel_authentication_endpoint")
private String backchannelAuthenticationEndpoint;
// For custom endpoints in the future
protected Map<String, Object> otherClaims = new HashMap<String, Object>();
public MTLSEndpointAliases() { }
public String getTokenEndpoint() {
return tokenEndpoint;
}
public void setTokenEndpoint(String tokenEndpoint) {
this.tokenEndpoint = tokenEndpoint;
}
public String getRevocationEndpoint() {
return revocationEndpoint;
}
public void setRevocationEndpoint(String revocationEndpoint) {
this.revocationEndpoint = revocationEndpoint;
}
public String getIntrospectionEndpoint() {
return introspectionEndpoint;
}
public void setIntrospectionEndpoint(String introspectionEndpoint) {
this.introspectionEndpoint = introspectionEndpoint;
}
public String getDeviceAuthorizationEndpoint() {
return deviceAuthorizationEndpoint;
}
public void setDeviceAuthorizationEndpoint(String deviceAuthorizationEndpoint) {
this.deviceAuthorizationEndpoint = deviceAuthorizationEndpoint;
}
public String getRegistrationEndpoint() {
return registrationEndpoint;
}
public void setRegistrationEndpoint(String registrationEndpoint) {
this.registrationEndpoint = registrationEndpoint;
}
public String getUserInfoEndpoint() {
return userInfoEndpoint;
}
public void setUserInfoEndpoint(String userInfoEndpoint) {
this.userInfoEndpoint = userInfoEndpoint;
}
public String getPushedAuthorizationRequestEndpoint() {
return pushedAuthorizationRequestEndpoint;
}
public void setPushedAuthorizationRequestEndpoint(String pushedAuthorizationRequestEndpoint) {
this.pushedAuthorizationRequestEndpoint = pushedAuthorizationRequestEndpoint;
}
public String getBackchannelAuthenticationEndpoint() {
return backchannelAuthenticationEndpoint;
}
public void setBackchannelAuthenticationEndpoint(String backchannelAuthenticationEndpoint) {
this.backchannelAuthenticationEndpoint = backchannelAuthenticationEndpoint;
}
@JsonAnyGetter
public Map<String, Object> getOtherClaims() {
return otherClaims;
}
@JsonAnySetter
public void setOtherClaims(String name, Object value) {
otherClaims.put(name, value);
}
}

View file

@ -175,6 +175,9 @@ public class OIDCConfigurationRepresentation {
@JsonProperty("pushed_authorization_request_endpoint")
private String pushedAuthorizationRequestEndpoint;
@JsonProperty("mtls_endpoint_aliases")
private MTLSEndpointAliases mtlsEndpointAliases;
protected Map<String, Object> otherClaims = new HashMap<String, Object>();
public String getIssuer() {
@ -525,6 +528,14 @@ public class OIDCConfigurationRepresentation {
this.requirePushedAuthorizationRequests = requirePushedAuthorizationRequests;
}
public MTLSEndpointAliases getMtlsEndpointAliases() {
return mtlsEndpointAliases;
}
public void setMtlsEndpointAliases(MTLSEndpointAliases mtlsEndpointAliases) {
this.mtlsEndpointAliases = mtlsEndpointAliases;
}
@JsonAnyGetter
public Map<String, Object> getOtherClaims() {
return otherClaims;

View file

@ -35,6 +35,7 @@ import org.keycloak.protocol.oidc.endpoints.TokenEndpoint;
import org.keycloak.protocol.oidc.grants.ciba.CibaGrantType;
import org.keycloak.protocol.oidc.grants.device.endpoints.DeviceEndpoint;
import org.keycloak.protocol.oidc.par.endpoints.ParEndpoint;
import org.keycloak.protocol.oidc.representations.MTLSEndpointAliases;
import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation;
import org.keycloak.protocol.oidc.utils.OIDCResponseType;
import org.keycloak.provider.Provider;
@ -186,6 +187,9 @@ public class OIDCWellKnownProvider implements WellKnownProvider {
config.setPushedAuthorizationRequestEndpoint(ParEndpoint.parUrl(backendUriInfo.getBaseUriBuilder()).build(realm.getName()).toString());
config.setRequirePushedAuthorizationRequests(Boolean.FALSE);
MTLSEndpointAliases mtlsEndpointAliases = getMtlsEndpointAliases(config);
config.setMtlsEndpointAliases(mtlsEndpointAliases);
return config;
}
@ -251,4 +255,18 @@ public class OIDCWellKnownProvider implements WellKnownProvider {
private List<String> getSupportedEncryptionEnc(boolean includeNone) {
return getSupportedAlgorithms(ContentEncryptionProvider.class, includeNone);
}
// 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;
}
}

View file

@ -31,6 +31,7 @@ import org.keycloak.jose.jwk.JSONWebKeySet;
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
import org.keycloak.protocol.oidc.OIDCWellKnownProviderFactory;
import org.keycloak.protocol.oidc.representations.MTLSEndpointAliases;
import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation;
import org.keycloak.protocol.oidc.utils.OIDCResponseType;
import org.keycloak.representations.IDToken;
@ -175,6 +176,9 @@ public class OIDCWellKnownProviderTest extends AbstractKeycloakTest {
// 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());