Add the nonce attribute when the client session context is recreated (#33422)
Closes #33355 Signed-off-by: rmartinc <rmartinc@redhat.com> Co-authored-by: Tomas Kralik <tomas.kralik@pbktechnology.cz>
This commit is contained in:
parent
ef48a3a360
commit
6e471a8477
2 changed files with 29 additions and 9 deletions
|
@ -99,7 +99,6 @@ import org.keycloak.util.TokenUtil;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
@ -1180,8 +1179,12 @@ public class TokenManager {
|
|||
String scope = oldRefreshToken.getScope();
|
||||
Object reuseId = oldRefreshToken.getOtherClaims().get(Constants.REUSE_ID);
|
||||
boolean offlineTokenRequested = Arrays.asList(scope.split(" ")).contains(OAuth2Constants.OFFLINE_ACCESS) ;
|
||||
if (offlineTokenRequested)
|
||||
if (offlineTokenRequested) {
|
||||
clientSessionCtx = DefaultClientSessionContext.fromClientSessionAndScopeParameter(clientSession, scope, session);
|
||||
if (oldRefreshToken.getNonce() != null) {
|
||||
clientSessionCtx.setAttribute(OIDCLoginProtocol.NONCE_PARAM, oldRefreshToken.getNonce());
|
||||
}
|
||||
}
|
||||
generateRefreshToken(offlineTokenRequested);
|
||||
if (realm.isRevokeRefreshToken()) {
|
||||
refreshToken.getOtherClaims().put(Constants.REUSE_ID, reuseId);
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.keycloak.testsuite.AssertEvents;
|
|||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.updaters.ClientAttributeUpdater;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.keycloak.util.TokenUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -62,7 +63,7 @@ public class NonceBackwardsCompatibleMapperTest extends AbstractTestRealmKeycloa
|
|||
|
||||
@Test
|
||||
public void testNonceWithoutMapper() throws JsonProcessingException {
|
||||
testNonce(false);
|
||||
testNonce(false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -70,7 +71,18 @@ public class NonceBackwardsCompatibleMapperTest extends AbstractTestRealmKeycloa
|
|||
ClientResource testApp = ApiUtil.findClientByClientId(testRealm(), "test-app");
|
||||
String mapperId = createNonceMapper(testApp);
|
||||
try {
|
||||
testNonce(true);
|
||||
testNonce(true, false);
|
||||
} finally {
|
||||
testApp.getProtocolMappers().delete(mapperId);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOfflineSessionNonceWithMapper() throws JsonProcessingException {
|
||||
ClientResource testApp = ApiUtil.findClientByClientId(testRealm(), "test-app");
|
||||
String mapperId = createNonceMapper(testApp);
|
||||
try {
|
||||
testNonce(true, true);
|
||||
} finally {
|
||||
testApp.getProtocolMappers().delete(mapperId);
|
||||
}
|
||||
|
@ -142,9 +154,12 @@ public class NonceBackwardsCompatibleMapperTest extends AbstractTestRealmKeycloa
|
|||
testIntrospection(idTokenString, nonce, true);
|
||||
}
|
||||
|
||||
private void testNonce(boolean mapper) throws JsonProcessingException {
|
||||
private void testNonce(boolean mapper, boolean offlineSession) throws JsonProcessingException {
|
||||
String nonce = KeycloakModelUtils.generateId();
|
||||
oauth.nonce(nonce);
|
||||
if (offlineSession) {
|
||||
oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
|
||||
}
|
||||
oauth.doLogin("test-user@localhost", "password");
|
||||
EventRepresentation loginEvent = events.expectLogin().assertEvent();
|
||||
|
||||
|
@ -158,12 +173,14 @@ public class NonceBackwardsCompatibleMapperTest extends AbstractTestRealmKeycloa
|
|||
RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
|
||||
checkNonce(nonce, refreshToken.getNonce(), mapper);
|
||||
|
||||
EventRepresentation tokenEvent = events.expectCodeToToken(loginEvent.getDetails().get(Details.CODE_ID),
|
||||
loginEvent.getSessionId()).assertEvent();
|
||||
EventRepresentation tokenEvent = events.expectCodeToToken(loginEvent.getDetails().get(Details.CODE_ID), loginEvent.getSessionId())
|
||||
.detail(Details.REFRESH_TOKEN_TYPE, offlineSession? TokenUtil.TOKEN_TYPE_OFFLINE : TokenUtil.TOKEN_TYPE_REFRESH)
|
||||
.assertEvent();
|
||||
|
||||
response = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
|
||||
events.expectRefresh(tokenEvent.getDetails().get(Details.REFRESH_TOKEN_ID),
|
||||
loginEvent.getSessionId()).assertEvent();
|
||||
events.expectRefresh(tokenEvent.getDetails().get(Details.REFRESH_TOKEN_ID), loginEvent.getSessionId())
|
||||
.detail(Details.REFRESH_TOKEN_TYPE, offlineSession? TokenUtil.TOKEN_TYPE_OFFLINE : TokenUtil.TOKEN_TYPE_REFRESH)
|
||||
.assertEvent();
|
||||
|
||||
token = oauth.verifyToken(response.getAccessToken());
|
||||
checkNonce(nonce, token.getNonce(), mapper);
|
||||
|
|
Loading…
Reference in a new issue