All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.unicon.cas.mfa.AbstractMultiFactorAuthenticationProtocolValidationSpecification Maven / Gradle / Ivy

Go to download

This module is intended to include all the Java you need to add to a CAS implementation to take advantage of the extended multifactor authentication features in this project.

There is a newer version: 2.0.0-RC3
Show newest version
package net.unicon.cas.mfa;

import net.unicon.cas.mfa.ticket.UnacceptableMultiFactorAuthenticationMethodException;
import net.unicon.cas.mfa.ticket.UnrecognizedMultiFactorAuthenticationMethodException;
import net.unicon.cas.mfa.util.MultiFactorUtils;
import org.apache.commons.lang.StringUtils;
import org.jasig.cas.authentication.Authentication;
import org.jasig.cas.validation.Assertion;
import org.jasig.cas.validation.Cas20ProtocolValidationSpecification;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Set;

/**
 * Validate the requested protocol spec, primarily based on the requested authentication method.
 * @author Misagh Moayyed
 * @see net.unicon.cas.mfa.web.MultiFactorServiceValidateController
 */
public abstract class AbstractMultiFactorAuthenticationProtocolValidationSpecification extends Cas20ProtocolValidationSpecification {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private String authenticationMethod = null;

    private boolean validateProxyAuthenticationRequests = false;

    /**
     * Constructor to spin up the validation spec instance.
     * No restrictions on the requested authentication method.
     *
     * @param validateProxyAuthenticationRequests flag
     */
    public AbstractMultiFactorAuthenticationProtocolValidationSpecification(final boolean validateProxyAuthenticationRequests) {
        super();
        this.validateProxyAuthenticationRequests = validateProxyAuthenticationRequests;
    }

    /**
     * Constructor to spin up the validation spec instance, requiring a particular
     * authentication method.
     * @param authnMethod required authentication method to match against.
     */
    public AbstractMultiFactorAuthenticationProtocolValidationSpecification(final String authnMethod) {
        this.authenticationMethod = authnMethod;
    }

    public final void setAuthenticationMethod(final String authnMethod) {
        this.authenticationMethod = authnMethod;
    }

    public final String getAuthenticationMethod() {
        return this.authenticationMethod;
    }

    /**
     * {@inheritDoc}
     * 

Validate the requested authentication method for this validation request. * If the produced assertion cannot satisfy the authentication method requested, * an instance of {@link UnacceptableMultiFactorAuthenticationMethodException} will be thrown. * If the authentication method used by the assertion is not blank, but does not match * the requested authentication method, an instance of {@link UnrecognizedMultiFactorAuthenticationMethodException} * will be thrown. * *

Note: The current {@link #isSatisfiedByInternal(Assertion)} method signature * only allows for returning of a boolean value indicating whether the assertion * can satisfy the requested protocol. This is not sufficient to fully explain the context * of a validation failure, as in the case of multifactor authentication, whether * the authentication method is unrecognized or unacceptable. In order to accommodate this, * and rather than changing the method signature to return more than just a boolean, the * implementation opts to throwing specific exceptions in order to indicate the context * of the failure. Exceptions are unchecked, yet are expected to be caught by the caller * in order to digest the failure. * * @see UnacceptableMultiFactorAuthenticationMethodException * @see UnrecognizedMultiFactorAuthenticationMethodException */ @Override protected final boolean isSatisfiedByInternal(final Assertion assertion) { final Authentication authentication = MultiFactorUtils.getAuthenticationFromAssertion(assertion); if (authentication != null) { final Set previouslyAchievedAuthenticationMethods = MultiFactorUtils.getSatisfiedAuthenticationMethods(authentication); if (!StringUtils.isBlank(getAuthenticationMethod())) { if (previouslyAchievedAuthenticationMethods.size() == 0) { final String msg = String.format("Requested authentication method [%s] is not available", getAuthenticationMethod()); logger.debug(msg); throw new UnacceptableMultiFactorAuthenticationMethodException("UNACCEPTABLE_AUTHENTICATION_METHOD", msg, getAuthenticationMethod()); } if (!previouslyAchievedAuthenticationMethods.contains(getAuthenticationMethod())) { final String msg = String.format("Requested authentication method [%s] does not " + "match the authentication method used [%s]", getAuthenticationMethod(), previouslyAchievedAuthenticationMethods); logger.debug(msg); throw new UnrecognizedMultiFactorAuthenticationMethodException("UNRECOGNIZED_AUTHENTICATION_METHOD", msg, getAuthenticationMethod()); } } return validateProxyAuthenticationRequests ? true : assertion.getChainedAuthentications().size() == 1; } logger.debug("No authentication context is available"); return false; } /** * An MFA validator that handles proxy authentications. */ public static final class WithProxy extends AbstractMultiFactorAuthenticationProtocolValidationSpecification { /** * Instantiates a new with proxy spec. */ public WithProxy() { super(true); } } /** * An MFA validator that does not handles proxy authentications. */ public static final class WithoutProxy extends AbstractMultiFactorAuthenticationProtocolValidationSpecification { /** * Instantiates a new without proxy spec. */ public WithoutProxy() { super(false); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy