Search in sources :

Example 26 with IdentityBrokerException

use of org.keycloak.broker.provider.IdentityBrokerException in project keycloak by keycloak.

the class IdentityBrokerService method clientInitiatedAccountLinking.

@GET
@NoCache
@Path("/{provider_id}/link")
public Response clientInitiatedAccountLinking(@PathParam("provider_id") String providerId, @QueryParam("redirect_uri") String redirectUri, @QueryParam("client_id") String clientId, @QueryParam("nonce") String nonce, @QueryParam("hash") String hash) {
    this.event.event(EventType.CLIENT_INITIATED_ACCOUNT_LINKING);
    checkRealm();
    ClientModel client = checkClient(clientId);
    redirectUri = RedirectUtils.verifyRedirectUri(session, redirectUri, client);
    if (redirectUri == null) {
        event.error(Errors.INVALID_REDIRECT_URI);
        throw new ErrorPageException(session, Response.Status.BAD_REQUEST, Messages.INVALID_REQUEST);
    }
    event.detail(Details.REDIRECT_URI, redirectUri);
    if (nonce == null || hash == null) {
        event.error(Errors.INVALID_REDIRECT_URI);
        throw new ErrorPageException(session, Response.Status.BAD_REQUEST, Messages.INVALID_REQUEST);
    }
    AuthenticationManager.AuthResult cookieResult = AuthenticationManager.authenticateIdentityCookie(session, realmModel, true);
    String errorParam = "link_error";
    if (cookieResult == null) {
        event.error(Errors.NOT_LOGGED_IN);
        UriBuilder builder = UriBuilder.fromUri(redirectUri).queryParam(errorParam, Errors.NOT_LOGGED_IN).queryParam("nonce", nonce);
        return Response.status(302).location(builder.build()).build();
    }
    cookieResult.getSession();
    event.session(cookieResult.getSession());
    event.user(cookieResult.getUser());
    event.detail(Details.USERNAME, cookieResult.getUser().getUsername());
    AuthenticatedClientSessionModel clientSession = null;
    for (AuthenticatedClientSessionModel cs : cookieResult.getSession().getAuthenticatedClientSessions().values()) {
        if (cs.getClient().getClientId().equals(clientId)) {
            byte[] decoded = Base64Url.decode(hash);
            MessageDigest md = null;
            try {
                md = MessageDigest.getInstance("SHA-256");
            } catch (NoSuchAlgorithmException e) {
                throw new ErrorPageException(session, Response.Status.INTERNAL_SERVER_ERROR, Messages.UNEXPECTED_ERROR_HANDLING_REQUEST);
            }
            String input = nonce + cookieResult.getSession().getId() + clientId + providerId;
            byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
            if (MessageDigest.isEqual(decoded, check)) {
                clientSession = cs;
                break;
            }
        }
    }
    if (clientSession == null) {
        event.error(Errors.INVALID_TOKEN);
        throw new ErrorPageException(session, Response.Status.BAD_REQUEST, Messages.INVALID_REQUEST);
    }
    event.detail(Details.IDENTITY_PROVIDER, providerId);
    ClientModel accountService = this.realmModel.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
    if (!accountService.getId().equals(client.getId())) {
        RoleModel manageAccountRole = accountService.getRole(AccountRoles.MANAGE_ACCOUNT);
        // Ensure user has role and client has "role scope" for this role
        ClientSessionContext ctx = DefaultClientSessionContext.fromClientSessionScopeParameter(clientSession, session);
        Set<RoleModel> userAccountRoles = ctx.getRolesStream().collect(Collectors.toSet());
        if (!userAccountRoles.contains(manageAccountRole)) {
            RoleModel linkRole = accountService.getRole(AccountRoles.MANAGE_ACCOUNT_LINKS);
            if (!userAccountRoles.contains(linkRole)) {
                event.error(Errors.NOT_ALLOWED);
                UriBuilder builder = UriBuilder.fromUri(redirectUri).queryParam(errorParam, Errors.NOT_ALLOWED).queryParam("nonce", nonce);
                return Response.status(302).location(builder.build()).build();
            }
        }
    }
    IdentityProviderModel identityProviderModel = realmModel.getIdentityProviderByAlias(providerId);
    if (identityProviderModel == null) {
        event.error(Errors.UNKNOWN_IDENTITY_PROVIDER);
        UriBuilder builder = UriBuilder.fromUri(redirectUri).queryParam(errorParam, Errors.UNKNOWN_IDENTITY_PROVIDER).queryParam("nonce", nonce);
        return Response.status(302).location(builder.build()).build();
    }
    // Create AuthenticationSessionModel with same ID like userSession and refresh cookie
    UserSessionModel userSession = cookieResult.getSession();
    // Auth session with ID corresponding to our userSession may already exists in some rare cases (EG. if some client tried to login in another browser tab with "prompt=login")
    RootAuthenticationSessionModel rootAuthSession = session.authenticationSessions().getRootAuthenticationSession(realmModel, userSession.getId());
    if (rootAuthSession == null) {
        rootAuthSession = session.authenticationSessions().createRootAuthenticationSession(realmModel, userSession.getId());
    }
    AuthenticationSessionModel authSession = rootAuthSession.createAuthenticationSession(client);
    // Refresh the cookie
    new AuthenticationSessionManager(session).setAuthSessionCookie(userSession.getId(), realmModel);
    ClientSessionCode<AuthenticationSessionModel> clientSessionCode = new ClientSessionCode<>(session, realmModel, authSession);
    clientSessionCode.setAction(AuthenticationSessionModel.Action.AUTHENTICATE.name());
    clientSessionCode.getOrGenerateCode();
    authSession.setProtocol(client.getProtocol());
    authSession.setRedirectUri(redirectUri);
    authSession.setClientNote(OIDCLoginProtocol.STATE_PARAM, UUID.randomUUID().toString());
    authSession.setAuthNote(LINKING_IDENTITY_PROVIDER, cookieResult.getSession().getId() + clientId + providerId);
    event.detail(Details.CODE_ID, userSession.getId());
    event.success();
    try {
        IdentityProvider identityProvider = getIdentityProvider(session, realmModel, providerId);
        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(authSession, Response.Status.INTERNAL_SERVER_ERROR, Messages.COULD_NOT_SEND_AUTHENTICATION_REQUEST, e, providerId);
    } 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.COULD_NOT_PROCEED_WITH_AUTHENTICATION_REQUEST);
}
Also used : UserSessionModel(org.keycloak.models.UserSessionModel) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) RoleModel(org.keycloak.models.RoleModel) SocialIdentityProvider(org.keycloak.broker.social.SocialIdentityProvider) IdentityProvider(org.keycloak.broker.provider.IdentityProvider) ErrorPageException(org.keycloak.services.ErrorPageException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) IdentityProviderModel(org.keycloak.models.IdentityProviderModel) ClientSessionCode(org.keycloak.services.managers.ClientSessionCode) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) WebApplicationException(javax.ws.rs.WebApplicationException) IOException(java.io.IOException) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) OAuthErrorException(org.keycloak.OAuthErrorException) NotFoundException(javax.ws.rs.NotFoundException) ErrorPageException(org.keycloak.services.ErrorPageException) AuthenticationManager(org.keycloak.services.managers.AuthenticationManager) AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) Response(javax.ws.rs.core.Response) ErrorResponse(org.keycloak.services.ErrorResponse) ClientModel(org.keycloak.models.ClientModel) DefaultClientSessionContext(org.keycloak.services.util.DefaultClientSessionContext) ClientSessionContext(org.keycloak.models.ClientSessionContext) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) UriBuilder(javax.ws.rs.core.UriBuilder) MessageDigest(java.security.MessageDigest) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET) NoCache(org.jboss.resteasy.annotations.cache.NoCache)

Example 27 with IdentityBrokerException

use of org.keycloak.broker.provider.IdentityBrokerException in project keycloak by keycloak.

the class BitbucketIdentityProvider method doGetFederatedIdentity.

@Override
protected BrokeredIdentityContext doGetFederatedIdentity(String accessToken) {
    try {
        JsonNode profile = SimpleHttp.doGet(USER_URL, session).header("Authorization", "Bearer " + accessToken).asJson();
        String type = getJsonProperty(profile, "type");
        if (type == null) {
            throw new IdentityBrokerException("Could not obtain account information from bitbucket.");
        }
        if (type.equals("error")) {
            JsonNode errorNode = profile.get("error");
            if (errorNode != null) {
                String errorMsg = getJsonProperty(errorNode, "message");
                throw new IdentityBrokerException("Could not obtain account information from bitbucket.  Error: " + errorMsg);
            } else {
                throw new IdentityBrokerException("Could not obtain account information from bitbucket.");
            }
        }
        if (!type.equals("user")) {
            logger.debug("Unknown object type: " + type);
            throw new IdentityBrokerException("Could not obtain account information from bitbucket.");
        }
        return extractUserInfo(accessToken, profile);
    } catch (Exception e) {
        if (e instanceof IdentityBrokerException)
            throw (IdentityBrokerException) e;
        throw new IdentityBrokerException("Could not obtain user profile from bitbucket.", e);
    }
}
Also used : IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) JsonNode(com.fasterxml.jackson.databind.JsonNode) IOException(java.io.IOException) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) OAuthErrorException(org.keycloak.OAuthErrorException) ErrorResponseException(org.keycloak.services.ErrorResponseException)

Aggregations

IdentityBrokerException (org.keycloak.broker.provider.IdentityBrokerException)27 IOException (java.io.IOException)13 BrokeredIdentityContext (org.keycloak.broker.provider.BrokeredIdentityContext)11 JsonNode (com.fasterxml.jackson.databind.JsonNode)8 OAuthErrorException (org.keycloak.OAuthErrorException)7 NotFoundException (javax.ws.rs.NotFoundException)5 WebApplicationException (javax.ws.rs.WebApplicationException)5 ErrorResponseException (org.keycloak.services.ErrorResponseException)5 AuthenticationSessionModel (org.keycloak.sessions.AuthenticationSessionModel)5 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)4 Path (javax.ws.rs.Path)4 IdentityProvider (org.keycloak.broker.provider.IdentityProvider)4 SocialIdentityProvider (org.keycloak.broker.social.SocialIdentityProvider)4 IdentityProviderModel (org.keycloak.models.IdentityProviderModel)4 RoleModel (org.keycloak.models.RoleModel)4 JsonWebToken (org.keycloak.representations.JsonWebToken)4 ErrorPageException (org.keycloak.services.ErrorPageException)4 GET (javax.ws.rs.GET)3 NoCache (org.jboss.resteasy.annotations.cache.NoCache)3 ClientModel (org.keycloak.models.ClientModel)3