Search in sources :

Example 1 with CredentialValidationOutput

use of org.keycloak.models.CredentialValidationOutput in project keycloak by keycloak.

the class LDAPStorageProvider method authenticate.

@Override
public CredentialValidationOutput authenticate(RealmModel realm, CredentialInput cred) {
    if (!(cred instanceof UserCredentialModel))
        CredentialValidationOutput.failed();
    UserCredentialModel credential = (UserCredentialModel) cred;
    if (credential.getType().equals(UserCredentialModel.KERBEROS)) {
        if (kerberosConfig.isAllowKerberosAuthentication()) {
            String spnegoToken = credential.getChallengeResponse();
            SPNEGOAuthenticator spnegoAuthenticator = factory.createSPNEGOAuthenticator(spnegoToken, kerberosConfig);
            spnegoAuthenticator.authenticate();
            Map<String, String> state = new HashMap<String, String>();
            if (spnegoAuthenticator.isAuthenticated()) {
                // TODO: This assumes that LDAP "uid" is equal to kerberos principal name. Like uid "hnelson" and kerberos principal "hnelson@KEYCLOAK.ORG".
                // Check if it's correct or if LDAP attribute for mapping kerberos principal should be available (For ApacheDS it seems to be attribute "krb5PrincipalName" but on MSAD it's likely different)
                String username = spnegoAuthenticator.getAuthenticatedUsername();
                UserModel user = findOrCreateAuthenticatedUser(realm, username);
                if (user == null) {
                    logger.warnf("Kerberos/SPNEGO authentication succeeded with username [%s], but couldn't find or create user with federation provider [%s]", username, model.getName());
                    return CredentialValidationOutput.failed();
                } else {
                    String delegationCredential = spnegoAuthenticator.getSerializedDelegationCredential();
                    if (delegationCredential != null) {
                        state.put(KerberosConstants.GSS_DELEGATION_CREDENTIAL, delegationCredential);
                    }
                    return new CredentialValidationOutput(user, CredentialValidationOutput.Status.AUTHENTICATED, state);
                }
            } else if (spnegoAuthenticator.getResponseToken() != null) {
                // Case when SPNEGO handshake requires multiple steps
                logger.tracef("SPNEGO Handshake will continue");
                state.put(KerberosConstants.RESPONSE_TOKEN, spnegoAuthenticator.getResponseToken());
                return new CredentialValidationOutput(null, CredentialValidationOutput.Status.CONTINUE, state);
            } else {
                logger.tracef("SPNEGO Handshake not successful");
                return CredentialValidationOutput.failed();
            }
        }
    }
    return CredentialValidationOutput.failed();
}
Also used : CachedUserModel(org.keycloak.models.cache.CachedUserModel) UserModel(org.keycloak.models.UserModel) CredentialValidationOutput(org.keycloak.models.CredentialValidationOutput) HashMap(java.util.HashMap) SPNEGOAuthenticator(org.keycloak.federation.kerberos.impl.SPNEGOAuthenticator) UserCredentialModel(org.keycloak.models.UserCredentialModel)

Example 2 with CredentialValidationOutput

use of org.keycloak.models.CredentialValidationOutput in project keycloak by keycloak.

the class SpnegoAuthenticator method authenticate.

@Override
public void authenticate(AuthenticationFlowContext context) {
    HttpRequest request = context.getHttpRequest();
    String authHeader = request.getHttpHeaders().getRequestHeaders().getFirst(HttpHeaders.AUTHORIZATION);
    if (authHeader == null) {
        Response challenge = challengeNegotiation(context, null);
        context.forceChallenge(challenge);
        return;
    }
    String[] tokens = authHeader.split(" ");
    if (tokens.length == 0) {
        // assume not supported
        logger.debug("Invalid length of tokens: " + tokens.length);
        context.attempted();
        return;
    }
    if (!KerberosConstants.NEGOTIATE.equalsIgnoreCase(tokens[0])) {
        logger.debug("Unknown scheme " + tokens[0]);
        context.attempted();
        return;
    }
    if (tokens.length != 2) {
        context.failure(AuthenticationFlowError.INVALID_CREDENTIALS);
        return;
    }
    String spnegoToken = tokens[1];
    UserCredentialModel spnegoCredential = UserCredentialModel.kerberos(spnegoToken);
    CredentialValidationOutput output = context.getSession().userCredentialManager().authenticate(context.getSession(), context.getRealm(), spnegoCredential);
    if (output == null) {
        logger.warn("Received kerberos token, but there is no user storage provider that handles kerberos credentials.");
        context.attempted();
        return;
    }
    if (output.getAuthStatus() == CredentialValidationOutput.Status.AUTHENTICATED) {
        context.setUser(output.getAuthenticatedUser());
        if (output.getState() != null && !output.getState().isEmpty()) {
            for (Map.Entry<String, String> entry : output.getState().entrySet()) {
                context.getAuthenticationSession().setUserSessionNote(entry.getKey(), entry.getValue());
            }
        }
        context.success();
    } else if (output.getAuthStatus() == CredentialValidationOutput.Status.CONTINUE) {
        String spnegoResponseToken = (String) output.getState().get(KerberosConstants.RESPONSE_TOKEN);
        Response challenge = challengeNegotiation(context, spnegoResponseToken);
        context.challenge(challenge);
    } else {
        context.getEvent().error(Errors.INVALID_USER_CREDENTIALS);
        context.failure(AuthenticationFlowError.INVALID_CREDENTIALS);
    }
}
Also used : HttpRequest(org.jboss.resteasy.spi.HttpRequest) Response(javax.ws.rs.core.Response) CredentialValidationOutput(org.keycloak.models.CredentialValidationOutput) UserCredentialModel(org.keycloak.models.UserCredentialModel) Map(java.util.Map)

Example 3 with CredentialValidationOutput

use of org.keycloak.models.CredentialValidationOutput in project keycloak by keycloak.

the class KerberosFederationProvider method authenticate.

@Override
public CredentialValidationOutput authenticate(RealmModel realm, CredentialInput input) {
    if (!(input instanceof UserCredentialModel))
        return null;
    UserCredentialModel credential = (UserCredentialModel) input;
    if (credential.getType().equals(UserCredentialModel.KERBEROS)) {
        String spnegoToken = credential.getChallengeResponse();
        SPNEGOAuthenticator spnegoAuthenticator = factory.createSPNEGOAuthenticator(spnegoToken, kerberosConfig);
        spnegoAuthenticator.authenticate();
        Map<String, String> state = new HashMap<String, String>();
        if (spnegoAuthenticator.isAuthenticated()) {
            String username = spnegoAuthenticator.getAuthenticatedUsername();
            UserModel user = findOrCreateAuthenticatedUser(realm, username);
            if (user == null) {
                return CredentialValidationOutput.failed();
            } else {
                String delegationCredential = spnegoAuthenticator.getSerializedDelegationCredential();
                if (delegationCredential != null) {
                    state.put(KerberosConstants.GSS_DELEGATION_CREDENTIAL, delegationCredential);
                }
                return new CredentialValidationOutput(user, CredentialValidationOutput.Status.AUTHENTICATED, state);
            }
        } else if (spnegoAuthenticator.getResponseToken() != null) {
            // Case when SPNEGO handshake requires multiple steps
            logger.tracef("SPNEGO Handshake will continue");
            state.put(KerberosConstants.RESPONSE_TOKEN, spnegoAuthenticator.getResponseToken());
            return new CredentialValidationOutput(null, CredentialValidationOutput.Status.CONTINUE, state);
        } else {
            logger.tracef("SPNEGO Handshake not successful");
            return CredentialValidationOutput.failed();
        }
    } else {
        return null;
    }
}
Also used : UserModel(org.keycloak.models.UserModel) CredentialValidationOutput(org.keycloak.models.CredentialValidationOutput) HashMap(java.util.HashMap) SPNEGOAuthenticator(org.keycloak.federation.kerberos.impl.SPNEGOAuthenticator) UserCredentialModel(org.keycloak.models.UserCredentialModel)

Aggregations

CredentialValidationOutput (org.keycloak.models.CredentialValidationOutput)3 UserCredentialModel (org.keycloak.models.UserCredentialModel)3 HashMap (java.util.HashMap)2 SPNEGOAuthenticator (org.keycloak.federation.kerberos.impl.SPNEGOAuthenticator)2 UserModel (org.keycloak.models.UserModel)2 Map (java.util.Map)1 Response (javax.ws.rs.core.Response)1 HttpRequest (org.jboss.resteasy.spi.HttpRequest)1 CachedUserModel (org.keycloak.models.cache.CachedUserModel)1