Java Code Examples for org.keycloak.models.ClientModel#getAttribute()

The following examples show how to use org.keycloak.models.ClientModel#getAttribute() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SamlService.java    From keycloak with Apache License 2.0 6 votes vote down vote up
/**
 * Checks the client configuration to return the redirect URL and the binding type.
 * POST is preferred, only if the SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE
 * and management URL are empty REDIRECT is chosen.
 *
 * @param client Client to create client session for
 * @return a two string array [samlUrl, bindingType] or null if error
 */
private String[] getUrlAndBindingForIdpInitiatedSso(ClientModel client) {
    String postUrl = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE);
    String getUrl = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE);
    if (postUrl != null && !postUrl.trim().isEmpty()) {
        // first the POST binding URL
        return new String[] {postUrl.trim(), SamlProtocol.SAML_POST_BINDING};
    } else if (client.getManagementUrl() != null && !client.getManagementUrl().trim().isEmpty()) {
        // second the management URL and POST
        return new String[] {client.getManagementUrl().trim(), SamlProtocol.SAML_POST_BINDING};
    } else if (getUrl != null && !getUrl.trim().isEmpty()){
        // last option REDIRECT binding and URL
        return new String[] {getUrl.trim(), SamlProtocol.SAML_REDIRECT_BINDING};
    } else {
        // error
        return null;
    }
}
 
Example 2
Source File: SamlService.java    From keycloak with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a client session object for SAML IdP-initiated SSO session.
 * The session takes the parameters from from client definition,
 * namely binding type and redirect URL.
 *
 * @param session KC session
 * @param realm Realm to create client session in
 * @param client Client to create client session for
 * @param relayState Optional relay state - free field as per SAML specification
 * @return The auth session model or null if there is no SAML url is found
 */
public AuthenticationSessionModel getOrCreateLoginSessionForIdpInitiatedSso(KeycloakSession session, RealmModel realm, ClientModel client, String relayState) {
    String[] bindingProperties = getUrlAndBindingForIdpInitiatedSso(client);
    if (bindingProperties == null) {
        return null;
    }
    String redirect = bindingProperties[0];
    String bindingType = bindingProperties[1];

    AuthenticationSessionModel authSession = createAuthenticationSession(client, null);

    authSession.setProtocol(SamlProtocol.LOGIN_PROTOCOL);
    authSession.setAction(AuthenticationSessionModel.Action.AUTHENTICATE.name());
    authSession.setClientNote(SamlProtocol.SAML_BINDING, bindingType);
    authSession.setClientNote(SamlProtocol.SAML_IDP_INITIATED_LOGIN, "true");
    authSession.setRedirectUri(redirect);

    if (relayState == null) {
        relayState = client.getAttribute(SamlProtocol.SAML_IDP_INITIATED_SSO_RELAY_STATE);
    }
    if (relayState != null && !relayState.trim().equals("")) {
        authSession.setClientNote(GeneralConstants.RELAY_STATE, relayState);
    }

    return authSession;
}
 
Example 3
Source File: SamlProtocol.java    From keycloak with Apache License 2.0 6 votes vote down vote up
protected boolean isLogoutPostBindingForClient(AuthenticatedClientSessionModel clientSession) {
    ClientModel client = clientSession.getClient();
    SamlClient samlClient = new SamlClient(client);
    String logoutPostUrl = client.getAttribute(SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE);
    String logoutRedirectUrl = client.getAttribute(SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE);

    if (logoutPostUrl == null || logoutPostUrl.trim().isEmpty()) {
        // if we don't have a redirect uri either, return true and default to the admin url + POST binding
        return (logoutRedirectUrl == null || logoutRedirectUrl.trim().isEmpty());
    }

    if (samlClient.forcePostBinding()) {
        return true; // configured to force a post binding and post binding logout url is not null
    }

    String bindingType = clientSession.getNote(SAML_BINDING);

    // if the login binding was POST, return true
    if (SAML_POST_BINDING.equals(bindingType))
        return true;

    // true if we don't have a redirect binding url, so use post binding, false for redirect binding
    return (logoutRedirectUrl == null || logoutRedirectUrl.trim().isEmpty());
}
 
