Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.RefreshToken;
import org.keycloak.representations.dpop.DPoP;
import org.keycloak.representations.idm.ClientPolicyExecutorConfigurationRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.services.clientpolicy.ClientPolicyContext;
Expand All @@ -37,6 +38,7 @@
import org.keycloak.services.clientpolicy.context.TokenRefreshContext;
import org.keycloak.services.clientpolicy.context.TokenRevokeContext;
import org.keycloak.services.clientpolicy.context.UserInfoRequestContext;
import org.keycloak.services.util.DPoPUtil;
import org.keycloak.services.util.MtlsHoKTokenUtil;

import com.fasterxml.jackson.annotation.JsonProperty;
Expand Down Expand Up @@ -91,9 +93,10 @@ public void executeOnEvent(ClientPolicyContext context) throws ClientPolicyExcep
case TOKEN_REQUEST:
case SERVICE_ACCOUNT_TOKEN_REQUEST:
case BACKCHANNEL_TOKEN_REQUEST:
DPoP dpop = session.getAttribute(DPoPUtil.DPOP_SESSION_ATTRIBUTE, DPoP.class);
AccessToken.Confirmation certConf = MtlsHoKTokenUtil.bindTokenWithClientCertificate(request, session);
if (certConf == null) {
throw new ClientPolicyException(OAuthErrorException.INVALID_REQUEST, "Client Certification missing for MTLS HoK Token Binding");
if (dpop == null && certConf == null) {
throw new ClientPolicyException(OAuthErrorException.INVALID_REQUEST, "Holder of Key Proof required (e.g. mTLS, DPoP)");
}
break;
case TOKEN_REFRESH:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2267,7 +2267,7 @@ public void testHolderOfKeyEnforceExecutor() throws Exception {
AccessTokenResponse tokenRes = oauth.ciba().doBackchannelAuthenticationTokenRequest(response.getAuthReqId());
assertThat(tokenRes.getStatusCode(), is(equalTo(400)));
assertThat(tokenRes.getError(), is(equalTo(OAuthErrorException.INVALID_GRANT)));
assertThat(tokenRes.getErrorDescription(), is(equalTo("Client Certification missing for MTLS HoK Token Binding")));
assertThat(tokenRes.getErrorDescription(), is(equalTo("Holder of Key Proof required (e.g. mTLS, DPoP)")));
events.expect(EventType.AUTHREQID_TO_TOKEN_ERROR).clearDetails().user((String)null).client(TEST_CLIENT_NAME).error(OAuthErrorException.INVALID_REQUEST).assertEvent();
oauth.httpClient().reset();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ public void testFAPIAdvancedLoginWithPrivateKeyJWT() throws Exception {
String signedJwt = createSignedRequestToken("foo", privateKey, publicKey, org.keycloak.crypto.Algorithm.PS256);
AccessTokenResponse tokenResponse = doAccessTokenRequestWithClientSignedJWT(code, signedJwt, DefaultHttpClient::new);
Assertions.assertEquals(OAuthErrorException.INVALID_GRANT,tokenResponse.getError());
Assertions.assertEquals("Client Certification missing for MTLS HoK Token Binding", tokenResponse.getErrorDescription());
Assertions.assertEquals("Holder of Key Proof required (e.g. mTLS, DPoP)", tokenResponse.getErrorDescription());

// Login with private-key-jwt client authentication and MTLS added to HttpClient. TokenRequest should be successful now
oauth.loginForm().requestUri(requestUri).open();
Expand Down
Loading