Search in sources :

Example 1 with SamlClient

use of org.keycloak.protocol.saml.SamlClient in project keycloak by keycloak.

the class KeycloakSamlSubsystemInstallation method generateInstallation.

@Override
public Response generateInstallation(KeycloakSession session, RealmModel realm, ClientModel client, URI baseUri) {
    SamlClient samlClient = new SamlClient(client);
    StringBuilder buffer = new StringBuilder();
    buffer.append("<secure-deployment name=\"YOUR-WAR.war\">\n");
    KeycloakSamlClientInstallation.baseXml(session, realm, client, baseUri, samlClient, buffer);
    buffer.append("</secure-deployment>\n");
    return Response.ok(buffer.toString(), MediaType.TEXT_PLAIN_TYPE).build();
}
Also used : SamlClient(org.keycloak.protocol.saml.SamlClient)

Example 2 with SamlClient

use of org.keycloak.protocol.saml.SamlClient in project keycloak by keycloak.

the class SamlSPDescriptorClientInstallation method getSPDescriptorForClient.

public static String getSPDescriptorForClient(ClientModel client) {
    try {
        SamlClient samlClient = new SamlClient(client);
        String assertionUrl;
        String logoutUrl;
        URI loginBinding;
        URI logoutBinding = null;
        if (samlClient.forcePostBinding()) {
            assertionUrl = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE);
            logoutUrl = client.getAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE);
            loginBinding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.getUri();
        } else {
            // redirect binding
            assertionUrl = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE);
            logoutUrl = client.getAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE);
            loginBinding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.getUri();
        }
        if (samlClient.forceArtifactBinding()) {
            if (client.getAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_ARTIFACT_ATTRIBUTE) != null) {
                logoutBinding = JBossSAMLURIConstants.SAML_HTTP_ARTIFACT_BINDING.getUri();
                logoutUrl = client.getAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_ARTIFACT_ATTRIBUTE);
            } else {
                logoutBinding = loginBinding;
            }
            assertionUrl = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_ARTIFACT_ATTRIBUTE);
            loginBinding = JBossSAMLURIConstants.SAML_HTTP_ARTIFACT_BINDING.getUri();
        }
        if (assertionUrl == null || assertionUrl.trim().isEmpty())
            assertionUrl = client.getManagementUrl();
        if (assertionUrl == null || assertionUrl.trim().isEmpty())
            assertionUrl = FALLBACK_ERROR_URL_STRING;
        if (logoutUrl == null || logoutUrl.trim().isEmpty())
            logoutUrl = client.getManagementUrl();
        if (logoutUrl == null || logoutUrl.trim().isEmpty())
            logoutUrl = FALLBACK_ERROR_URL_STRING;
        if (logoutBinding == null)
            logoutBinding = loginBinding;
        String nameIdFormat = samlClient.getNameIDFormat();
        if (nameIdFormat == null)
            nameIdFormat = SamlProtocol.SAML_DEFAULT_NAMEID_FORMAT;
        Element spCertificate = SPMetadataDescriptor.buildKeyInfoElement(null, samlClient.getClientSigningCertificate());
        Element encCertificate = SPMetadataDescriptor.buildKeyInfoElement(null, samlClient.getClientEncryptingCertificate());
        StringWriter sw = new StringWriter();
        XMLStreamWriter writer = StaxUtil.getXMLStreamWriter(sw);
        SAMLMetadataWriter metadataWriter = new SAMLMetadataWriter(writer);
        EntityDescriptorType entityDescriptor = SPMetadataDescriptor.buildSPdescriptor(loginBinding, logoutBinding, new URI(assertionUrl), new URI(logoutUrl), samlClient.requiresClientSignature(), samlClient.requiresAssertionSignature(), samlClient.requiresEncryption(), client.getClientId(), nameIdFormat, Arrays.asList(spCertificate), Arrays.asList(encCertificate));
        metadataWriter.writeEntityDescriptor(entityDescriptor);
        return sw.toString();
    } catch (Exception ex) {
        logger.error("Cannot generate SP metadata", ex);
        return "";
    }
}
Also used : SAMLMetadataWriter(org.keycloak.saml.processing.core.saml.v2.writers.SAMLMetadataWriter) StringWriter(java.io.StringWriter) XMLStreamWriter(javax.xml.stream.XMLStreamWriter) Element(org.w3c.dom.Element) EntityDescriptorType(org.keycloak.dom.saml.v2.metadata.EntityDescriptorType) URI(java.net.URI) SamlClient(org.keycloak.protocol.saml.SamlClient)

Example 3 with SamlClient

use of org.keycloak.protocol.saml.SamlClient in project keycloak by keycloak.

the class KeycloakSamlSubsystemCliInstallation method generateInstallation.