Example 4
Source File: SamlSPDescriptorClientInstallation.java    From keycloak with Apache License 2.0 6 votes vote down vote up
public static String getSPDescriptorForClient(ClientModel client) {
    SamlClient samlClient = new SamlClient(client);
    String assertionUrl;
    String logoutUrl;
    String binding;
    if (samlClient.forcePostBinding()) {
        assertionUrl = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE);
        logoutUrl = client.getAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE);
        binding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get();
    } else { //redirect binding
        assertionUrl = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE);
        logoutUrl = client.getAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE);
        binding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get();
    }
    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;
    String nameIdFormat = samlClient.getNameIDFormat();
    if (nameIdFormat == null) nameIdFormat = SamlProtocol.SAML_DEFAULT_NAMEID_FORMAT;
    String spCertificate = SPMetadataDescriptor.xmlKeyInfo("        ", null, samlClient.getClientSigningCertificate(), KeyTypes.SIGNING.value(), true);
    String encCertificate = SPMetadataDescriptor.xmlKeyInfo("        ", null, samlClient.getClientEncryptingCertificate(), KeyTypes.ENCRYPTION.value(), true);
    return SPMetadataDescriptor.getSPDescriptor(binding, assertionUrl, logoutUrl, samlClient.requiresClientSignature(), 
            samlClient.requiresAssertionSignature(), samlClient.requiresEncryption(),
            client.getClientId(), nameIdFormat, spCertificate, encCertificate);
}
 
Example 5
Source File: DefaultTokenManager.java    From keycloak with Apache License 2.0 6 votes vote down vote up
private String getSignatureAlgorithm(String clientAttribute) {
    RealmModel realm = session.getContext().getRealm();
    ClientModel client = session.getContext().getClient();

    String algorithm = client != null && clientAttribute != null ? client.getAttribute(clientAttribute) : null;
    if (algorithm != null && !algorithm.equals("")) {
        return algorithm;
    }

    algorithm = realm.getDefaultSignatureAlgorithm();
    if (algorithm != null && !algorithm.equals("")) {
        return algorithm;
    }

    return DEFAULT_ALGORITHM_NAME;
}
 
Example 6
Source File: SamlService.java    From keycloak with Apache License 2.0 5 votes vote down vote up
@GET
@Path("clients/{client}")
@Produces(MediaType.TEXT_HTML_UTF_8)
public Response idpInitiatedSSO(@PathParam("client") String clientUrlName, @QueryParam("RelayState") String relayState) {
    event.event(EventType.LOGIN);
    CacheControlUtil.noBackButtonCacheControlHeader();
    ClientModel client = null;
    for (ClientModel c : realm.getClients()) {
        String urlName = c.getAttribute(SamlProtocol.SAML_IDP_INITIATED_SSO_URL_NAME);
        if (urlName == null)
            continue;
        if (urlName.equals(clientUrlName)) {
            client = c;
            break;
        }
    }
    if (client == null) {
        event.error(Errors.CLIENT_NOT_FOUND);
        return ErrorPage.error(session, null, Response.Status.BAD_REQUEST, Messages.CLIENT_NOT_FOUND);
    }
    if (!client.isEnabled()) {
        event.error(Errors.CLIENT_DISABLED);
        return ErrorPage.error(session, null, Response.Status.BAD_REQUEST, Messages.CLIENT_DISABLED);
    }
    if (!isClientProtocolCorrect(client)) {
        event.error(Errors.INVALID_CLIENT);
        return ErrorPage.error(session, null, Response.Status.BAD_REQUEST, "Wrong client protocol.");
    }

    session.getContext().setClient(client);

    AuthenticationSessionModel authSession = getOrCreateLoginSessionForIdpInitiatedSso(this.session, this.realm, client, relayState);
    if (authSession == null) {
        logger.error("SAML assertion consumer url not set up");
        event.error(Errors.INVALID_REDIRECT_URI);
        return ErrorPage.error(session, null, Response.Status.BAD_REQUEST, Messages.INVALID_REDIRECT_URI);
    }

    return newBrowserAuthentication(authSession, false, false);
}
 
