[KEYCLOAK-18807] - Fixing claims in JARM responses
This commit is contained in:
parent
13a08362d4
commit
730d4e8ac9
3 changed files with 52 additions and 7 deletions
|
@ -24,6 +24,8 @@ public interface OAuth2Constants {
|
|||
|
||||
String CODE = "code";
|
||||
|
||||
String TOKEN = "token";
|
||||
|
||||
String CLIENT_ID = "client_id";
|
||||
|
||||
String CLIENT_SECRET = "client_secret";
|
||||
|
|
|
@ -17,14 +17,19 @@
|
|||
|
||||
package org.keycloak.protocol.oidc.utils;
|
||||
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.common.util.Encode;
|
||||
import org.keycloak.common.util.HtmlUtils;
|
||||
import org.keycloak.common.util.KeycloakUriBuilder;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakContext;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.representations.AuthorizationResponseToken;
|
||||
import org.keycloak.services.Urls;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
@ -183,10 +188,10 @@ public abstract class OIDCRedirectUriBuilder {
|
|||
// https://openid.net/specs/openid-financial-api-jarm-ID1.html
|
||||
private static class JWTRedirectUriBuilder extends OIDCRedirectUriBuilder {
|
||||
|
||||
private OIDCResponseMode responseMode;
|
||||
private AuthorizationResponseToken responseJWT;
|
||||
private KeycloakSession session;
|
||||
private AuthenticatedClientSessionModel clientSession;
|
||||
private final OIDCResponseMode responseMode;
|
||||
private final AuthorizationResponseToken responseJWT;
|
||||
private final KeycloakSession session;
|
||||
private final AuthenticatedClientSessionModel clientSession;
|
||||
|
||||
public JWTRedirectUriBuilder(KeycloakUriBuilder uriBuilder, OIDCResponseMode responseMode, KeycloakSession session, AuthenticatedClientSessionModel clientSession) {
|
||||
super(uriBuilder);
|
||||
|
@ -204,12 +209,23 @@ public abstract class OIDCRedirectUriBuilder {
|
|||
|
||||
@Override
|
||||
public Response build() {
|
||||
KeycloakContext context = session.getContext();
|
||||
ClientModel client = context.getClient();
|
||||
RealmModel realm = client.getRealm();
|
||||
|
||||
responseJWT.issuer(Urls.realmIssuer(context.getUri().getBaseUri(), realm.getName()));
|
||||
responseJWT.audience(client.getClientId());
|
||||
responseJWT.exp((long) (Time.currentTime() + realm.getAccessCodeLifespan()));
|
||||
|
||||
if(clientSession != null) {
|
||||
responseJWT.issuer(clientSession.getNote(OIDCLoginProtocol.ISSUER));
|
||||
responseJWT.audience(clientSession.getClient().getClientId());
|
||||
responseJWT.setOtherClaims("scope", clientSession.getNote(OIDCLoginProtocol.SCOPE_PARAM));
|
||||
responseJWT.exp((long) (Time.currentTime() + clientSession.getRealm().getAccessCodeLifespan()));
|
||||
String responseType = clientSession.getNote(OIDCLoginProtocol.RESPONSE_TYPE_PARAM);
|
||||
|
||||
if (OAuth2Constants.TOKEN.equals(responseType)) {
|
||||
responseJWT.setOtherClaims(OAuth2Constants.SCOPE, clientSession.getNote(OIDCLoginProtocol.SCOPE_PARAM));
|
||||
}
|
||||
}
|
||||
|
||||
switch (responseMode) {
|
||||
case QUERY_JWT:
|
||||
return buildQueryResponse();
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.testsuite.oidc;
|
|||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.OAuthErrorException;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.events.Errors;
|
||||
|
@ -38,6 +39,9 @@ import java.io.IOException;
|
|||
import java.net.URI;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class AuthorizationTokenResponseModeTest extends AbstractTestRealmKeycloakTest {
|
||||
|
@ -76,6 +80,8 @@ public class AuthorizationTokenResponseModeTest extends AbstractTestRealmKeycloa
|
|||
|
||||
assertEquals("test-app", responseToken.getAudience()[0]);
|
||||
Assert.assertNotNull(responseToken.getOtherClaims().get("code"));
|
||||
// should not return code when response_type not 'token'
|
||||
assertFalse(responseToken.getOtherClaims().containsKey(OAuth2Constants.SCOPE));
|
||||
assertEquals("OpenIdConnect.AuthenticationProperties=2302984sdlk", responseToken.getOtherClaims().get("state"));
|
||||
Assert.assertNull(responseToken.getOtherClaims().get("error"));
|
||||
|
||||
|
@ -212,6 +218,27 @@ public class AuthorizationTokenResponseModeTest extends AbstractTestRealmKeycloa
|
|||
events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().assertEvent();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrorObjectExpectedClaims() throws Exception {
|
||||
ClientManager.realm(adminClient.realm("test")).clientId("test-app").implicitFlow(true);
|
||||
oauth.responseMode("query.jwt");
|
||||
oauth.responseType("code id_token");
|
||||
oauth.stateParamHardcoded("OpenIdConnect.AuthenticationProperties=2302984sdlk");
|
||||
oauth.nonce("123456");
|
||||
UriBuilder b = UriBuilder.fromUri(oauth.getLoginFormUrl());
|
||||
driver.navigate().to(b.build().toURL());
|
||||
|
||||
OAuthClient.AuthorizationEndpointResponse errorResponse = new OAuthClient.AuthorizationEndpointResponse(oauth);
|
||||
AuthorizationResponseToken responseToken = oauth.verifyAuthorizationResponseToken(errorResponse.getResponse());
|
||||
|
||||
assertNotNull(responseToken.getIssuer());
|
||||
assertNotNull(responseToken.getExp());
|
||||
assertNotNull(responseToken.getAudience());
|
||||
assertNotEquals(0, responseToken.getAudience().length);
|
||||
assertTrue(responseToken.getOtherClaims().containsKey("error"));
|
||||
assertTrue(responseToken.getOtherClaims().containsKey("error_description"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue