updates to method contracts and code impl to be more specific about providerAlias (#24070)

closes #24072
This commit is contained in:
Andrew 2023-10-18 02:33:06 -04:00 committed by GitHub
parent e91a0afca2
commit 77c3e7190c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 113 additions and 113 deletions

View file

@ -61,8 +61,8 @@ public class LinkedAccountRepresentation implements Comparable<LinkedAccountRepr
return providerAlias; return providerAlias;
} }
public void setProviderAlias(String providerId) { public void setProviderAlias(String providerAlias) {
this.providerAlias = providerId; this.providerAlias = providerAlias;
} }
public String getProviderName() { public String getProviderName() {

View file

@ -27,12 +27,12 @@ public class FederatedIdentityModel {
private final String identityProvider; private final String identityProvider;
private final String userName; private final String userName;
public FederatedIdentityModel(String identityProvider, String userId, String userName) { public FederatedIdentityModel(String providerAlias, String userId, String userName) {
this(identityProvider, userId, userName, null); this(providerAlias, userId, userName, null);
} }
public FederatedIdentityModel(String providerId, String userId, String userName, String token) { public FederatedIdentityModel(String providerAlias, String userId, String userName, String token) {
this.identityProvider = providerId; this.identityProvider = providerAlias;
this.userId = userId; this.userId = userId;
this.userName = userName; this.userName = userName;
this.token = token; this.token = token;

View file

@ -44,13 +44,13 @@ public class Urls {
return realmBase(baseUri).path(RealmsResource.class, "getAccountService"); return realmBase(baseUri).path(RealmsResource.class, "getAccountService");
} }
public static URI identityProviderAuthnResponse(URI baseUri, String providerId, String realmName) { public static URI identityProviderAuthnResponse(URI baseUri, String providerAlias, String realmName) {
return realmBase(baseUri).path(RealmsResource.class, "getBrokerService") return realmBase(baseUri).path(RealmsResource.class, "getBrokerService")
.path(IdentityBrokerService.class, "getEndpoint") .path(IdentityBrokerService.class, "getEndpoint")
.build(realmName, providerId); .build(realmName, providerAlias);
} }
public static URI identityProviderAuthnRequest(URI baseUri, String providerId, String realmName, String accessCode, String clientId, String tabId) { public static URI identityProviderAuthnRequest(URI baseUri, String providerAlias, String realmName, String accessCode, String clientId, String tabId) {
UriBuilder uriBuilder = realmBase(baseUri).path(RealmsResource.class, "getBrokerService") UriBuilder uriBuilder = realmBase(baseUri).path(RealmsResource.class, "getBrokerService")
.path(IdentityBrokerService.class, "performLogin"); .path(IdentityBrokerService.class, "performLogin");
@ -64,25 +64,25 @@ public class Urls {
uriBuilder.replaceQueryParam(Constants.TAB_ID, tabId); uriBuilder.replaceQueryParam(Constants.TAB_ID, tabId);
} }
return uriBuilder.build(realmName, providerId); return uriBuilder.build(realmName, providerAlias);
} }
public static URI identityProviderLinkRequest(URI baseUri, String providerId, String realmName) { public static URI identityProviderLinkRequest(URI baseUri, String providerAlias, String realmName) {
UriBuilder uriBuilder = realmBase(baseUri).path(RealmsResource.class, "getBrokerService") UriBuilder uriBuilder = realmBase(baseUri).path(RealmsResource.class, "getBrokerService")
.replaceQuery(null) .replaceQuery(null)
.path(IdentityBrokerService.class, "clientInitiatedAccountLinking"); .path(IdentityBrokerService.class, "clientInitiatedAccountLinking");
return uriBuilder.build(realmName, providerId); return uriBuilder.build(realmName, providerAlias);
} }
public static URI identityProviderRetrieveToken(URI baseUri, String providerId, String realmName) { public static URI identityProviderRetrieveToken(URI baseUri, String providerAlias, String realmName) {
return realmBase(baseUri).path(RealmsResource.class, "getBrokerService") return realmBase(baseUri).path(RealmsResource.class, "getBrokerService")
.path(IdentityBrokerService.class, "retrieveToken") .path(IdentityBrokerService.class, "retrieveToken")
.build(realmName, providerId); .build(realmName, providerAlias);
} }
public static URI identityProviderAuthnRequest(URI baseURI, String providerId, String realmName) { public static URI identityProviderAuthnRequest(URI baseURI, String providerAlias, String realmName) {
return identityProviderAuthnRequest(baseURI, providerId, realmName, null, null, null); return identityProviderAuthnRequest(baseURI, providerAlias, realmName, null, null, null);
} }
public static URI identityProviderAfterFirstBrokerLogin(URI baseUri, String realmName, String accessCode, String clientId, String tabId) { public static URI identityProviderAfterFirstBrokerLogin(URI baseUri, String realmName, String accessCode, String clientId, String tabId) {

View file

@ -191,20 +191,20 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
/** /**
* Closes off CORS preflight requests for account linking * Closes off CORS preflight requests for account linking
* *
* @param providerId * @param providerAlias
* @return * @return
*/ */
@OPTIONS @OPTIONS
@Path("/{provider_id}/link") @Path("/{provider_alias}/link")
public Response clientIntiatedAccountLinkingPreflight(@PathParam("provider_id") String providerId) { public Response clientIntiatedAccountLinkingPreflight(@PathParam("provider_alias") String providerAlias) {
return Response.status(403).build(); // don't allow preflight return Response.status(403).build(); // don't allow preflight
} }
@GET @GET
@NoCache @NoCache
@Path("/{provider_id}/link") @Path("/{provider_alias}/link")
public Response clientInitiatedAccountLinking(@PathParam("provider_id") String providerId, public Response clientInitiatedAccountLinking(@PathParam("provider_alias") String providerAlias,
@QueryParam("redirect_uri") String redirectUri, @QueryParam("redirect_uri") String redirectUri,
@QueryParam("client_id") String clientId, @QueryParam("client_id") String clientId,
@QueryParam("nonce") String nonce, @QueryParam("nonce") String nonce,
@ -253,7 +253,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
throw new ErrorPageException(session, Response.Status.INTERNAL_SERVER_ERROR, Messages.UNEXPECTED_ERROR_HANDLING_REQUEST); throw new ErrorPageException(session, Response.Status.INTERNAL_SERVER_ERROR, Messages.UNEXPECTED_ERROR_HANDLING_REQUEST);
} }
String input = nonce + cookieResult.getSession().getId() + clientId + providerId; String input = nonce + cookieResult.getSession().getId() + clientId + providerAlias;
byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8)); byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
if (MessageDigest.isEqual(decoded, check)) { if (MessageDigest.isEqual(decoded, check)) {
clientSession = cs; clientSession = cs;
@ -266,7 +266,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
throw new ErrorPageException(session, Response.Status.BAD_REQUEST, Messages.INVALID_REQUEST); throw new ErrorPageException(session, Response.Status.BAD_REQUEST, Messages.INVALID_REQUEST);
} }
event.detail(Details.IDENTITY_PROVIDER, providerId); event.detail(Details.IDENTITY_PROVIDER, providerAlias);
ClientModel accountService = this.realmModel.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); ClientModel accountService = this.realmModel.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
if (!accountService.getId().equals(client.getId())) { if (!accountService.getId().equals(client.getId())) {
@ -289,7 +289,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
} }
IdentityProviderModel identityProviderModel = realmModel.getIdentityProviderByAlias(providerId); IdentityProviderModel identityProviderModel = realmModel.getIdentityProviderByAlias(providerAlias);
if (identityProviderModel == null) { if (identityProviderModel == null) {
event.error(Errors.UNKNOWN_IDENTITY_PROVIDER); event.error(Errors.UNKNOWN_IDENTITY_PROVIDER);
UriBuilder builder = UriBuilder.fromUri(redirectUri) UriBuilder builder = UriBuilder.fromUri(redirectUri)
@ -320,14 +320,14 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
authSession.setProtocol(client.getProtocol()); authSession.setProtocol(client.getProtocol());
authSession.setRedirectUri(redirectUri); authSession.setRedirectUri(redirectUri);
authSession.setClientNote(OIDCLoginProtocol.STATE_PARAM, UUID.randomUUID().toString()); authSession.setClientNote(OIDCLoginProtocol.STATE_PARAM, UUID.randomUUID().toString());
authSession.setAuthNote(LINKING_IDENTITY_PROVIDER, cookieResult.getSession().getId() + clientId + providerId); authSession.setAuthNote(LINKING_IDENTITY_PROVIDER, cookieResult.getSession().getId() + clientId + providerAlias);
event.detail(Details.CODE_ID, userSession.getId()); event.detail(Details.CODE_ID, userSession.getId());
event.success(); event.success();
try { try {
IdentityProvider identityProvider = getIdentityProvider(session, realmModel, providerId); IdentityProvider<?> identityProvider = getIdentityProvider(session, realmModel, providerAlias);
Response response = identityProvider.performLogin(createAuthenticationRequest(providerId, clientSessionCode)); Response response = identityProvider.performLogin(createAuthenticationRequest(providerAlias, clientSessionCode));
if (response != null) { if (response != null) {
if (isDebugEnabled()) { if (isDebugEnabled()) {
@ -336,9 +336,9 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
return response; return response;
} }
} catch (IdentityBrokerException e) { } catch (IdentityBrokerException e) {
return redirectToErrorPage(authSession, Response.Status.INTERNAL_SERVER_ERROR, Messages.COULD_NOT_SEND_AUTHENTICATION_REQUEST, e, providerId); return redirectToErrorPage(authSession, Response.Status.INTERNAL_SERVER_ERROR, Messages.COULD_NOT_SEND_AUTHENTICATION_REQUEST, e, providerAlias);
} catch (Exception e) { } catch (Exception e) {
return redirectToErrorPage(authSession, Response.Status.INTERNAL_SERVER_ERROR, Messages.UNEXPECTED_ERROR_HANDLING_REQUEST, e, providerId); return redirectToErrorPage(authSession, Response.Status.INTERNAL_SERVER_ERROR, Messages.UNEXPECTED_ERROR_HANDLING_REQUEST, e, providerAlias);
} }
return redirectToErrorPage(authSession, Response.Status.INTERNAL_SERVER_ERROR, Messages.COULD_NOT_PROCEED_WITH_AUTHENTICATION_REQUEST); return redirectToErrorPage(authSession, Response.Status.INTERNAL_SERVER_ERROR, Messages.COULD_NOT_PROCEED_WITH_AUTHENTICATION_REQUEST);
@ -347,27 +347,27 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
@POST @POST
@Path("/{provider_id}/login") @Path("/{provider_alias}/login")
public Response performPostLogin(@PathParam("provider_id") String providerId, public Response performPostLogin(@PathParam("provider_alias") String providerAlias,
@QueryParam(LoginActionsService.SESSION_CODE) String code, @QueryParam(LoginActionsService.SESSION_CODE) String code,
@QueryParam("client_id") String clientId, @QueryParam("client_id") String clientId,
@QueryParam(Constants.TAB_ID) String tabId, @QueryParam(Constants.TAB_ID) String tabId,
@QueryParam(OIDCLoginProtocol.LOGIN_HINT_PARAM) String loginHint) { @QueryParam(OIDCLoginProtocol.LOGIN_HINT_PARAM) String loginHint) {
return performLogin(providerId, code, clientId, tabId, loginHint); return performLogin(providerAlias, code, clientId, tabId, loginHint);
} }
@GET @GET
@NoCache @NoCache
@Path("/{provider_id}/login") @Path("/{provider_alias}/login")
public Response performLogin(@PathParam("provider_id") String providerId, public Response performLogin(@PathParam("provider_alias") String providerAlias,
@QueryParam(LoginActionsService.SESSION_CODE) String code, @QueryParam(LoginActionsService.SESSION_CODE) String code,
@QueryParam("client_id") String clientId, @QueryParam("client_id") String clientId,
@QueryParam(Constants.TAB_ID) String tabId, @QueryParam(Constants.TAB_ID) String tabId,
@QueryParam(OIDCLoginProtocol.LOGIN_HINT_PARAM) String loginHint) { @QueryParam(OIDCLoginProtocol.LOGIN_HINT_PARAM) String loginHint) {
this.event.detail(Details.IDENTITY_PROVIDER, providerId); this.event.detail(Details.IDENTITY_PROVIDER, providerAlias);
if (isDebugEnabled()) { if (isDebugEnabled()) {
logger.debugf("Sending authentication request to identity provider [%s].", providerId); logger.debugf("Sending authentication request to identity provider [%s].", providerAlias);
} }
try { try {
@ -375,22 +375,22 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
ClientSessionCode<AuthenticationSessionModel> clientSessionCode = new ClientSessionCode<>(session, realmModel, authSession); ClientSessionCode<AuthenticationSessionModel> clientSessionCode = new ClientSessionCode<>(session, realmModel, authSession);
clientSessionCode.setAction(AuthenticationSessionModel.Action.AUTHENTICATE.name()); clientSessionCode.setAction(AuthenticationSessionModel.Action.AUTHENTICATE.name());
IdentityProviderModel identityProviderModel = realmModel.getIdentityProviderByAlias(providerId); IdentityProviderModel identityProviderModel = realmModel.getIdentityProviderByAlias(providerAlias);
if (identityProviderModel == null) { if (identityProviderModel == null) {
throw new IdentityBrokerException("Identity Provider [" + providerId + "] not found."); throw new IdentityBrokerException("Identity Provider [" + providerAlias + "] not found.");
} }
if (identityProviderModel.isLinkOnly()) { if (identityProviderModel.isLinkOnly()) {
throw new IdentityBrokerException("Identity Provider [" + providerId + "] is not allowed to perform a login."); throw new IdentityBrokerException("Identity Provider [" + providerAlias + "] is not allowed to perform a login.");
} }
if (clientSessionCode != null && clientSessionCode.getClientSession() != null && loginHint != null) { if (clientSessionCode != null && clientSessionCode.getClientSession() != null && loginHint != null) {
clientSessionCode.getClientSession().setClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM, loginHint); clientSessionCode.getClientSession().setClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM, loginHint);
} }
IdentityProviderFactory providerFactory = getIdentityProviderFactory(session, identityProviderModel); IdentityProviderFactory<?> providerFactory = getIdentityProviderFactory(session, identityProviderModel);
IdentityProvider identityProvider = providerFactory.create(session, identityProviderModel); IdentityProvider<?> identityProvider = providerFactory.create(session, identityProviderModel);
Response response = identityProvider.performLogin(createAuthenticationRequest(providerId, clientSessionCode)); Response response = identityProvider.performLogin(createAuthenticationRequest(providerAlias, clientSessionCode));
if (response != null) { if (response != null) {
if (isDebugEnabled()) { if (isDebugEnabled()) {
@ -399,20 +399,20 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
return response; return response;
} }
} catch (IdentityBrokerException e) { } catch (IdentityBrokerException e) {
return redirectToErrorPage(Response.Status.BAD_GATEWAY, Messages.COULD_NOT_SEND_AUTHENTICATION_REQUEST, e, providerId); return redirectToErrorPage(Response.Status.BAD_GATEWAY, Messages.COULD_NOT_SEND_AUTHENTICATION_REQUEST, e, providerAlias);
} catch (Exception e) { } catch (Exception e) {
return redirectToErrorPage(Response.Status.INTERNAL_SERVER_ERROR, Messages.UNEXPECTED_ERROR_HANDLING_REQUEST, e, providerId); return redirectToErrorPage(Response.Status.INTERNAL_SERVER_ERROR, Messages.UNEXPECTED_ERROR_HANDLING_REQUEST, e, providerAlias);
} }
return redirectToErrorPage(Response.Status.INTERNAL_SERVER_ERROR, Messages.COULD_NOT_PROCEED_WITH_AUTHENTICATION_REQUEST); return redirectToErrorPage(Response.Status.INTERNAL_SERVER_ERROR, Messages.COULD_NOT_PROCEED_WITH_AUTHENTICATION_REQUEST);
} }
@Path("{provider_id}/endpoint") @Path("{provider_alias}/endpoint")
public Object getEndpoint(@PathParam("provider_id") String providerId) { public Object getEndpoint(@PathParam("provider_alias") String providerAlias) {
IdentityProvider identityProvider; IdentityProvider identityProvider;
try { try {
identityProvider = getIdentityProvider(session, realmModel, providerId); identityProvider = getIdentityProvider(session, realmModel, providerAlias);
} catch (IdentityBrokerException e) { } catch (IdentityBrokerException e) {
throw new NotFoundException(e.getMessage()); throw new NotFoundException(e.getMessage());
} }
@ -420,7 +420,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
return identityProvider.callback(realmModel, this, event); return identityProvider.callback(realmModel, this, event);
} }
@Path("{provider_id}/token") @Path("{provider_alias}/token")
@OPTIONS @OPTIONS
public Response retrieveTokenPreflight() { public Response retrieveTokenPreflight() {
return Cors.add(this.request, Response.ok()).auth().preflight().build(); return Cors.add(this.request, Response.ok()).auth().preflight().build();
@ -428,9 +428,9 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
@GET @GET
@NoCache @NoCache
@Path("{provider_id}/token") @Path("{provider_alias}/token")
public Response retrieveToken(@PathParam("provider_id") String providerId) { public Response retrieveToken(@PathParam("provider_alias") String providerAlias) {
return getToken(providerId, false); return getToken(providerAlias, false);
} }
private boolean canReadBrokerToken(AccessToken token) { private boolean canReadBrokerToken(AccessToken token) {
@ -439,7 +439,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
return brokerRoles != null && brokerRoles.isUserInRole(Constants.READ_TOKEN_ROLE); return brokerRoles != null && brokerRoles.isUserInRole(Constants.READ_TOKEN_ROLE);
} }
private Response getToken(String providerId, boolean forceRetrieval) { private Response getToken(String providerAlias, boolean forceRetrieval) {
this.event.event(EventType.IDENTITY_PROVIDER_RETRIEVE_TOKEN); this.event.event(EventType.IDENTITY_PROVIDER_RETRIEVE_TOKEN);
try { try {
@ -461,22 +461,22 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
} }
if (!canReadBrokerToken(token)) { if (!canReadBrokerToken(token)) {
return corsResponse(forbidden("Client [" + clientModel.getClientId() + "] not authorized to retrieve tokens from identity provider [" + providerId + "]."), clientModel); return corsResponse(forbidden("Client [" + clientModel.getClientId() + "] not authorized to retrieve tokens from identity provider [" + providerAlias + "]."), clientModel);
} }
IdentityProvider identityProvider = getIdentityProvider(session, realmModel, providerId); IdentityProvider identityProvider = getIdentityProvider(session, realmModel, providerAlias);
IdentityProviderModel identityProviderConfig = getIdentityProviderConfig(providerId); IdentityProviderModel identityProviderConfig = getIdentityProviderConfig(providerAlias);
if (identityProviderConfig.isStoreToken()) { if (identityProviderConfig.isStoreToken()) {
FederatedIdentityModel identity = this.session.users().getFederatedIdentity(this.realmModel, authResult.getUser(), providerId); FederatedIdentityModel identity = this.session.users().getFederatedIdentity(this.realmModel, authResult.getUser(), providerAlias);
if (identity == null) { if (identity == null) {
return corsResponse(badRequest("User [" + authResult.getUser().getId() + "] is not associated with identity provider [" + providerId + "]."), clientModel); return corsResponse(badRequest("User [" + authResult.getUser().getId() + "] is not associated with identity provider [" + providerAlias + "]."), clientModel);
} }
if (identity.getToken() == null) { if (identity.getToken() == null) {
return corsResponse(notFound("No token stored for user [" + authResult.getUser().getId() + "] with associated identity provider [" + providerId + "]."), clientModel); return corsResponse(notFound("No token stored for user [" + authResult.getUser().getId() + "] with associated identity provider [" + providerAlias + "]."), clientModel);
} }
this.event.success(); this.event.success();
@ -484,14 +484,14 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
return corsResponse(identityProvider.retrieveToken(session, identity), clientModel); return corsResponse(identityProvider.retrieveToken(session, identity), clientModel);
} }
return corsResponse(badRequest("Identity Provider [" + providerId + "] does not support this operation."), clientModel); return corsResponse(badRequest("Identity Provider [" + providerAlias + "] does not support this operation."), clientModel);
} }
return badRequest("Invalid token."); return badRequest("Invalid token.");
} catch (IdentityBrokerException e) { } catch (IdentityBrokerException e) {
return redirectToErrorPage(Response.Status.BAD_GATEWAY, Messages.COULD_NOT_OBTAIN_TOKEN, e, providerId); return redirectToErrorPage(Response.Status.BAD_GATEWAY, Messages.COULD_NOT_OBTAIN_TOKEN, e, providerAlias);
} catch (Exception e) { } catch (Exception e) {
return redirectToErrorPage(Response.Status.BAD_GATEWAY, Messages.UNEXPECTED_ERROR_RETRIEVING_TOKEN, e, providerId); return redirectToErrorPage(Response.Status.BAD_GATEWAY, Messages.UNEXPECTED_ERROR_RETRIEVING_TOKEN, e, providerAlias);
} }
} }
@ -499,10 +499,10 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
IdentityProviderModel identityProviderConfig = context.getIdpConfig(); IdentityProviderModel identityProviderConfig = context.getIdpConfig();
AuthenticationSessionModel authenticationSession = context.getAuthenticationSession(); AuthenticationSessionModel authenticationSession = context.getAuthenticationSession();
String providerId = identityProviderConfig.getAlias(); String providerAlias = identityProviderConfig.getAlias();
if (!identityProviderConfig.isStoreToken()) { if (!identityProviderConfig.isStoreToken()) {
if (isDebugEnabled()) { if (isDebugEnabled()) {
logger.debugf("Token will not be stored for identity provider [%s].", providerId); logger.debugf("Token will not be stored for identity provider [%s].", providerAlias);
} }
context.setToken(null); context.setToken(null);
} }
@ -524,12 +524,12 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
target.preprocessFederatedIdentity(session, realmModel, mapper, context); target.preprocessFederatedIdentity(session, realmModel, mapper, context);
}); });
FederatedIdentityModel federatedIdentityModel = new FederatedIdentityModel(providerId, context.getId(), FederatedIdentityModel federatedIdentityModel = new FederatedIdentityModel(providerAlias, context.getId(),
context.getUsername(), context.getToken()); context.getUsername(), context.getToken());
this.event.event(EventType.IDENTITY_PROVIDER_LOGIN) this.event.event(EventType.IDENTITY_PROVIDER_LOGIN)
.detail(Details.REDIRECT_URI, authenticationSession.getRedirectUri()) .detail(Details.REDIRECT_URI, authenticationSession.getRedirectUri())
.detail(Details.IDENTITY_PROVIDER, providerId) .detail(Details.IDENTITY_PROVIDER, providerAlias)
.detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername()); .detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername());
UserModel federatedUser = this.session.users().getUserByFederatedIdentity(this.realmModel, federatedIdentityModel); UserModel federatedUser = this.session.users().getUserByFederatedIdentity(this.realmModel, federatedIdentityModel);
@ -543,13 +543,13 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
// Check if federatedUser is already authenticated (this means linking social into existing federatedUser account) // Check if federatedUser is already authenticated (this means linking social into existing federatedUser account)
UserSessionModel userSession = new AuthenticationSessionManager(session).getUserSession(authenticationSession); UserSessionModel userSession = new AuthenticationSessionManager(session).getUserSession(authenticationSession);
if (shouldPerformAccountLinking(authenticationSession, userSession, providerId)) { if (shouldPerformAccountLinking(authenticationSession, userSession, providerAlias)) {
return performAccountLinking(authenticationSession, userSession, context, federatedIdentityModel, federatedUser); return performAccountLinking(authenticationSession, userSession, context, federatedIdentityModel, federatedUser);
} }
if (federatedUser == null) { if (federatedUser == null) {
logger.debugf("Federated user not found for provider '%s' and broker username '%s'", providerId, context.getUsername()); logger.debugf("Federated user not found for provider '%s' and broker username '%s'", providerAlias, context.getUsername());
authenticationSession.setAuthNote(AbstractUsernameFormAuthenticator.ATTEMPTED_USERNAME, context.getUsername()); authenticationSession.setAuthNote(AbstractUsernameFormAuthenticator.ATTEMPTED_USERNAME, context.getUsername());
String username = context.getModelUsername(); String username = context.getModelUsername();
@ -654,14 +654,14 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
throw new IdentityBrokerException("Not found serialized context in clientSession"); throw new IdentityBrokerException("Not found serialized context in clientSession");
} }
BrokeredIdentityContext context = serializedCtx.deserialize(session, authSession); BrokeredIdentityContext context = serializedCtx.deserialize(session, authSession);
String providerId = context.getIdpConfig().getAlias(); String providerAlias = context.getIdpConfig().getAlias();
event.detail(Details.IDENTITY_PROVIDER, providerId); event.detail(Details.IDENTITY_PROVIDER, providerAlias);
event.detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername()); event.detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername());
// Ensure the first-broker-login flow was successfully finished // Ensure the first-broker-login flow was successfully finished
String authProvider = authSession.getAuthNote(AbstractIdpAuthenticator.FIRST_BROKER_LOGIN_SUCCESS); String authProvider = authSession.getAuthNote(AbstractIdpAuthenticator.FIRST_BROKER_LOGIN_SUCCESS);
if (authProvider == null || !authProvider.equals(providerId)) { if (authProvider == null || !authProvider.equals(providerAlias)) {
throw new IdentityBrokerException("Invalid request. Not found the flag that first-broker-login flow was finished"); throw new IdentityBrokerException("Invalid request. Not found the flag that first-broker-login flow was finished");
} }
@ -694,11 +694,11 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
String isRegisteredNewUser = authSession.getAuthNote(AbstractIdpAuthenticator.BROKER_REGISTERED_NEW_USER); String isRegisteredNewUser = authSession.getAuthNote(AbstractIdpAuthenticator.BROKER_REGISTERED_NEW_USER);
if (Boolean.parseBoolean(isRegisteredNewUser)) { if (Boolean.parseBoolean(isRegisteredNewUser)) {
logger.debugf("Registered new user '%s' after first login with identity provider '%s'. Identity provider username is '%s' . ", federatedUser.getUsername(), providerId, context.getUsername()); logger.debugf("Registered new user '%s' after first login with identity provider '%s'. Identity provider username is '%s' . ", federatedUser.getUsername(), providerAlias, context.getUsername());
context.getIdp().importNewUser(session, realmModel, federatedUser, context); context.getIdp().importNewUser(session, realmModel, federatedUser, context);
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory(); KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
realmModel.getIdentityProviderMappersByAliasStream(providerId).forEach(mapper -> { realmModel.getIdentityProviderMappersByAliasStream(providerAlias).forEach(mapper -> {
IdentityProviderMapper target = (IdentityProviderMapper) sessionFactory IdentityProviderMapper target = (IdentityProviderMapper) sessionFactory
.getProviderFactory(IdentityProviderMapper.class, mapper.getIdentityProviderMapper()); .getProviderFactory(IdentityProviderMapper.class, mapper.getIdentityProviderMapper());
target.importNewUser(session, realmModel, federatedUser, mapper, context); target.importNewUser(session, realmModel, federatedUser, mapper, context);
@ -716,7 +716,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
.success(); .success();
} else { } else {
logger.debugf("Linked existing keycloak user '%s' with identity provider '%s' . Identity provider username is '%s' .", federatedUser.getUsername(), providerId, context.getUsername()); logger.debugf("Linked existing keycloak user '%s' with identity provider '%s' . Identity provider username is '%s' .", federatedUser.getUsername(), providerAlias, context.getUsername());
event.event(EventType.FEDERATED_IDENTITY_LINK) event.event(EventType.FEDERATED_IDENTITY_LINK)
.success(); .success();
@ -795,11 +795,11 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
} }
private Response afterPostBrokerLoginFlowSuccess(AuthenticationSessionModel authSession, BrokeredIdentityContext context, boolean wasFirstBrokerLogin) { private Response afterPostBrokerLoginFlowSuccess(AuthenticationSessionModel authSession, BrokeredIdentityContext context, boolean wasFirstBrokerLogin) {
String providerId = context.getIdpConfig().getAlias(); String providerAlias = context.getIdpConfig().getAlias();
UserModel federatedUser = authSession.getAuthenticatedUser(); UserModel federatedUser = authSession.getAuthenticatedUser();
if (wasFirstBrokerLogin) { if (wasFirstBrokerLogin) {
return finishBrokerAuthentication(context, federatedUser, authSession, providerId); return finishBrokerAuthentication(context, federatedUser, authSession, providerAlias);
} else { } else {
boolean firstBrokerLoginInProgress = (authSession.getAuthNote(AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE) != null); boolean firstBrokerLoginInProgress = (authSession.getAuthNote(AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE) != null);
@ -811,23 +811,23 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
return afterFirstBrokerLogin(authSession); return afterFirstBrokerLogin(authSession);
} else { } else {
return finishBrokerAuthentication(context, federatedUser, authSession, providerId); return finishBrokerAuthentication(context, federatedUser, authSession, providerAlias);
} }
} }
} }
private Response finishBrokerAuthentication(BrokeredIdentityContext context, UserModel federatedUser, AuthenticationSessionModel authSession, String providerId) { private Response finishBrokerAuthentication(BrokeredIdentityContext context, UserModel federatedUser, AuthenticationSessionModel authSession, String providerAlias) {
authSession.setAuthNote(AuthenticationProcessor.BROKER_SESSION_ID, context.getBrokerSessionId()); authSession.setAuthNote(AuthenticationProcessor.BROKER_SESSION_ID, context.getBrokerSessionId());
authSession.setAuthNote(AuthenticationProcessor.BROKER_USER_ID, context.getBrokerUserId()); authSession.setAuthNote(AuthenticationProcessor.BROKER_USER_ID, context.getBrokerUserId());
this.event.user(federatedUser); this.event.user(federatedUser);
context.getIdp().authenticationFinished(authSession, context); context.getIdp().authenticationFinished(authSession, context);
authSession.setUserSessionNote(Details.IDENTITY_PROVIDER, providerId); authSession.setUserSessionNote(Details.IDENTITY_PROVIDER, providerAlias);
authSession.setUserSessionNote(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername()); authSession.setUserSessionNote(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername());
event.detail(Details.IDENTITY_PROVIDER, providerId) event.detail(Details.IDENTITY_PROVIDER, providerAlias)
.detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername()); .detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername());
if (isDebugEnabled()) { if (isDebugEnabled()) {
@ -881,7 +881,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
} }
private boolean shouldPerformAccountLinking(AuthenticationSessionModel authSession, UserSessionModel userSession, String providerId) { private boolean shouldPerformAccountLinking(AuthenticationSessionModel authSession, UserSessionModel userSession, String providerAlias) {
String noteFromSession = authSession.getAuthNote(LINKING_IDENTITY_PROVIDER); String noteFromSession = authSession.getAuthNote(LINKING_IDENTITY_PROVIDER);
if (noteFromSession == null) { if (noteFromSession == null) {
return false; return false;
@ -891,7 +891,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
if (userSession == null) { if (userSession == null) {
linkingValid = false; linkingValid = false;
} else { } else {
String expectedNote = userSession.getId() + authSession.getClient().getClientId() + providerId; String expectedNote = userSession.getId() + authSession.getClient().getClientId() + providerAlias;
linkingValid = expectedNote.equals(noteFromSession); linkingValid = expectedNote.equals(noteFromSession);
} }
@ -1140,7 +1140,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
return null; return null;
} }
private AuthenticationRequest createAuthenticationRequest(String providerId, ClientSessionCode<AuthenticationSessionModel> clientSessionCode) { private AuthenticationRequest createAuthenticationRequest(String providerAlias, ClientSessionCode<AuthenticationSessionModel> clientSessionCode) {
AuthenticationSessionModel authSession = null; AuthenticationSessionModel authSession = null;
IdentityBrokerState encodedState = null; IdentityBrokerState encodedState = null;
@ -1150,11 +1150,11 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
encodedState = IdentityBrokerState.decoded(relayState, authSession.getClient().getId(), authSession.getClient().getClientId(), authSession.getTabId()); encodedState = IdentityBrokerState.decoded(relayState, authSession.getClient().getId(), authSession.getClient().getClientId(), authSession.getTabId());
} }
return new AuthenticationRequest(this.session, this.realmModel, authSession, this.request, this.session.getContext().getUri(), encodedState, getRedirectUri(providerId)); return new AuthenticationRequest(this.session, this.realmModel, authSession, this.request, this.session.getContext().getUri(), encodedState, getRedirectUri(providerAlias));
} }
private String getRedirectUri(String providerId) { private String getRedirectUri(String providerAlias) {
return Urls.identityProviderAuthnResponse(this.session.getContext().getUri().getBaseUri(), providerId, this.realmModel.getName()).toString(); return Urls.identityProviderAuthnResponse(this.session.getContext().getUri().getBaseUri(), providerAlias, this.realmModel.getName()).toString();
} }
private Response redirectToErrorPage(AuthenticationSessionModel authSession, Response.Status status, String message, Object ... parameters) { private Response redirectToErrorPage(AuthenticationSessionModel authSession, Response.Status status, String message, Object ... parameters) {
@ -1241,11 +1241,11 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
throw ErrorResponse.error(message, Response.Status.NOT_FOUND); throw ErrorResponse.error(message, Response.Status.NOT_FOUND);
} }
public static IdentityProvider getIdentityProvider(KeycloakSession session, RealmModel realm, String alias) { public static IdentityProvider<?> getIdentityProvider(KeycloakSession session, RealmModel realm, String alias) {
IdentityProviderModel identityProviderModel = realm.getIdentityProviderByAlias(alias); IdentityProviderModel identityProviderModel = realm.getIdentityProviderByAlias(alias);
if (identityProviderModel != null) { if (identityProviderModel != null) {
IdentityProviderFactory providerFactory = getIdentityProviderFactory(session, identityProviderModel); IdentityProviderFactory<?> providerFactory = getIdentityProviderFactory(session, identityProviderModel);
if (providerFactory == null) { if (providerFactory == null) {
throw new IdentityBrokerException("Could not find factory for identity provider [" + alias + "]."); throw new IdentityBrokerException("Could not find factory for identity provider [" + alias + "].");
@ -1257,7 +1257,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
throw new IdentityBrokerException("Identity Provider [" + alias + "] not found."); throw new IdentityBrokerException("Identity Provider [" + alias + "] not found.");
} }
public static IdentityProviderFactory getIdentityProviderFactory(KeycloakSession session, IdentityProviderModel model) { public static IdentityProviderFactory<?> getIdentityProviderFactory(KeycloakSession session, IdentityProviderModel model) {
return Stream.concat(session.getKeycloakSessionFactory().getProviderFactoriesStream(IdentityProvider.class), return Stream.concat(session.getKeycloakSessionFactory().getProviderFactoriesStream(IdentityProvider.class),
session.getKeycloakSessionFactory().getProviderFactoriesStream(SocialIdentityProvider.class)) session.getKeycloakSessionFactory().getProviderFactoriesStream(SocialIdentityProvider.class))
.filter(providerFactory -> Objects.equals(providerFactory.getId(), model.getProviderId())) .filter(providerFactory -> Objects.equals(providerFactory.getId(), model.getProviderId()))
@ -1266,10 +1266,10 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
.orElse(null); .orElse(null);
} }
private IdentityProviderModel getIdentityProviderConfig(String providerId) { private IdentityProviderModel getIdentityProviderConfig(String providerAlias) {
IdentityProviderModel model = this.realmModel.getIdentityProviderByAlias(providerId); IdentityProviderModel model = this.realmModel.getIdentityProviderByAlias(providerAlias);
if (model == null) { if (model == null) {
throw new IdentityBrokerException("Configuration for identity provider [" + providerId + "] not found."); throw new IdentityBrokerException("Configuration for identity provider [" + providerAlias + "] not found.");
} }
return model; return model;
} }

View file

@ -115,9 +115,9 @@ public class LinkedAccountsResource {
private LinkedAccountRepresentation toLinkedAccountRepresentation(IdentityProviderModel provider, Set<String> socialIds, private LinkedAccountRepresentation toLinkedAccountRepresentation(IdentityProviderModel provider, Set<String> socialIds,
Stream<FederatedIdentityModel> identities) { Stream<FederatedIdentityModel> identities) {
String providerId = provider.getAlias(); String providerAlias = provider.getAlias();
FederatedIdentityModel identity = getIdentity(identities, providerId); FederatedIdentityModel identity = getIdentity(identities, providerAlias);
String displayName = KeycloakModelUtils.getIdentityProviderDisplayName(session, provider); String displayName = KeycloakModelUtils.getIdentityProviderDisplayName(session, provider);
String guiOrder = provider.getConfig() != null ? provider.getConfig().get("guiOrder") : null; String guiOrder = provider.getConfig() != null ? provider.getConfig().get("guiOrder") : null;
@ -125,7 +125,7 @@ public class LinkedAccountsResource {
LinkedAccountRepresentation rep = new LinkedAccountRepresentation(); LinkedAccountRepresentation rep = new LinkedAccountRepresentation();
rep.setConnected(identity != null); rep.setConnected(identity != null);
rep.setSocial(socialIds.contains(provider.getProviderId())); rep.setSocial(socialIds.contains(provider.getProviderId()));
rep.setProviderAlias(providerId); rep.setProviderAlias(providerAlias);
rep.setDisplayName(displayName); rep.setDisplayName(displayName);
rep.setGuiOrder(guiOrder); rep.setGuiOrder(guiOrder);
rep.setProviderName(provider.getAlias()); rep.setProviderName(provider.getAlias());
@ -135,16 +135,16 @@ public class LinkedAccountsResource {
return rep; return rep;
} }
private FederatedIdentityModel getIdentity(Stream<FederatedIdentityModel> identities, String providerId) { private FederatedIdentityModel getIdentity(Stream<FederatedIdentityModel> identities, String providerAlias) {
return identities.filter(model -> Objects.equals(model.getIdentityProvider(), providerId)) return identities.filter(model -> Objects.equals(model.getIdentityProvider(), providerAlias))
.findFirst().orElse(null); .findFirst().orElse(null);
} }
@GET @GET
@Path("/{providerId}") @Path("/{providerAlias}")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Deprecated @Deprecated
public Response buildLinkedAccountURI(@PathParam("providerId") String providerId, public Response buildLinkedAccountURI(@PathParam("providerAlias") String providerAlias,
@QueryParam("redirectUri") String redirectUri) { @QueryParam("redirectUri") String redirectUri) {
auth.require(AccountRoles.MANAGE_ACCOUNT); auth.require(AccountRoles.MANAGE_ACCOUNT);
@ -152,7 +152,7 @@ public class LinkedAccountsResource {
ErrorResponse.error(Messages.INVALID_REDIRECT_URI, Response.Status.BAD_REQUEST); ErrorResponse.error(Messages.INVALID_REDIRECT_URI, Response.Status.BAD_REQUEST);
} }
String errorMessage = checkCommonPreconditions(providerId); String errorMessage = checkCommonPreconditions(providerAlias);
if (errorMessage != null) { if (errorMessage != null) {
throw ErrorResponse.error(errorMessage, Response.Status.BAD_REQUEST); throw ErrorResponse.error(errorMessage, Response.Status.BAD_REQUEST);
} }
@ -163,10 +163,10 @@ public class LinkedAccountsResource {
try { try {
String nonce = UUID.randomUUID().toString(); String nonce = UUID.randomUUID().toString();
MessageDigest md = MessageDigest.getInstance("SHA-256"); MessageDigest md = MessageDigest.getInstance("SHA-256");
String input = nonce + auth.getSession().getId() + ACCOUNT_CONSOLE_CLIENT_ID + providerId; String input = nonce + auth.getSession().getId() + ACCOUNT_CONSOLE_CLIENT_ID + providerAlias;
byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8)); byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
String hash = Base64Url.encode(check); String hash = Base64Url.encode(check);
URI linkUri = Urls.identityProviderLinkRequest(this.session.getContext().getUri().getBaseUri(), providerId, realm.getName()); URI linkUri = Urls.identityProviderLinkRequest(this.session.getContext().getUri().getBaseUri(), providerAlias, realm.getName());
linkUri = UriBuilder.fromUri(linkUri) linkUri = UriBuilder.fromUri(linkUri)
.queryParam("nonce", nonce) .queryParam("nonce", nonce)
.queryParam("hash", hash) .queryParam("hash", hash)
@ -189,17 +189,17 @@ public class LinkedAccountsResource {
} }
@DELETE @DELETE
@Path("/{providerId}") @Path("/{providerAlias}")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Response removeLinkedAccount(@PathParam("providerId") String providerId) { public Response removeLinkedAccount(@PathParam("providerAlias") String providerAlias) {
auth.require(AccountRoles.MANAGE_ACCOUNT); auth.require(AccountRoles.MANAGE_ACCOUNT);
String errorMessage = checkCommonPreconditions(providerId); String errorMessage = checkCommonPreconditions(providerAlias);
if (errorMessage != null) { if (errorMessage != null) {
throw ErrorResponse.error(errorMessage, Response.Status.BAD_REQUEST); throw ErrorResponse.error(errorMessage, Response.Status.BAD_REQUEST);
} }
FederatedIdentityModel link = session.users().getFederatedIdentity(realm, user, providerId); FederatedIdentityModel link = session.users().getFederatedIdentity(realm, user, providerAlias);
if (link == null) { if (link == null) {
throw ErrorResponse.error(Messages.FEDERATED_IDENTITY_NOT_ACTIVE, Response.Status.BAD_REQUEST); throw ErrorResponse.error(Messages.FEDERATED_IDENTITY_NOT_ACTIVE, Response.Status.BAD_REQUEST);
} }
@ -208,10 +208,10 @@ public class LinkedAccountsResource {
if (!(session.users().getFederatedIdentitiesStream(realm, user).count() > 1 || user.getFederationLink() != null || isPasswordSet())) { if (!(session.users().getFederatedIdentitiesStream(realm, user).count() > 1 || user.getFederationLink() != null || isPasswordSet())) {
throw ErrorResponse.error(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER, Response.Status.BAD_REQUEST); throw ErrorResponse.error(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER, Response.Status.BAD_REQUEST);
} }
session.users().removeFederatedIdentity(realm, user, providerId);
logger.debugv("Social provider {0} removed successfully from user {1}", providerId, user.getUsername()); session.users().removeFederatedIdentity(realm, user, providerAlias);
logger.debugv("Social provider {0} removed successfully from user {1}", providerAlias, user.getUsername());
event.event(EventType.REMOVE_FEDERATED_IDENTITY).client(auth.getClient()).user(auth.getUser()) event.event(EventType.REMOVE_FEDERATED_IDENTITY).client(auth.getClient()).user(auth.getUser())
.detail(Details.USERNAME, auth.getUser().getUsername()) .detail(Details.USERNAME, auth.getUser().getUsername())
@ -222,14 +222,14 @@ public class LinkedAccountsResource {
return Cors.add(request, Response.noContent()).auth().allowedOrigins(auth.getToken()).build(); return Cors.add(request, Response.noContent()).auth().allowedOrigins(auth.getToken()).build();
} }
private String checkCommonPreconditions(String providerId) { private String checkCommonPreconditions(String providerAlias) {
auth.require(AccountRoles.MANAGE_ACCOUNT); auth.require(AccountRoles.MANAGE_ACCOUNT);
if (Validation.isEmpty(providerId)) { if (Validation.isEmpty(providerAlias)) {
return Messages.MISSING_IDENTITY_PROVIDER; return Messages.MISSING_IDENTITY_PROVIDER;
} }
if (!isValidProvider(providerId)) { if (!isValidProvider(providerAlias)) {
return Messages.IDENTITY_PROVIDER_NOT_FOUND; return Messages.IDENTITY_PROVIDER_NOT_FOUND;
} }
@ -244,7 +244,7 @@ public class LinkedAccountsResource {
return user.credentialManager().isConfiguredFor(PasswordCredentialModel.TYPE); return user.credentialManager().isConfiguredFor(PasswordCredentialModel.TYPE);
} }
private boolean isValidProvider(String providerId) { private boolean isValidProvider(String providerAlias) {
return realm.getIdentityProvidersStream().anyMatch(model -> Objects.equals(model.getAlias(), providerId)); return realm.getIdentityProvidersStream().anyMatch(model -> Objects.equals(model.getAlias(), providerAlias));
} }
} }