Example 7
Source File: SamlProtocol.java    From keycloak with Apache License 2.0 5 votes vote down vote up
public static String getLogoutServiceUrl(KeycloakSession session, ClientModel client, String bindingType) {
    String logoutServiceUrl = null;
    if (SAML_POST_BINDING.equals(bindingType)) {
        logoutServiceUrl = client.getAttribute(SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE);
    } else {
        logoutServiceUrl = client.getAttribute(SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT_ATTRIBUTE);
    }
    if (logoutServiceUrl == null)
        logoutServiceUrl = client.getManagementUrl();
    if (logoutServiceUrl == null || logoutServiceUrl.trim().equals(""))
        return null;
    return ResourceAdminManager.resolveUri(session, client.getRootUrl(), logoutServiceUrl);

}
 
Example 8
Source File: DefaultTokenManager.java    From keycloak with Apache License 2.0 5 votes vote down vote up
private String getCekManagementAlgorithm(String clientAttribute) {
    ClientModel client = session.getContext().getClient();
    String algorithm = client != null && clientAttribute != null ? client.getAttribute(clientAttribute) : null;
    if (algorithm != null && !algorithm.equals("")) {
        return algorithm;
    }
    return null;
}
 
Example 9
Source File: DefaultTokenManager.java    From keycloak with Apache License 2.0 5 votes vote down vote up
private String getEncryptAlgorithm(String clientAttribute) {
    ClientModel client = session.getContext().getClient();
    String algorithm = client != null && clientAttribute != null ? client.getAttribute(clientAttribute) : null;
    if (algorithm != null && !algorithm.equals("")) {
        return algorithm;
    }
    return null;
}
 
Example 10
Source File: DefaultThemeSelectorProvider.java    From keycloak with Apache License 2.0 5 votes vote down vote up
@Override
public String getThemeName(Theme.Type type) {
    String name = null;

    switch (type) {
        case WELCOME:
            name = Config.scope("theme").get("welcomeTheme");
            break;
        case LOGIN:
            ClientModel client = session.getContext().getClient();
            if (client != null) {
                name = client.getAttribute(LOGIN_THEME_KEY);
            }

            if (name == null || name.isEmpty()) {
                name = session.getContext().getRealm().getLoginTheme();
            }
            
            break;
        case ACCOUNT:
            name = session.getContext().getRealm().getAccountTheme();
            break;
        case EMAIL:
            name = session.getContext().getRealm().getEmailTheme();
            break;
        case ADMIN:
            name = session.getContext().getRealm().getAdminTheme();
            break;
    }

    if (name == null || name.isEmpty()) {
        name = Config.scope("theme").get("default", Version.NAME.toLowerCase());
    }

    return name;
}
 
Example 11
Source File: SamlService.java    From keycloak with Apache License 2.0 4 votes vote down vote up
protected Response loginRequest(String relayState, AuthnRequestType requestAbstractType, ClientModel client) {
    SamlClient samlClient = new SamlClient(client);

    if (! validateDestination(requestAbstractType, samlClient, Errors.INVALID_SAML_AUTHN_REQUEST)) {
        return ErrorPage.error(session, null, Response.Status.BAD_REQUEST, Messages.INVALID_REQUEST);
    }

    String bindingType = getBindingType(requestAbstractType);
    if (samlClient.forcePostBinding())
        bindingType = SamlProtocol.SAML_POST_BINDING;
    String redirect;
    URI redirectUri = requestAbstractType.getAssertionConsumerServiceURL();
    if (redirectUri != null && ! "null".equals(redirectUri.toString())) { // "null" is for testing purposes
        redirect = RedirectUtils.verifyRedirectUri(session, redirectUri.toString(), client);
    } else {
        if (bindingType.equals(SamlProtocol.SAML_POST_BINDING)) {
            redirect = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_POST_ATTRIBUTE);
        } else {
            redirect = client.getAttribute(SamlProtocol.SAML_ASSERTION_CONSUMER_URL_REDIRECT_ATTRIBUTE);
        }
        if (redirect == null || redirect.trim().isEmpty()) {
            redirect = client.getManagementUrl();
        }

    }

    if (redirect == null) {
        event.error(Errors.INVALID_REDIRECT_URI);
        return ErrorPage.error(session, null, Response.Status.BAD_REQUEST, Messages.INVALID_REDIRECT_URI);
    }

    AuthenticationSessionModel authSession = createAuthenticationSession(client, relayState);

    authSession.setProtocol(SamlProtocol.LOGIN_PROTOCOL);
    authSession.setRedirectUri(redirect);
    authSession.setAction(AuthenticationSessionModel.Action.AUTHENTICATE.name());
    authSession.setClientNote(SamlProtocol.SAML_BINDING, bindingType);
    authSession.setClientNote(GeneralConstants.RELAY_STATE, relayState);
    authSession.setClientNote(SamlProtocol.SAML_REQUEST_ID, requestAbstractType.getID());

    // Handle NameIDPolicy from SP
    NameIDPolicyType nameIdPolicy = requestAbstractType.getNameIDPolicy();
    final URI nameIdFormatUri = nameIdPolicy == null ? null : nameIdPolicy.getFormat();
    if (nameIdFormatUri != null && ! samlClient.forceNameIDFormat()) {
        String nameIdFormat = nameIdFormatUri.toString();
        // TODO: Handle AllowCreate too, relevant for persistent NameID.
        if (isSupportedNameIdFormat(nameIdFormat)) {
            authSession.setClientNote(GeneralConstants.NAMEID_FORMAT, nameIdFormat);
        } else {
            event.detail(Details.REASON, "unsupported_nameid_format");
            event.error(Errors.INVALID_SAML_AUTHN_REQUEST);
            return ErrorPage.error(session, null, Response.Status.BAD_REQUEST, Messages.UNSUPPORTED_NAME_ID_FORMAT);
        }
    }

    //Reading subject/nameID in the saml request
    SubjectType subject = requestAbstractType.getSubject();
    if (subject != null) {
        SubjectType.STSubType subType = subject.getSubType();
        if (subType != null) {
            BaseIDAbstractType baseID = subject.getSubType().getBaseID();
            if (baseID instanceof NameIDType) {
                NameIDType nameID = (NameIDType) baseID;
                authSession.setClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM, nameID.getValue());
            }

        }
    }

    if (null != requestAbstractType.isForceAuthn()
        && requestAbstractType.isForceAuthn()) {
        authSession.setAuthNote(SamlProtocol.SAML_LOGIN_REQUEST_FORCEAUTHN, SamlProtocol.SAML_FORCEAUTHN_REQUIREMENT);
    }
    

    for(Iterator<SamlAuthenticationPreprocessor> it = SamlSessionUtils.getSamlAuthenticationPreprocessorIterator(session); it.hasNext();) {
        requestAbstractType = it.next().beforeProcessingLoginRequest(requestAbstractType, authSession);
    }

    //If unset we fall back to default "false"
    final boolean isPassive = (null != requestAbstractType.isIsPassive() && requestAbstractType.isIsPassive().booleanValue());
    return newBrowserAuthentication(authSession, isPassive, redirectToAuthentication);
}
 
Example 12
Source File: SamlProtocolUtils.java    From keycloak with Apache License 2.0 4 votes vote down vote up
public static PublicKey getPublicKey(ClientModel client, String attribute) throws VerificationException {
    String certPem = client.getAttribute(attribute);
    return getPublicKey(certPem);
}
 