@Override
public Response generateInstallation(KeycloakSession session, RealmModel realm, ClientModel client, URI baseUri) {
    SamlClient samlClient = new SamlClient(client);
    StringBuilder builder = new StringBuilder();
    String entityId = client.getBaseUrl() == null ? "SPECIFY YOUR entityID!" : client.getBaseUrl();
    String bindingUrl = RealmsResource.protocolUrl(UriBuilder.fromUri(baseUri)).build(realm.getName(), SamlProtocol.LOGIN_PROTOCOL).toString();
    builder.append("/subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/:add\n\n").append("/subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP=").append(quote(entityId)).append("/:add(sslPolicy=").append(realm.getSslRequired().name()).append(",logoutPage=").append(quote("SPECIFY YOUR LOGOUT PAGE!")).append("\n\n");
    if (samlClient.requiresClientSignature()) {
        builder.append("/subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP=").append(quote(entityId)).append("/Key=KEY1:add(signing=true, \\\nPrivateKeyPem=").append(quote(samlClient.getClientSigningPrivateKey() == null ? "PRIVATE KEY NOT SET UP OR KNOWN" : samlClient.getClientSigningPrivateKey())).append(", \\\nCertificatePem=").append(quote(samlClient.getClientSigningCertificate() == null ? "YOU MUST CONFIGURE YOUR_CLIENT's SIGNING CERTIFICATE" : samlClient.getClientSigningCertificate())).append(")\n\n");
    }
    if (samlClient.requiresEncryption()) {
        builder.append("/subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP=").append(quote(entityId)).append("/Key=KEY2:add(encryption=true,PrivateKeyPem=").append(quote(samlClient.getClientEncryptingPrivateKey() == null ? "PRIVATE KEY NOT SET UP OR KNOWN" : samlClient.getClientEncryptingPrivateKey())).append(")\n\n");
    }
    builder.append("/subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP=").append(quote(entityId)).append("/IDP=idp/:add( \\\n    SingleSignOnService={ \\\n        signRequest=").append(Boolean.toString(samlClient.requiresClientSignature())).append(", \\\n        validateResponseSignature=").append(Boolean.toString(samlClient.requiresRealmSignature())).append(", \\\n        validateAssertionSignature=").append(Boolean.toString(samlClient.requiresAssertionSignature())).append(", \\\n        requestBinding=POST, \\\n        bindingUrl=").append(bindingUrl).append("}, \\\n    SingleLogoutService={ \\\n        signRequest=").append(Boolean.toString(samlClient.requiresClientSignature())).append(", \\\n        signResponse=").append(Boolean.toString(samlClient.requiresClientSignature())).append(", \\\n        validateRequestSignature=").append(Boolean.toString(samlClient.requiresRealmSignature())).append(", \\\n        validateResponseSignature=").append(Boolean.toString(samlClient.requiresRealmSignature())).append(", \\\n        requestBinding=POST, \\\n        responseBinding=POST, \\\n        postBindingUrl=").append(bindingUrl).append(", \\\n        redirectBindingUrl=").append(bindingUrl).append("} \\\n)\n\n");
    if (samlClient.requiresClientSignature()) {
        builder.append("/subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP=").append(quote(entityId)).append("/IDP=idp/:write-attribute(name=signatureAlgorithm,value=").append(samlClient.getSignatureAlgorithm()).append(")\n\n");
        if (samlClient.getCanonicalizationMethod() != null) {
            builder.append("/subsystem=keycloak-saml/secure-deployment=YOUR-WAR.war/SP=").append(quote(entityId)).append("/IDP=idp/:write-attribute(name=signatureCanonicalizationMethod,value=").append(samlClient.getCanonicalizationMethod()).append(")\n");
        }
    }
    return Response.ok(builder.toString(), MediaType.TEXT_PLAIN_TYPE).build();
}
Also used : SamlClient(org.keycloak.protocol.saml.SamlClient)

Example 4 with SamlClient

use of org.keycloak.protocol.saml.SamlClient in project keycloak by keycloak.

the class ClientManager method clientIdChanged.

public void clientIdChanged(ClientModel client, ClientRepresentation newClientRepresentation) {
    String newClientId = newClientRepresentation.getClientId();
    logger.debugf("Updating clientId from '%s' to '%s'", client.getClientId(), newClientId);
    UserModel serviceAccountUser = realmManager.getSession().users().getServiceAccount(client);
    if (serviceAccountUser != null) {
        String username = ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + newClientId;
        serviceAccountUser.setUsername(username);
    }
    if (SamlProtocol.LOGIN_PROTOCOL.equals(client.getProtocol())) {
        SamlClient samlClient = new SamlClient(client);
        samlClient.setArtifactBindingIdentifierFrom(newClientId);
        newClientRepresentation.getAttributes().put(SamlConfigAttributes.SAML_ARTIFACT_BINDING_IDENTIFIER, samlClient.getArtifactBindingIdentifier());
    }
}
Also used : UserModel(org.keycloak.models.UserModel) SamlClient(org.keycloak.protocol.saml.SamlClient)

Example 5 with SamlClient

use of org.keycloak.protocol.saml.SamlClient in project keycloak by keycloak.

the class DefaultTokenExchangeProvider method exchangeClientToSAML2Client.

protected Response exchangeClientToSAML2Client(UserModel targetUser, UserSessionModel targetUserSession, String requestedTokenType, ClientModel targetClient, String audience, String scope) {
    // Create authSession with target SAML 2.0 client and authenticated user
    LoginProtocolFactory factory = (LoginProtocolFactory) session.getKeycloakSessionFactory().getProviderFactory(LoginProtocol.class, SamlProtocol.LOGIN_PROTOCOL);
    SamlService samlService = (SamlService) factory.createProtocolEndpoint(realm, event);
    ResteasyProviderFactory.getInstance().injectProperties(samlService);
    AuthenticationSessionModel authSession = samlService.getOrCreateLoginSessionForIdpInitiatedSso(session, realm, targetClient, null);
    if (authSession == null) {
        logger.error("SAML assertion consumer url not set up");
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_CLIENT, "Client requires assertion consumer url set up", Response.Status.BAD_REQUEST);
    }
    authSession.setAuthenticatedUser(targetUser);
    event.session(targetUserSession);
    AuthenticationManager.setClientScopesInSession(authSession);
    ClientSessionContext clientSessionCtx = TokenManager.attachAuthenticationSession(this.session, targetUserSession, authSession);
    updateUserSessionFromClientAuth(targetUserSession);
    // Create SAML 2.0 Assertion Response
    SamlClient samlClient = new SamlClient(targetClient);
    SamlProtocol samlProtocol = new TokenExchangeSamlProtocol(samlClient).setEventBuilder(event).setHttpHeaders(headers).setRealm(realm).setSession(session).setUriInfo(session.getContext().getUri());
    Response samlAssertion = samlProtocol.authenticated(authSession, targetUserSession, clientSessionCtx);
    if (samlAssertion.getStatus() != 200) {
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "Can not get SAML 2.0 token", Response.Status.BAD_REQUEST);
    }
    String xmlString = (String) samlAssertion.getEntity();
    String encodedXML = Base64Url.encode(xmlString.getBytes(GeneralConstants.SAML_CHARSET));
    int assertionLifespan = samlClient.getAssertionLifespan();
    AccessTokenResponse res = new AccessTokenResponse();
    res.setToken(encodedXML);
    res.setTokenType("Bearer");
    res.setExpiresIn(assertionLifespan <= 0 ? realm.getAccessCodeLifespan() : assertionLifespan);
    res.setOtherClaims(OAuth2Constants.ISSUED_TOKEN_TYPE, requestedTokenType);
    event.detail(Details.AUDIENCE, targetClient.getClientId());
    event.success();
    return cors.builder(Response.ok(res, MediaType.APPLICATION_JSON_TYPE)).build();
}
Also used : AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) TokenExchangeSamlProtocol(org.keycloak.protocol.oidc.endpoints.TokenEndpoint.TokenExchangeSamlProtocol) SamlProtocol(org.keycloak.protocol.saml.SamlProtocol) TokenExchangeSamlProtocol(org.keycloak.protocol.oidc.endpoints.TokenEndpoint.TokenExchangeSamlProtocol) SamlClient(org.keycloak.protocol.saml.SamlClient) SamlService(org.keycloak.protocol.saml.SamlService) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse) Response(javax.ws.rs.core.Response) LoginProtocolFactory(org.keycloak.protocol.LoginProtocolFactory) ClientSessionContext(org.keycloak.models.ClientSessionContext) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) LoginProtocol(org.keycloak.protocol.LoginProtocol) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse)

Aggregations

SamlClient (org.keycloak.protocol.saml.SamlClient)7 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1 StringWriter (java.io.StringWriter)1 URI (java.net.URI)1 ZipEntry (java.util.zip.ZipEntry)1 ZipOutputStream (java.util.zip.ZipOutputStream)1 Response (javax.ws.rs.core.Response)1 XMLStreamWriter (javax.xml.stream.XMLStreamWriter)1 EntityDescriptorType (org.keycloak.dom.saml.v2.metadata.EntityDescriptorType)1 ClientSessionContext (org.keycloak.models.ClientSessionContext)1 UserModel (org.keycloak.models.UserModel)1 LoginProtocol (org.keycloak.protocol.LoginProtocol)1 LoginProtocolFactory (org.keycloak.protocol.LoginProtocolFactory)1 TokenExchangeSamlProtocol (org.keycloak.protocol.oidc.endpoints.TokenEndpoint.TokenExchangeSamlProtocol)1 SamlProtocol (org.keycloak.protocol.saml.SamlProtocol)1 SamlService (org.keycloak.protocol.saml.SamlService)1 AccessTokenResponse (org.keycloak.representations.AccessTokenResponse)1 SAMLMetadataWriter (org.keycloak.saml.processing.core.saml.v2.writers.SAMLMetadataWriter)1 CorsErrorResponseException (org.keycloak.services.CorsErrorResponseException)1