Search in sources :

Example 6 with IdentityProvider

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

the class IdentityBrokerService method getEndpoint.

@Path("{provider_id}/endpoint")
public Object getEndpoint(@PathParam("provider_id") String providerId) {
    IdentityProvider identityProvider;
    try {
        identityProvider = getIdentityProvider(session, realmModel, providerId);
    } catch (IdentityBrokerException e) {
        throw new NotFoundException(e.getMessage());
    }
    Object callback = identityProvider.callback(realmModel, this, event);
    ResteasyProviderFactory.getInstance().injectProperties(callback);
    return callback;
}
Also used : IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) NotFoundException(javax.ws.rs.NotFoundException) SocialIdentityProvider(org.keycloak.broker.social.SocialIdentityProvider) IdentityProvider(org.keycloak.broker.provider.IdentityProvider) Path(javax.ws.rs.Path)

Example 7 with IdentityProvider

use of org.keycloak.broker.provider.IdentityProvider 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 8 with IdentityProvider

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

the class AuthenticationManager method backchannelLogoutAll.

private static BackchannelLogoutResponse backchannelLogoutAll(KeycloakSession session, RealmModel realm, UserSessionModel userSession, AuthenticationSessionModel logoutAuthSession, UriInfo uriInfo, HttpHeaders headers, boolean logoutBroker) {
    BackchannelLogoutResponse backchannelLogoutResponse = new BackchannelLogoutResponse();
    for (AuthenticatedClientSessionModel clientSession : userSession.getAuthenticatedClientSessions().values()) {
        Response clientSessionLogoutResponse = backchannelLogoutClientSession(session, realm, clientSession, logoutAuthSession, uriInfo, headers);
        String backchannelLogoutUrl = OIDCAdvancedConfigWrapper.fromClientModel(clientSession.getClient()).getBackchannelLogoutUrl();
        BackchannelLogoutResponse.DownStreamBackchannelLogoutResponse downStreamBackchannelLogoutResponse = new BackchannelLogoutResponse.DownStreamBackchannelLogoutResponse();
        downStreamBackchannelLogoutResponse.setWithBackchannelLogoutUrl(backchannelLogoutUrl != null);
        if (clientSessionLogoutResponse != null) {
            downStreamBackchannelLogoutResponse.setResponseCode(clientSessionLogoutResponse.getStatus());
        } else {
            downStreamBackchannelLogoutResponse.setResponseCode(null);
        }
        backchannelLogoutResponse.addClientResponses(downStreamBackchannelLogoutResponse);
    }
    if (logoutBroker) {
        String brokerId = userSession.getNote(Details.IDENTITY_PROVIDER);
        if (brokerId != null) {
            IdentityProvider identityProvider = IdentityBrokerService.getIdentityProvider(session, realm, brokerId);
            try {
                identityProvider.backchannelLogout(session, userSession, uriInfo, realm);
            } catch (Exception e) {
                logger.warn("Exception at broker backchannel logout for broker " + brokerId, e);
                backchannelLogoutResponse.setLocalLogoutSucceeded(false);
            }
        }
    }
    return backchannelLogoutResponse;
}
Also used : BackchannelLogoutResponse(org.keycloak.protocol.oidc.BackchannelLogoutResponse) Response(javax.ws.rs.core.Response) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) IdentityProvider(org.keycloak.broker.provider.IdentityProvider) BackchannelLogoutResponse(org.keycloak.protocol.oidc.BackchannelLogoutResponse) ErrorResponseException(org.keycloak.services.ErrorResponseException) AuthenticationFlowException(org.keycloak.authentication.AuthenticationFlowException) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException) VerificationException(org.keycloak.common.VerificationException) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Example 9 with IdentityProvider

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

the class SerializedBrokeredIdentityContext method deserialize.

public BrokeredIdentityContext deserialize(KeycloakSession session, AuthenticationSessionModel authSession) {
    BrokeredIdentityContext ctx = new BrokeredIdentityContext(getId());
    ctx.setUsername(getBrokerUsername());
    ctx.setModelUsername(getModelUsername());
    ctx.setEmail(getEmail());
    ctx.setFirstName(getFirstName());
    ctx.setLastName(getLastName());
    ctx.setBrokerSessionId(getBrokerSessionId());
    ctx.setBrokerUserId(getBrokerUserId());
    ctx.setToken(getToken());
    RealmModel realm = authSession.getRealm();
    IdentityProviderModel idpConfig = realm.getIdentityProviderByAlias(getIdentityProviderId());
    if (idpConfig == null) {
        throw new ModelException("Can't find identity provider with ID " + getIdentityProviderId() + " in realm " + realm.getName());
    }
    IdentityProvider idp = IdentityBrokerService.getIdentityProvider(session, realm, idpConfig.getAlias());
    ctx.setIdpConfig(idpConfig);
    ctx.setIdp(idp);
    IdentityProviderDataMarshaller serializer = idp.getMarshaller();
    for (Map.Entry<String, ContextDataEntry> entry : getContextData().entrySet()) {
        try {
            ContextDataEntry value = entry.getValue();
            Class<?> clazz = Reflections.classForName(value.getClazz(), this.getClass().getClassLoader());
            Object deserialized = serializer.deserialize(value.getData(), clazz);
            ctx.getContextData().put(entry.getKey(), deserialized);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    ctx.setAuthenticationSession(authSession);
    return ctx;
}
Also used : ModelException(org.keycloak.models.ModelException) IdentityProvider(org.keycloak.broker.provider.IdentityProvider) IdentityProviderModel(org.keycloak.models.IdentityProviderModel) BrokeredIdentityContext(org.keycloak.broker.provider.BrokeredIdentityContext) IOException(java.io.IOException) ModelException(org.keycloak.models.ModelException) RealmModel(org.keycloak.models.RealmModel) IdentityProviderDataMarshaller(org.keycloak.broker.provider.IdentityProviderDataMarshaller) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

IdentityProvider (org.keycloak.broker.provider.IdentityProvider)9 Response (javax.ws.rs.core.Response)6 IdentityProviderModel (org.keycloak.models.IdentityProviderModel)6 IOException (java.io.IOException)4 NotFoundException (javax.ws.rs.NotFoundException)4 OAuthErrorException (org.keycloak.OAuthErrorException)4 IdentityBrokerException (org.keycloak.broker.provider.IdentityBrokerException)4 SocialIdentityProvider (org.keycloak.broker.social.SocialIdentityProvider)4 AuthenticationSessionModel (org.keycloak.sessions.AuthenticationSessionModel)4 RootAuthenticationSessionModel (org.keycloak.sessions.RootAuthenticationSessionModel)4 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)3 Path (javax.ws.rs.Path)3 WebApplicationException (javax.ws.rs.WebApplicationException)3 ClientModel (org.keycloak.models.ClientModel)3 ErrorPageException (org.keycloak.services.ErrorPageException)3 AuthenticationManager (org.keycloak.services.managers.AuthenticationManager)3 Map (java.util.Map)2 GET (javax.ws.rs.GET)2 NoCache (org.jboss.resteasy.annotations.cache.NoCache)2 BrokeredIdentityContext (org.keycloak.broker.provider.BrokeredIdentityContext)2