Example 13
Source File: X509ClientAuthenticator.java    From keycloak with Apache License 2.0 4 votes vote down vote up
@Override
public void authenticateClient(ClientAuthenticationFlowContext context) {

    X509ClientCertificateLookup provider = context.getSession().getProvider(X509ClientCertificateLookup.class);
    if (provider == null) {
        logger.errorv("\"{0}\" Spi is not available, did you forget to update the configuration?",
                X509ClientCertificateLookup.class);
        return;
    }

    X509Certificate[] certs = null;
    ClientModel client = null;
    try {
        certs = provider.getCertificateChain(context.getHttpRequest());
        String client_id = null;
        MediaType mediaType = context.getHttpRequest().getHttpHeaders().getMediaType();
        boolean hasFormData = mediaType != null && mediaType.isCompatible(MediaType.APPLICATION_FORM_URLENCODED_TYPE);

        MultivaluedMap<String, String> formData = hasFormData ? context.getHttpRequest().getDecodedFormParameters() : null;
        MultivaluedMap<String, String> queryParams = context.getSession().getContext().getUri().getQueryParameters();

        if (formData != null) {
            client_id = formData.getFirst(OAuth2Constants.CLIENT_ID);
        }

        if (client_id == null && queryParams != null) {
            client_id = queryParams.getFirst(OAuth2Constants.CLIENT_ID);
        }

        if (client_id == null) {
            client_id = context.getSession().getAttribute("client_id", String.class);
        }

        if (client_id == null) {
            Response challengeResponse = ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), "invalid_client", "Missing client_id parameter");
            context.challenge(challengeResponse);
            return;
        }

        client = context.getRealm().getClientByClientId(client_id);
        if (client == null) {
            context.failure(AuthenticationFlowError.CLIENT_NOT_FOUND, null);
            return;
        }
        context.getEvent().client(client_id);
        context.setClient(client);

        if (!client.isEnabled()) {
            context.failure(AuthenticationFlowError.CLIENT_DISABLED, null);
            return;
        }
    } catch (GeneralSecurityException e) {
        logger.errorf("[X509ClientCertificateAuthenticator:authenticate] Exception: %s", e.getMessage());
        context.attempted();
        return;
    }

    if (certs == null || certs.length == 0) {
        // No x509 client cert, fall through and
        // continue processing the rest of the authentication flow
        logger.debug("[X509ClientCertificateAuthenticator:authenticate] x509 client certificate is not available for mutual SSL.");
        context.attempted();
        return;
    }

    String subjectDNRegexp = client.getAttribute(ATTR_SUBJECT_DN);
    if (subjectDNRegexp == null || subjectDNRegexp.length() == 0) {
        logger.errorf("[X509ClientCertificateAuthenticator:authenticate] " + ATTR_SUBJECT_DN + " is null or empty");
        context.attempted();
        return;
    }
    Pattern subjectDNPattern = Pattern.compile(subjectDNRegexp);

    Optional<String> matchedCertificate = Arrays.stream(certs)
          .map(certificate -> certificate.getSubjectDN().getName())
          .filter(subjectdn -> subjectDNPattern.matcher(subjectdn).matches())
          .findFirst();

    if (!matchedCertificate.isPresent()) {
        // We do quite expensive operation here, so better check the logging level beforehand.
        if (logger.isDebugEnabled()) {
            logger.debug("[X509ClientCertificateAuthenticator:authenticate] Couldn't match any certificate for pattern " + subjectDNRegexp);
            logger.debug("[X509ClientCertificateAuthenticator:authenticate] Available SubjectDNs: " +
                  Arrays.stream(certs)
                        .map(cert -> cert.getSubjectDN().getName())
                        .collect(Collectors.toList()));
        }
        context.attempted();
        return;
    } else {
        logger.debug("[X509ClientCertificateAuthenticator:authenticate] Matched " + matchedCertificate.get() + " certificate.");
    }

    context.success();
}