KEYCLOAK-7997 Implement Client Registration Metadata based on Mutual TLS
This commit is contained in:
parent
12d965abf3
commit
be0ba79daa
4 changed files with 69 additions and 0 deletions
|
@ -100,6 +100,8 @@ public class OIDCClientRepresentation {
|
|||
// https://tools.ietf.org/html/draft-ietf-oauth-mtls-08#section-6.5
|
||||
private Boolean tls_client_certificate_bound_access_tokens;
|
||||
|
||||
private String tls_client_auth_subject_dn;
|
||||
|
||||
// OIDC Session Management
|
||||
private List<String> post_logout_redirect_uris;
|
||||
|
||||
|
@ -446,4 +448,13 @@ public class OIDCClientRepresentation {
|
|||
public void setTlsClientCertificateBoundAccessTokens(Boolean tls_client_certificate_bound_access_tokens) {
|
||||
this.tls_client_certificate_bound_access_tokens = tls_client_certificate_bound_access_tokens;
|
||||
}
|
||||
|
||||
public String getTlsClientAuthSubjectDn() {
|
||||
return tls_client_auth_subject_dn;
|
||||
}
|
||||
|
||||
public void setTlsClientAuthSubjectDn(String tls_client_auth_subject_dn) {
|
||||
this.tls_client_auth_subject_dn = tls_client_auth_subject_dn;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.keycloak.protocol.oidc;
|
||||
|
||||
import org.keycloak.authentication.authenticators.client.X509ClientAuthenticator;
|
||||
import org.keycloak.jose.jws.Algorithm;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
|
@ -118,6 +119,14 @@ public class OIDCAdvancedConfigWrapper {
|
|||
setAttribute(OIDCConfigAttributes.USE_MTLS_HOK_TOKEN, val);
|
||||
}
|
||||
|
||||
public String getTlsClientAuthSubjectDn() {
|
||||
return getAttribute(X509ClientAuthenticator.ATTR_SUBJECT_DN);
|
||||
}
|
||||
|
||||
public void setTlsClientAuthSubjectDn(String tls_client_auth_subject_dn) {
|
||||
setAttribute(X509ClientAuthenticator.ATTR_SUBJECT_DN, tls_client_auth_subject_dn);
|
||||
}
|
||||
|
||||
public String getPkceCodeChallengeMethod() {
|
||||
return getAttribute(OIDCConfigAttributes.PKCE_CODE_CHALLENGE_METHOD);
|
||||
}
|
||||
|
|
|
@ -121,6 +121,10 @@ public class DescriptionConverter {
|
|||
else configWrapper.setUseMtlsHoKToken(false);
|
||||
}
|
||||
|
||||
if (clientOIDC.getTlsClientAuthSubjectDn() != null) {
|
||||
configWrapper.setTlsClientAuthSubjectDn(clientOIDC.getTlsClientAuthSubjectDn());
|
||||
}
|
||||
|
||||
if (clientOIDC.getIdTokenSignedResponseAlg() != null) {
|
||||
configWrapper.setIdTokenSignedResponseAlg(clientOIDC.getIdTokenSignedResponseAlg());
|
||||
}
|
||||
|
@ -215,6 +219,9 @@ public class DescriptionConverter {
|
|||
} else {
|
||||
response.setTlsClientCertificateBoundAccessTokens(Boolean.FALSE);
|
||||
}
|
||||
if (config.getTlsClientAuthSubjectDn() != null) {
|
||||
response.setTlsClientAuthSubjectDn(config.getTlsClientAuthSubjectDn());
|
||||
}
|
||||
if (config.getIdTokenSignedResponseAlg() != null) {
|
||||
response.setIdTokenSignedResponseAlg(config.getIdTokenSignedResponseAlg());
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.admin.client.resource.ClientsResource;
|
||||
import org.keycloak.authentication.authenticators.client.X509ClientAuthenticator;
|
||||
import org.keycloak.client.registration.Auth;
|
||||
import org.keycloak.client.registration.ClientRegistrationException;
|
||||
import org.keycloak.client.registration.HttpErrorException;
|
||||
|
@ -422,6 +423,47 @@ public class OIDCClientRegistrationTest extends AbstractClientRegistrationTest {
|
|||
clientsResource.get(samlClient.getId()).update(samlClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTlsClientAuthSubjectDn() throws Exception {
|
||||
OIDCClientRepresentation response = null;
|
||||
OIDCClientRepresentation updated = null;
|
||||
try {
|
||||
// create (no specification)
|
||||
OIDCClientRepresentation clientRep = createRep();
|
||||
clientRep.setTokenEndpointAuthMethod(OIDCLoginProtocol.TLS_CLIENT_AUTH);
|
||||
clientRep.setTlsClientAuthSubjectDn("Ein");
|
||||
|
||||
response = reg.oidc().create(clientRep);
|
||||
Assert.assertEquals(OIDCLoginProtocol.TLS_CLIENT_AUTH, response.getTokenEndpointAuthMethod());
|
||||
Assert.assertEquals("Ein", response.getTlsClientAuthSubjectDn());
|
||||
|
||||
// Test Keycloak representation
|
||||
ClientRepresentation kcClient = getClient(response.getClientId());
|
||||
OIDCAdvancedConfigWrapper config = OIDCAdvancedConfigWrapper.fromClientRepresentation(kcClient);
|
||||
Assert.assertEquals(X509ClientAuthenticator.PROVIDER_ID, kcClient.getClientAuthenticatorType());
|
||||
Assert.assertEquals("Ein", config.getTlsClientAuthSubjectDn());
|
||||
|
||||
// update
|
||||
reg.auth(Auth.token(response));
|
||||
response.setTlsClientAuthSubjectDn("(.*?)(?:$)");
|
||||
updated = reg.oidc().update(response);
|
||||
Assert.assertEquals(OIDCLoginProtocol.TLS_CLIENT_AUTH, updated.getTokenEndpointAuthMethod());
|
||||
Assert.assertEquals("(.*?)(?:$)", updated.getTlsClientAuthSubjectDn());
|
||||
|
||||
// Test Keycloak representation
|
||||
kcClient = getClient(updated.getClientId());
|
||||
config = OIDCAdvancedConfigWrapper.fromClientRepresentation(kcClient);
|
||||
Assert.assertEquals(X509ClientAuthenticator.PROVIDER_ID, kcClient.getClientAuthenticatorType());
|
||||
Assert.assertEquals("(.*?)(?:$)", config.getTlsClientAuthSubjectDn());
|
||||
} finally {
|
||||
// revert
|
||||
reg.auth(Auth.token(updated));
|
||||
updated.setTokenEndpointAuthMethod(null);
|
||||
updated.setTlsClientAuthSubjectDn(null);
|
||||
reg.oidc().update(updated);
|
||||
}
|
||||
}
|
||||
|
||||
private ClientRepresentation getKeycloakClient(String clientId) {
|
||||
return ApiUtil.findClientByClientId(adminClient.realms().realm(REALM_NAME), clientId).toRepresentation();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue