ID token mapping
This commit is contained in:
parent
51e2507f5d
commit
453ef808cc
3 changed files with 43 additions and 39 deletions
|
@ -339,7 +339,7 @@ public class OIDCLoginProtocolService {
|
|||
|
||||
TokenManager.attachClientSession(userSession, clientSession);
|
||||
|
||||
AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event)
|
||||
AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event, session, userSession, clientSession)
|
||||
.generateAccessToken(session, scope, client, user, userSession, clientSession)
|
||||
.generateRefreshToken()
|
||||
.generateIDToken()
|
||||
|
@ -506,9 +506,9 @@ public class OIDCLoginProtocolService {
|
|||
event.error(Errors.INVALID_TOKEN);
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
}
|
||||
AccessToken accessToken;
|
||||
AccessTokenResponse res;
|
||||
try {
|
||||
accessToken = tokenManager.refreshAccessToken(session, uriInfo, clientConnection, realm, client, refreshToken, event);
|
||||
res = tokenManager.refreshAccessToken(session, uriInfo, clientConnection, realm, client, refreshToken, event);
|
||||
} catch (OAuthErrorException e) {
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
error.put(OAuth2Constants.ERROR, e.getError());
|
||||
|
@ -517,10 +517,6 @@ public class OIDCLoginProtocolService {
|
|||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
}
|
||||
|
||||
AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event)
|
||||
.accessToken(accessToken)
|
||||
.generateIDToken()
|
||||
.generateRefreshToken().build();
|
||||
|
||||
event.success();
|
||||
|
||||
|
@ -680,7 +676,7 @@ public class OIDCLoginProtocolService {
|
|||
return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build();
|
||||
}
|
||||
|
||||
AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event)
|
||||
AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event, session, userSession, clientSession)
|
||||
.accessToken(token)
|
||||
.generateIDToken()
|
||||
.generateRefreshToken().build();
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.keycloak.models.UserSessionProvider;
|
|||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.ProtocolMapper;
|
||||
import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper;
|
||||
import org.keycloak.protocol.oidc.mappers.OIDCIDTokenMapper;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.AccessTokenResponse;
|
||||
import org.keycloak.representations.IDToken;
|
||||
|
@ -58,7 +59,7 @@ public class TokenManager {
|
|||
}
|
||||
}
|
||||
|
||||
public AccessToken refreshAccessToken(KeycloakSession session, UriInfo uriInfo, ClientConnection connection, RealmModel realm, ClientModel client, String encodedRefreshToken, EventBuilder event) throws OAuthErrorException {
|
||||
public AccessTokenResponse refreshAccessToken(KeycloakSession session, UriInfo uriInfo, ClientConnection connection, RealmModel realm, ClientModel client, String encodedRefreshToken, EventBuilder event) throws OAuthErrorException {
|
||||
RefreshToken refreshToken = verifyRefreshToken(realm, encodedRefreshToken);
|
||||
|
||||
event.user(refreshToken.getSubject()).session(refreshToken.getSessionState()).detail(Details.REFRESH_TOKEN_ID, refreshToken.getId());
|
||||
|
@ -105,11 +106,15 @@ public class TokenManager {
|
|||
AccessToken accessToken = initToken(realm, client, user, userSession, clientSession);
|
||||
accessToken.setRealmAccess(refreshToken.getRealmAccess());
|
||||
accessToken.setResourceAccess(refreshToken.getResourceAccess());
|
||||
accessToken = transformToken(session, accessToken, realm, client, user, userSession, clientSession);
|
||||
accessToken = transformAccessToken(session, accessToken, realm, client, user, userSession, clientSession);
|
||||
|
||||
userSession.setLastSessionRefresh(currentTime);
|
||||
|
||||
return accessToken;
|
||||
AccessTokenResponse res = responseBuilder(realm, client, event, session, userSession, clientSession)
|
||||
.accessToken(accessToken)
|
||||
.generateIDToken()
|
||||
.generateRefreshToken().build();
|
||||
return res;
|
||||
}
|
||||
|
||||
public RefreshToken verifyRefreshToken(RealmModel realm, String encodedRefreshToken) throws OAuthErrorException {
|
||||
|
@ -138,7 +143,7 @@ public class TokenManager {
|
|||
for (RoleModel role : requestedRoles) {
|
||||
addComposites(token, role);
|
||||
}
|
||||
token = transformToken(session, token, realm, client, user, userSession, clientSession);
|
||||
token = transformAccessToken(session, token, realm, client, user, userSession, clientSession);
|
||||
return token;
|
||||
}
|
||||
|
||||
|
@ -233,7 +238,7 @@ public class TokenManager {
|
|||
}
|
||||
}
|
||||
|
||||
public AccessToken transformToken(KeycloakSession session, AccessToken token, RealmModel realm, ClientModel client, UserModel user,
|
||||
public AccessToken transformAccessToken(KeycloakSession session, AccessToken token, RealmModel realm, ClientModel client, UserModel user,
|
||||
UserSessionModel userSession, ClientSessionModel clientSession) {
|
||||
Set<ProtocolMapperModel> mappings = client.getProtocolMappers();
|
||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||
|
@ -249,6 +254,21 @@ public class TokenManager {
|
|||
}
|
||||
return token;
|
||||
}
|
||||
public void transformIDToken(KeycloakSession session, IDToken token, RealmModel realm, ClientModel client, UserModel user,
|
||||
UserSessionModel userSession, ClientSessionModel clientSession) {
|
||||
Set<ProtocolMapperModel> mappings = client.getProtocolMappers();
|
||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||
for (ProtocolMapperModel mapping : mappings) {
|
||||
if (!mapping.getProtocol().equals(OIDCLoginProtocol.LOGIN_PROTOCOL)) continue;
|
||||
|
||||
ProtocolMapper mapper = (ProtocolMapper)sessionFactory.getProviderFactory(ProtocolMapper.class, mapping.getProtocolMapper());
|
||||
if (mapper == null || !(mapper instanceof OIDCIDTokenMapper)) continue;
|
||||
token = ((OIDCIDTokenMapper)mapper).transformIDToken(token, mapping, session, userSession, clientSession);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected AccessToken initToken(RealmModel realm, ClientModel client, UserModel user, UserSessionModel session, ClientSessionModel clientSession) {
|
||||
|
@ -308,22 +328,29 @@ public class TokenManager {
|
|||
return encodedToken;
|
||||
}
|
||||
|
||||
public AccessTokenResponseBuilder responseBuilder(RealmModel realm, ClientModel client, EventBuilder event) {
|
||||
return new AccessTokenResponseBuilder(realm, client, event);
|
||||
public AccessTokenResponseBuilder responseBuilder(RealmModel realm, ClientModel client, EventBuilder event, KeycloakSession session, UserSessionModel userSession, ClientSessionModel clientSession) {
|
||||
return new AccessTokenResponseBuilder(realm, client, event, session, userSession, clientSession);
|
||||
}
|
||||
|
||||
public class AccessTokenResponseBuilder {
|
||||
RealmModel realm;
|
||||
ClientModel client;
|
||||
EventBuilder event;
|
||||
KeycloakSession session;
|
||||
UserSessionModel userSession;
|
||||
ClientSessionModel clientSession;
|
||||
|
||||
AccessToken accessToken;
|
||||
RefreshToken refreshToken;
|
||||
IDToken idToken;
|
||||
EventBuilder event;
|
||||
|
||||
public AccessTokenResponseBuilder(RealmModel realm, ClientModel client, EventBuilder event) {
|
||||
public AccessTokenResponseBuilder(RealmModel realm, ClientModel client, EventBuilder event, KeycloakSession session, UserSessionModel userSession, ClientSessionModel clientSession) {
|
||||
this.realm = realm;
|
||||
this.client = client;
|
||||
this.event = event;
|
||||
this.session = session;
|
||||
this.userSession = userSession;
|
||||
this.clientSession = clientSession;
|
||||
}
|
||||
|
||||
public AccessTokenResponseBuilder accessToken(AccessToken accessToken) {
|
||||
|
@ -366,25 +393,7 @@ public class TokenManager {
|
|||
if (realm.getAccessTokenLifespan() > 0) {
|
||||
idToken.expiration(Time.currentTime() + realm.getAccessTokenLifespan());
|
||||
}
|
||||
idToken.getUserClaimSet().setPreferredUsername(accessToken.getUserClaimSet().getPreferredUsername());
|
||||
idToken.getUserClaimSet().setGivenName(accessToken.getUserClaimSet().getGivenName());
|
||||
idToken.getUserClaimSet().setMiddleName(accessToken.getUserClaimSet().getMiddleName());
|
||||
idToken.getUserClaimSet().setFamilyName(accessToken.getUserClaimSet().getFamilyName());
|
||||
idToken.getUserClaimSet().setName(accessToken.getUserClaimSet().getName());
|
||||
idToken.getUserClaimSet().setNickName(accessToken.getUserClaimSet().getNickName());
|
||||
idToken.getUserClaimSet().setGender(accessToken.getUserClaimSet().getGender());
|
||||
idToken.getUserClaimSet().setPicture(accessToken.getUserClaimSet().getPicture());
|
||||
idToken.getUserClaimSet().setProfile(accessToken.getUserClaimSet().getProfile());
|
||||
idToken.getUserClaimSet().setWebsite(accessToken.getUserClaimSet().getWebsite());
|
||||
idToken.getUserClaimSet().setBirthdate(accessToken.getUserClaimSet().getBirthdate());
|
||||
idToken.getUserClaimSet().setEmail(accessToken.getUserClaimSet().getEmail());
|
||||
idToken.getUserClaimSet().setEmailVerified(accessToken.getUserClaimSet().getEmailVerified());
|
||||
idToken.getUserClaimSet().setLocale(accessToken.getUserClaimSet().getLocale());
|
||||
idToken.getUserClaimSet().setAddress(accessToken.getUserClaimSet().getAddress());
|
||||
idToken.getUserClaimSet().setPhoneNumber(accessToken.getUserClaimSet().getPhoneNumber());
|
||||
idToken.getUserClaimSet().setPhoneNumberVerified(accessToken.getUserClaimSet().getPhoneNumberVerified());
|
||||
idToken.getUserClaimSet().setZoneinfo(accessToken.getUserClaimSet().getZoneinfo());
|
||||
idToken.setOtherClaims(accessToken.getOtherClaims());
|
||||
transformIDToken(session, idToken, realm, client, userSession.getUser(), userSession, clientSession);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.keycloak.models.RealmModel;
|
|||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.UserClaimSet;
|
||||
import org.keycloak.services.managers.AppAuthManager;
|
||||
import org.keycloak.services.managers.EventsManager;
|
||||
import org.keycloak.services.resources.Cors;
|
||||
|
@ -133,7 +132,7 @@ public class UserInfoService {
|
|||
ClientModel clientModel = realmModel.findClient(accessToken.getIssuedFor());
|
||||
UserModel userModel = userSession.getUser();
|
||||
AccessToken userInfo = new AccessToken();
|
||||
this.tokenManager.transformToken(session, userInfo, realmModel, clientModel, userModel, userSession, null);
|
||||
this.tokenManager.transformAccessToken(session, userInfo, realmModel, clientModel, userModel, userSession, null);
|
||||
|
||||
event
|
||||
.detail(Details.USERNAME, userModel.getUsername())
|
||||
|
|
Loading…
Reference in a new issue