use of org.keycloak.broker.provider.IdentityProvider in project keycloak by keycloak.
the class DefaultTokenExchangeProvider method exchangeToIdentityProvider.
protected Response exchangeToIdentityProvider(UserModel targetUser, UserSessionModel targetUserSession, String requestedIssuer) {
event.detail(Details.REQUESTED_ISSUER, requestedIssuer);
IdentityProviderModel providerModel = realm.getIdentityProviderByAlias(requestedIssuer);
if (providerModel == null) {
event.detail(Details.REASON, "unknown requested_issuer");
event.error(Errors.UNKNOWN_IDENTITY_PROVIDER);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "Invalid issuer", Response.Status.BAD_REQUEST);
}
IdentityProvider provider = IdentityBrokerService.getIdentityProvider(session, realm, requestedIssuer);
if (!(provider instanceof ExchangeTokenToIdentityProviderToken)) {
event.detail(Details.REASON, "exchange unsupported by requested_issuer");
event.error(Errors.UNKNOWN_IDENTITY_PROVIDER);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "Issuer does not support token exchange", Response.Status.BAD_REQUEST);
}
if (!AdminPermissions.management(session, realm).idps().canExchangeTo(client, providerModel)) {
event.detail(Details.REASON, "client not allowed to exchange for requested_issuer");
event.error(Errors.NOT_ALLOWED);
throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "Client not allowed to exchange", Response.Status.FORBIDDEN);
}
Response response = ((ExchangeTokenToIdentityProviderToken) provider).exchangeFromToken(session.getContext().getUri(), event, client, targetUserSession, targetUser, formParams);
return cors.builder(Response.fromResponse(response)).build();
}
use of org.keycloak.broker.provider.IdentityProvider in project keycloak by keycloak.
the class DefaultTokenExchangeProvider method exchangeExternalToken.
protected Response exchangeExternalToken(String issuer, String subjectToken) {
AtomicReference<ExchangeExternalToken> externalIdp = new AtomicReference<>(null);
AtomicReference<IdentityProviderModel> externalIdpModel = new AtomicReference<>(null);
realm.getIdentityProvidersStream().filter(idpModel -> {
IdentityProviderFactory factory = IdentityBrokerService.getIdentityProviderFactory(session, idpModel);
IdentityProvider idp = factory.create(session, idpModel);
if (idp instanceof ExchangeExternalToken) {
ExchangeExternalToken external = (ExchangeExternalToken) idp;
if (idpModel.getAlias().equals(issuer) || external.isIssuer(issuer, formParams)) {
externalIdp.set(external);
externalIdpModel.set(idpModel);
return true;
}
}
return false;
}).findFirst();
if (externalIdp.get() == null) {
event.error(Errors.INVALID_ISSUER);
throw new CorsErrorResponseException(cors, Errors.INVALID_ISSUER, "Invalid " + OAuth2Constants.SUBJECT_ISSUER + " parameter", Response.Status.BAD_REQUEST);
}
if (!AdminPermissions.management(session, realm).idps().canExchangeTo(client, externalIdpModel.get())) {
event.detail(Details.REASON, "client not allowed to exchange subject_issuer");
event.error(Errors.NOT_ALLOWED);
throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "Client not allowed to exchange", Response.Status.FORBIDDEN);
}
BrokeredIdentityContext context = externalIdp.get().exchangeExternal(event, formParams);
if (context == null) {
event.error(Errors.INVALID_ISSUER);
throw new CorsErrorResponseException(cors, Errors.INVALID_ISSUER, "Invalid " + OAuth2Constants.SUBJECT_ISSUER + " parameter", Response.Status.BAD_REQUEST);
}
UserModel user = importUserFromExternalIdentity(context);
UserSessionModel userSession = session.sessions().createUserSession(realm, user, user.getUsername(), clientConnection.getRemoteAddr(), "external-exchange", false, null, null);
externalIdp.get().exchangeExternalComplete(userSession, context, formParams);
// this must exist so that we can obtain access token from user session if idp's store tokens is off
userSession.setNote(IdentityProvider.EXTERNAL_IDENTITY_PROVIDER, externalIdpModel.get().getAlias());
userSession.setNote(IdentityProvider.FEDERATED_ACCESS_TOKEN, subjectToken);
return exchangeClientToClient(user, userSession);
}
use of org.keycloak.broker.provider.IdentityProvider in project keycloak by keycloak.
the class AuthenticationManager method browserLogout.
public static Response browserLogout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers, String initiatingIdp) {
if (userSession == null)
return null;
if (logger.isDebugEnabled()) {
UserModel user = userSession.getUser();
logger.debugv("Logging out: {0} ({1})", user.getUsername(), userSession.getId());
}
if (userSession.getState() != UserSessionModel.State.LOGGING_OUT) {
userSession.setState(UserSessionModel.State.LOGGING_OUT);
}
final AuthenticationSessionManager asm = new AuthenticationSessionManager(session);
AuthenticationSessionModel logoutAuthSession = createOrJoinLogoutSession(session, realm, asm, userSession, true);
Response response = browserLogoutAllClients(userSession, session, realm, headers, uriInfo, logoutAuthSession);
if (response != null) {
return response;
}
String brokerId = userSession.getNote(Details.IDENTITY_PROVIDER);
if (brokerId != null && !brokerId.equals(initiatingIdp)) {
IdentityProvider identityProvider = IdentityBrokerService.getIdentityProvider(session, realm, brokerId);
response = identityProvider.keycloakInitiatedBrowserLogout(session, userSession, uriInfo, realm);
if (response != null) {
return response;
}
}
return finishBrowserLogout(session, realm, userSession, uriInfo, connection, headers);
}
use of org.keycloak.broker.provider.IdentityProvider in project keycloak by keycloak.
the class IdentityBrokerService method performLogin.
@GET
@NoCache
@Path("/{provider_id}/login")
public Response performLogin(@PathParam("provider_id") String providerId, @QueryParam(LoginActionsService.SESSION_CODE) String code, @QueryParam("client_id") String clientId, @QueryParam(Constants.TAB_ID) String tabId, @QueryParam(OIDCLoginProtocol.LOGIN_HINT_PARAM) String loginHint) {
this.event.detail(Details.IDENTITY_PROVIDER, providerId);
if (isDebugEnabled()) {
logger.debugf("Sending authentication request to identity provider [%s].", providerId);
}
try {
AuthenticationSessionModel authSession = parseSessionCode(code, clientId, tabId);
ClientSessionCode<AuthenticationSessionModel> clientSessionCode = new ClientSessionCode<>(session, realmModel, authSession);
clientSessionCode.setAction(AuthenticationSessionModel.Action.AUTHENTICATE.name());
IdentityProviderModel identityProviderModel = realmModel.getIdentityProviderByAlias(providerId);
if (identityProviderModel == null) {
throw new IdentityBrokerException("Identity Provider [" + providerId + "] not found.");
}
if (identityProviderModel.isLinkOnly()) {
throw new IdentityBrokerException("Identity Provider [" + providerId + "] is not allowed to perform a login.");
}
if (clientSessionCode != null && clientSessionCode.getClientSession() != null && loginHint != null) {
clientSessionCode.getClientSession().setClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM, loginHint);
}
IdentityProviderFactory providerFactory = getIdentityProviderFactory(session, identityProviderModel);
IdentityProvider identityProvider = providerFactory.create(session, identityProviderModel);
Response response = identityProvider.performLogin(createAuthenticationRequest(providerId, clientSessionCode));
if (response != null) {
if (isDebugEnabled()) {
logger.debugf("Identity provider [%s] is going to send a request [%s].", identityProvider, response);
}
return response;
}
} catch (IdentityBrokerException e) {
return redirectToErrorPage(Response.Status.BAD_GATEWAY, Messages.COULD_NOT_SEND_AUTHENTICATION_REQUEST, e, providerId);
} 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.COULD_NOT_PROCEED_WITH_AUTHENTICATION_REQUEST);
}
use of org.keycloak.broker.provider.IdentityProvider in project keycloak by keycloak.
the class IdentityBrokerService method getToken.
private Response getToken(String providerId, boolean forceRetrieval) {
this.event.event(EventType.IDENTITY_PROVIDER_RETRIEVE_TOKEN);
try {
AuthenticationManager.AuthResult authResult = new AppAuthManager.BearerTokenAuthenticator(session).setRealm(realmModel).setConnection(clientConnection).setHeaders(request.getHttpHeaders()).authenticate();
if (authResult != null) {
AccessToken token = authResult.getToken();
ClientModel clientModel = authResult.getClient();
session.getContext().setClient(clientModel);
ClientModel brokerClient = realmModel.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID);
if (brokerClient == null) {
return corsResponse(forbidden("Realm has not migrated to support the broker token exchange service"), clientModel);
}
if (!canReadBrokerToken(token)) {
return corsResponse(forbidden("Client [" + clientModel.getClientId() + "] not authorized to retrieve tokens from identity provider [" + providerId + "]."), clientModel);
}
IdentityProvider identityProvider = getIdentityProvider(session, realmModel, providerId);
IdentityProviderModel identityProviderConfig = getIdentityProviderConfig(providerId);
if (identityProviderConfig.isStoreToken()) {
FederatedIdentityModel identity = this.session.users().getFederatedIdentity(this.realmModel, authResult.getUser(), providerId);
if (identity == null) {
return corsResponse(badRequest("User [" + authResult.getUser().getId() + "] is not associated with identity provider [" + providerId + "]."), clientModel);
}
this.event.success();
return corsResponse(identityProvider.retrieveToken(session, identity), clientModel);
}
return corsResponse(badRequest("Identity Provider [" + providerId + "] does not support this operation."), clientModel);
}
return badRequest("Invalid token.");
} catch (IdentityBrokerException e) {
return redirectToErrorPage(Response.Status.BAD_GATEWAY, Messages.COULD_NOT_OBTAIN_TOKEN, e, providerId);
} catch (Exception e) {
return redirectToErrorPage(Response.Status.BAD_GATEWAY, Messages.UNEXPECTED_ERROR_RETRIEVING_TOKEN, e, providerId);
}
}
Aggregations