use of org.keycloak.jose.jws.JWSHeader in project keycloak by keycloak.
the class LogoutTokenUtil method generateSignedLogoutToken.
public static String generateSignedLogoutToken(PrivateKey privateKey, String keyId, String issuer, String clientId, String userId, String sessionId, boolean revokeOfflineSessions) throws IOException {
JWSHeader jwsHeader = new JWSHeader(Algorithm.RS256, OAuth2Constants.JWT, ContentType.APPLICATION_JSON.toString(), keyId);
String logoutTokenHeaderEncoded = Base64Url.encode(JsonSerialization.writeValueAsBytes(jwsHeader));
LogoutToken logoutToken = new LogoutToken();
logoutToken.setSid(sessionId);
logoutToken.putEvents(TokenUtil.TOKEN_BACKCHANNEL_LOGOUT_EVENT, new HashMap<>());
logoutToken.putEvents(TokenUtil.TOKEN_BACKCHANNEL_LOGOUT_EVENT_REVOKE_OFFLINE_TOKENS, revokeOfflineSessions);
logoutToken.setSubject(userId);
logoutToken.issuer(issuer);
logoutToken.id(UUID.randomUUID().toString());
logoutToken.issuedNow();
logoutToken.audience(clientId);
String logoutTokenPayloadEncoded = Base64Url.encode(JsonSerialization.writeValueAsBytes(logoutToken));
try {
Signature signature = Signature.getInstance(JavaAlgorithm.RS256);
signature.initSign(privateKey);
String data = logoutTokenHeaderEncoded + "." + logoutTokenPayloadEncoded;
byte[] dataByteArray = data.getBytes();
signature.update(dataByteArray);
byte[] signatureByteArray = signature.sign();
return data + "." + Base64Url.encode(signatureByteArray);
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
return null;
}
}
use of org.keycloak.jose.jws.JWSHeader in project keycloak by keycloak.
the class AbstractOIDCResponseTypeTest method oidcFlow.
private void oidcFlow(String expectedAccessAlg, String expectedIdTokenAlg) throws Exception {
EventRepresentation loginEvent = loginUser("abcdef123456");
OAuthClient.AuthorizationEndpointResponse authzResponse = new OAuthClient.AuthorizationEndpointResponse(oauth, isFragment());
Assert.assertNotNull(authzResponse.getSessionState());
JWSHeader header = null;
String idToken = authzResponse.getIdToken();
String accessToken = authzResponse.getAccessToken();
if (idToken != null) {
header = new JWSInput(idToken).getHeader();
assertEquals(expectedIdTokenAlg, header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertNull(header.getContentType());
}
if (accessToken != null) {
header = new JWSInput(accessToken).getHeader();
assertEquals(expectedAccessAlg, header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertNull(header.getContentType());
}
List<IDToken> idTokens = testAuthzResponseAndRetrieveIDTokens(authzResponse, loginEvent);
for (IDToken idt : idTokens) {
Assert.assertEquals("abcdef123456", idt.getNonce());
Assert.assertEquals(authzResponse.getSessionState(), idt.getSessionState());
}
}
use of org.keycloak.jose.jws.JWSHeader in project keycloak by keycloak.
the class OfflineTokenTest method offlineTokenRequest.
private void offlineTokenRequest(String expectedRefreshAlg, String expectedAccessAlg, String expectedIdTokenAlg) throws Exception {
oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
oauth.clientId("offline-client");
OAuthClient.AccessTokenResponse tokenResponse = oauth.doClientCredentialsGrantAccessTokenRequest("secret1");
JWSHeader header = null;
String idToken = tokenResponse.getIdToken();
String accessToken = tokenResponse.getAccessToken();
String refreshToken = tokenResponse.getRefreshToken();
if (idToken != null) {
header = new JWSInput(idToken).getHeader();
assertEquals(expectedIdTokenAlg, header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertNull(header.getContentType());
}
if (accessToken != null) {
header = new JWSInput(accessToken).getHeader();
assertEquals(expectedAccessAlg, header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertNull(header.getContentType());
}
if (refreshToken != null) {
header = new JWSInput(refreshToken).getHeader();
assertEquals(expectedRefreshAlg, header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertNull(header.getContentType());
}
AccessToken token = oauth.verifyToken(tokenResponse.getAccessToken());
String offlineTokenString = tokenResponse.getRefreshToken();
RefreshToken offlineToken = oauth.parseRefreshToken(offlineTokenString);
events.expectClientLogin().client("offline-client").user(serviceAccountUserId).session(token.getSessionState()).detail(Details.TOKEN_ID, token.getId()).detail(Details.REFRESH_TOKEN_ID, offlineToken.getId()).detail(Details.REFRESH_TOKEN_TYPE, TokenUtil.TOKEN_TYPE_OFFLINE).detail(Details.USERNAME, ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "offline-client").assertEvent();
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
Assert.assertEquals(0, offlineToken.getExpiration());
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), serviceAccountUserId);
// Now retrieve another offline token and decode that previous offline token is still valid
tokenResponse = oauth.doClientCredentialsGrantAccessTokenRequest("secret1");
AccessToken token2 = oauth.verifyToken(tokenResponse.getAccessToken());
String offlineTokenString2 = tokenResponse.getRefreshToken();
RefreshToken offlineToken2 = oauth.parseRefreshToken(offlineTokenString2);
events.expectClientLogin().client("offline-client").user(serviceAccountUserId).session(token2.getSessionState()).detail(Details.TOKEN_ID, token2.getId()).detail(Details.REFRESH_TOKEN_ID, offlineToken2.getId()).detail(Details.REFRESH_TOKEN_TYPE, TokenUtil.TOKEN_TYPE_OFFLINE).detail(Details.USERNAME, ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "offline-client").assertEvent();
// Refresh with both offline tokens is fine
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), serviceAccountUserId);
testRefreshWithOfflineToken(token2, offlineToken2, offlineTokenString2, token2.getSessionState(), serviceAccountUserId);
}
use of org.keycloak.jose.jws.JWSHeader in project keycloak by keycloak.
the class ServiceAccountTest method clientCredentialsAuthSuccessWithRefreshToken.
// Testing of refresh token is for backwards compatibility. By default, there won't be refresh token for the client credentials grant
private void clientCredentialsAuthSuccessWithRefreshToken(String expectedRefreshAlg, String expectedAccessAlg) throws Exception {
oauth.clientId("service-account-cl-refresh-on");
OAuthClient.AccessTokenResponse response = oauth.doClientCredentialsGrantAccessTokenRequest("secret1");
assertEquals(200, response.getStatusCode());
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
JWSHeader header = new JWSInput(response.getAccessToken()).getHeader();
assertEquals(expectedAccessAlg, header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertNull(header.getContentType());
header = new JWSInput(response.getRefreshToken()).getHeader();
assertEquals(expectedRefreshAlg, header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertNull(header.getContentType());
events.expectClientLogin().client("service-account-cl-refresh-on").user(userId).session(accessToken.getSessionState()).detail(Details.TOKEN_ID, accessToken.getId()).detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()).detail(Details.USERNAME, userName).assertEvent();
assertEquals(accessToken.getSessionState(), refreshToken.getSessionState());
System.out.println("Access token other claims: " + accessToken.getOtherClaims());
Assert.assertEquals("service-account-cl-refresh-on", accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ID));
Assert.assertTrue(accessToken.getOtherClaims().containsKey(ServiceAccountConstants.CLIENT_ADDRESS));
Assert.assertTrue(accessToken.getOtherClaims().containsKey(ServiceAccountConstants.CLIENT_HOST));
OAuthClient.AccessTokenResponse refreshedResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret1");
AccessToken refreshedAccessToken = oauth.verifyToken(refreshedResponse.getAccessToken());
RefreshToken refreshedRefreshToken = oauth.parseRefreshToken(refreshedResponse.getRefreshToken());
assertEquals(accessToken.getSessionState(), refreshedAccessToken.getSessionState());
assertEquals(accessToken.getSessionState(), refreshedRefreshToken.getSessionState());
events.expectRefresh(refreshToken.getId(), refreshToken.getSessionState()).user(userId).client("service-account-cl-refresh-on").assertEvent();
}
use of org.keycloak.jose.jws.JWSHeader in project keycloak by keycloak.
the class ResourceOwnerPasswordCredentialsGrantTest method grantRequest.
private void grantRequest(String expectedRefreshAlg, String expectedAccessAlg) throws Exception {
String clientId = "resource-owner";
String login = "direct-login";
oauth.clientId(clientId);
OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("secret", login, "password", null);
assertEquals(200, response.getStatusCode());
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
JWSHeader header = new JWSInput(response.getAccessToken()).getHeader();
assertEquals(expectedAccessAlg, header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertNull(header.getContentType());
header = new JWSInput(response.getRefreshToken()).getHeader();
assertEquals(expectedRefreshAlg, header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertNull(header.getContentType());
events.expectLogin().client(clientId).user(userId).session(accessToken.getSessionState()).detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD).detail(Details.TOKEN_ID, accessToken.getId()).detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()).detail(Details.USERNAME, login).removeDetail(Details.CODE_ID).removeDetail(Details.REDIRECT_URI).removeDetail(Details.CONSENT).assertEvent();
Assert.assertTrue(login.equals(accessToken.getPreferredUsername()) || login.equals(accessToken.getEmail()));
assertEquals(accessToken.getSessionState(), refreshToken.getSessionState());
OAuthClient.AccessTokenResponse refreshedResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret");
AccessToken refreshedAccessToken = oauth.verifyToken(refreshedResponse.getAccessToken());
RefreshToken refreshedRefreshToken = oauth.parseRefreshToken(refreshedResponse.getRefreshToken());
assertEquals(accessToken.getSessionState(), refreshedAccessToken.getSessionState());
assertEquals(accessToken.getSessionState(), refreshedRefreshToken.getSessionState());
events.expectRefresh(refreshToken.getId(), refreshToken.getSessionState()).user(userId).client(clientId).assertEvent();
}
Aggregations