Search in sources :

Example 11 with IdentityBrokerException

use of org.keycloak.broker.provider.IdentityBrokerException 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);
}
Also used : Response(javax.ws.rs.core.Response) ErrorResponse(org.keycloak.services.ErrorResponse) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) SocialIdentityProvider(org.keycloak.broker.social.SocialIdentityProvider) IdentityProvider(org.keycloak.broker.provider.IdentityProvider) IdentityProviderModel(org.keycloak.models.IdentityProviderModel) ClientSessionCode(org.keycloak.services.managers.ClientSessionCode) IdentityProviderFactory(org.keycloak.broker.provider.IdentityProviderFactory) 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) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET) NoCache(org.jboss.resteasy.annotations.cache.NoCache)

Example 12 with IdentityBrokerException

use of org.keycloak.broker.provider.IdentityBrokerException 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);
    }
}
Also used : AuthenticationManager(org.keycloak.services.managers.AuthenticationManager) ClientModel(org.keycloak.models.ClientModel) AccessToken(org.keycloak.representations.AccessToken) FederatedIdentityModel(org.keycloak.models.FederatedIdentityModel) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) SocialIdentityProvider(org.keycloak.broker.social.SocialIdentityProvider) IdentityProvider(org.keycloak.broker.provider.IdentityProvider) IdentityProviderModel(org.keycloak.models.IdentityProviderModel) 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)

Example 13 with IdentityBrokerException

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

the class SAMLIdentityProvider method performLogin.

@Override
public Response performLogin(AuthenticationRequest request) {
    try {
        UriInfo uriInfo = request.getUriInfo();
        RealmModel realm = request.getRealm();
        String issuerURL = getEntityId(uriInfo, realm);
        String destinationUrl = getConfig().getSingleSignOnServiceUrl();
        String nameIDPolicyFormat = getConfig().getNameIDPolicyFormat();
        if (nameIDPolicyFormat == null) {
            nameIDPolicyFormat = JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get();
        }
        String protocolBinding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get();
        String assertionConsumerServiceUrl = request.getRedirectUri();
        if (getConfig().isPostBindingResponse()) {
            protocolBinding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get();
        }
        SAML2RequestedAuthnContextBuilder requestedAuthnContext = new SAML2RequestedAuthnContextBuilder().setComparison(getConfig().getAuthnContextComparisonType());
        for (String authnContextClassRef : getAuthnContextClassRefUris()) requestedAuthnContext.addAuthnContextClassRef(authnContextClassRef);
        for (String authnContextDeclRef : getAuthnContextDeclRefUris()) requestedAuthnContext.addAuthnContextDeclRef(authnContextDeclRef);
        Integer attributeConsumingServiceIndex = getConfig().getAttributeConsumingServiceIndex();
        String loginHint = getConfig().isLoginHint() ? request.getAuthenticationSession().getClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM) : null;
        Boolean allowCreate = null;
        if (getConfig().getConfig().get(SAMLIdentityProviderConfig.ALLOW_CREATE) == null || getConfig().isAllowCreate())
            allowCreate = Boolean.TRUE;
        SAML2AuthnRequestBuilder authnRequestBuilder = new SAML2AuthnRequestBuilder().assertionConsumerUrl(assertionConsumerServiceUrl).destination(destinationUrl).issuer(issuerURL).forceAuthn(getConfig().isForceAuthn()).protocolBinding(protocolBinding).nameIdPolicy(SAML2NameIDPolicyBuilder.format(nameIDPolicyFormat).setAllowCreate(allowCreate)).attributeConsumingServiceIndex(attributeConsumingServiceIndex).requestedAuthnContext(requestedAuthnContext).subject(loginHint);
        JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder(session).relayState(request.getState().getEncoded());
        boolean postBinding = getConfig().isPostBindingAuthnRequest();
        if (getConfig().isWantAuthnRequestsSigned()) {
            KeyManager.ActiveRsaKey keys = session.keys().getActiveRsaKey(realm);
            String keyName = getConfig().getXmlSigKeyInfoKeyNameTransformer().getKeyName(keys.getKid(), keys.getCertificate());
            binding.signWith(keyName, keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signatureAlgorithm(getSignatureAlgorithm()).signDocument();
            if (!postBinding && getConfig().isAddExtensionsElementWithKeyInfo()) {
                // Only include extension if REDIRECT binding and signing whole SAML protocol message
                authnRequestBuilder.addExtension(new KeycloakKeySamlExtensionGenerator(keyName));
            }
        }
        AuthnRequestType authnRequest = authnRequestBuilder.createAuthnRequest();
        for (Iterator<SamlAuthenticationPreprocessor> it = SamlSessionUtils.getSamlAuthenticationPreprocessorIterator(session); it.hasNext(); ) {
            authnRequest = it.next().beforeSendingLoginRequest(authnRequest, request.getAuthenticationSession());
        }
        if (authnRequest.getDestination() != null) {
            destinationUrl = authnRequest.getDestination().toString();
        }
        // Save the current RequestID in the Auth Session as we need to verify it against the ID returned from the IdP
        request.getAuthenticationSession().setClientNote(SamlProtocol.SAML_REQUEST_ID_BROKER, authnRequest.getID());
        if (postBinding) {
            return binding.postBinding(authnRequestBuilder.toDocument()).request(destinationUrl);
        } else {
            return binding.redirectBinding(authnRequestBuilder.toDocument()).request(destinationUrl);
        }
    } catch (Exception e) {
        throw new IdentityBrokerException("Could not create authentication request.", e);
    }
}
Also used : SAML2RequestedAuthnContextBuilder(org.keycloak.saml.SAML2RequestedAuthnContextBuilder) JaxrsSAML2BindingBuilder(org.keycloak.protocol.saml.JaxrsSAML2BindingBuilder) KeycloakKeySamlExtensionGenerator(org.keycloak.saml.processing.core.util.KeycloakKeySamlExtensionGenerator) ConfigurationException(org.keycloak.saml.common.exceptions.ConfigurationException) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) RealmModel(org.keycloak.models.RealmModel) AuthnRequestType(org.keycloak.dom.saml.v2.protocol.AuthnRequestType) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) SamlAuthenticationPreprocessor(org.keycloak.protocol.saml.preprocessor.SamlAuthenticationPreprocessor) SAML2AuthnRequestBuilder(org.keycloak.saml.SAML2AuthnRequestBuilder) KeyManager(org.keycloak.models.KeyManager) UriInfo(javax.ws.rs.core.UriInfo)

Example 14 with IdentityBrokerException

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

the class OIDCIdentityProvider method getFederatedIdentity.

@Override
public BrokeredIdentityContext getFederatedIdentity(String response) {
    AccessTokenResponse tokenResponse = null;
    try {
        tokenResponse = JsonSerialization.readValue(response, AccessTokenResponse.class);
    } catch (IOException e) {
        throw new IdentityBrokerException("Could not decode access token response.", e);
    }
    String accessToken = verifyAccessToken(tokenResponse);
    String encodedIdToken = tokenResponse.getIdToken();
    JsonWebToken idToken = validateToken(encodedIdToken);
    try {
        BrokeredIdentityContext identity = extractIdentity(tokenResponse, accessToken, idToken);
        if (!identity.getId().equals(idToken.getSubject())) {
            throw new IdentityBrokerException("Mismatch between the subject in the id_token and the subject from the user_info endpoint");
        }
        identity.getContextData().put(BROKER_NONCE_PARAM, idToken.getOtherClaims().get(OIDCLoginProtocol.NONCE_PARAM));
        if (getConfig().isStoreToken()) {
            if (tokenResponse.getExpiresIn() > 0) {
                long accessTokenExpiration = Time.currentTime() + tokenResponse.getExpiresIn();
                tokenResponse.getOtherClaims().put(ACCESS_TOKEN_EXPIRATION, accessTokenExpiration);
                response = JsonSerialization.writeValueAsString(tokenResponse);
            }
            identity.setToken(response);
        }
        return identity;
    } catch (Exception e) {
        throw new IdentityBrokerException("Could not fetch attributes from userinfo endpoint.", e);
    }
}
Also used : IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) IOException(java.io.IOException) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse) JsonWebToken(org.keycloak.representations.JsonWebToken) BrokeredIdentityContext(org.keycloak.broker.provider.BrokeredIdentityContext) OAuthErrorException(org.keycloak.OAuthErrorException) ErrorResponseException(org.keycloak.services.ErrorResponseException) JWSInputException(org.keycloak.jose.jws.JWSInputException) IOException(java.io.IOException) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException)

Example 15 with IdentityBrokerException

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

the class OIDCIdentityProvider method validateToken.

protected JsonWebToken validateToken(String encodedToken, boolean ignoreAudience) {
    if (encodedToken == null) {
        throw new IdentityBrokerException("No token from server.");
    }
    JsonWebToken token;
    try {
        JWSInput jws = new JWSInput(encodedToken);
        if (!verify(jws)) {
            throw new IdentityBrokerException("token signature validation failed");
        }
        token = jws.readJsonContent(JsonWebToken.class);
    } catch (JWSInputException e) {
        throw new IdentityBrokerException("Invalid token", e);
    }
    String iss = token.getIssuer();
    if (!token.isActive(getConfig().getAllowedClockSkew())) {
        throw new IdentityBrokerException("Token is no longer valid");
    }
    if (!ignoreAudience && !token.hasAudience(getConfig().getClientId())) {
        throw new IdentityBrokerException("Wrong audience from token.");
    }
    if (!ignoreAudience && (token.getIssuedFor() != null && !getConfig().getClientId().equals(token.getIssuedFor()))) {
        throw new IdentityBrokerException("Token issued for does not match client id");
    }
    String trustedIssuers = getConfig().getIssuer();
    if (trustedIssuers != null && trustedIssuers.length() > 0) {
        String[] issuers = trustedIssuers.split(",");
        for (String trustedIssuer : issuers) {
            if (iss != null && iss.equals(trustedIssuer.trim())) {
                return token;
            }
        }
        throw new IdentityBrokerException("Wrong issuer from token. Got: " + iss + " expected: " + getConfig().getIssuer());
    }
    return token;
}
Also used : IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) JWSInputException(org.keycloak.jose.jws.JWSInputException) JWSInput(org.keycloak.jose.jws.JWSInput) JsonWebToken(org.keycloak.representations.JsonWebToken)

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