├── maven
├── maven-wrapper.jar
└── maven-wrapper.properties
├── cas-mfa-overlay
├── etc
│ ├── authn-methods.conf
│ ├── jetty
│ │ ├── web.xml
│ │ ├── jetty-https.xml
│ │ └── jetty-ssl.xml
│ ├── cas.properties
│ └── log4j2.xml
├── maven
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── src
│ └── main
│ │ └── webapp
│ │ └── WEB-INF
│ │ ├── spring-configuration
│ │ └── propertyFileConfigurer.xml
│ │ ├── classes
│ │ └── services
│ │ │ └── HTTPSandIMAPS-10000001.json
│ │ └── deployerConfigContext.xml
└── pom.xml
├── cas-mfa-duo
├── maven
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── src
│ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── duosecurity
│ │ │ ├── DuoWebException.java
│ │ │ ├── Util.java
│ │ │ └── DuoWeb.java
│ │ └── groovy
│ │ └── net
│ │ └── unicon
│ │ └── cas
│ │ └── mfa
│ │ └── authentication
│ │ └── duo
│ │ ├── DuoAuthenticationService.groovy
│ │ ├── DuoMultiFactorWebflowConfigurer.java
│ │ ├── DuoCredentials.groovy
│ │ └── DuoAuthenticationHandler.groovy
└── pom.xml
├── cas-mfa-java
├── maven
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── src
│ ├── main
│ │ ├── java
│ │ │ └── net
│ │ │ │ └── unicon
│ │ │ │ └── cas
│ │ │ │ └── mfa
│ │ │ │ ├── authentication
│ │ │ │ ├── CompositeAuthentication.java
│ │ │ │ ├── AuthenticationMethodConfigurationProvider.java
│ │ │ │ ├── AuthenticationMethodTranslator.java
│ │ │ │ ├── DefaultAuthenticationMethodConfigurationProvider.java
│ │ │ │ ├── RegisteredServiceMfaRoleProcessor.java
│ │ │ │ ├── principal
│ │ │ │ │ └── UnknownPrincipalMatchException.java
│ │ │ │ ├── MultiFactorAuthenticationRequestResolver.java
│ │ │ │ ├── RequestedAuthenticationMethodRankingStrategy.java
│ │ │ │ ├── DefaultAuthenticationSupport.java
│ │ │ │ ├── StubAuthenticationMethodTranslator.java
│ │ │ │ ├── CasMultiFactorApplicationContextAware.java
│ │ │ │ ├── AuthenticationSupport.java
│ │ │ │ ├── RegexAuthenticationMethodTranslator.java
│ │ │ │ ├── RememberAuthenticationMethodMetaDataPopulator.java
│ │ │ │ ├── AuthenticationMethod.java
│ │ │ │ ├── DefaultCompositeAuthentication.java
│ │ │ │ ├── JsonBackedAuthenticationMethodConfigurationProvider.java
│ │ │ │ ├── MultiFactorAuthenticationRequestContext.java
│ │ │ │ ├── OrderedMultiFactorMethodRankingStrategy.java
│ │ │ │ └── MultiFactorAuthenticationTransactionContext.java
│ │ │ │ ├── web
│ │ │ │ ├── flow
│ │ │ │ │ ├── view
│ │ │ │ │ │ ├── MultiFactorLoginViewPrincipalGreeter.java
│ │ │ │ │ │ └── MultifactorLoginViewPrincipalAttributeGreeter.java
│ │ │ │ │ ├── event
│ │ │ │ │ │ ├── ErroringMultiFactorAuthenticationSpringWebflowEventBuilder.java
│ │ │ │ │ │ ├── MultiFactorAuthenticationSpringWebflowEventBuilder.java
│ │ │ │ │ │ └── ServiceAuthenticationMethodMultiFactorAuthenticationSpringWebflowEventBuilder.java
│ │ │ │ │ ├── ConfigurableSpringWebflowExceptionHandler.java
│ │ │ │ │ ├── NoAuthenticationContextAvailable.java
│ │ │ │ │ ├── RemoveHostnameInContextAction.java
│ │ │ │ │ ├── SendTicketGrantingTicketAction.java
│ │ │ │ │ └── TerminatingMultiFactorAuthenticationViaFormAction.java
│ │ │ │ ├── support
│ │ │ │ │ ├── AuthenticationMethodVerifier.java
│ │ │ │ │ ├── UnrecognizedAuthenticationMethodException.java
│ │ │ │ │ ├── MultiFactorWebApplicationServiceFactory.java
│ │ │ │ │ ├── DefaultMultiFactorWebApplicationServiceFactory.java
│ │ │ │ │ ├── MultiFactorAuthenticationSupportingWebApplicationService.java
│ │ │ │ │ ├── RequestParameterMultiFactorAuthenticationArgumentExtractor.java
│ │ │ │ │ ├── DefaultAuthenticationMethodVerifier.java
│ │ │ │ │ └── MultiFactorAuthenticationRequestsCollectingArgumentExtractor.java
│ │ │ │ └── view
│ │ │ │ │ └── Cas30ResponseView.java
│ │ │ │ ├── ticket
│ │ │ │ ├── UnacceptableMultiFactorAuthenticationMethodException.java
│ │ │ │ ├── UnrecognizedMultiFactorAuthenticationMethodException.java
│ │ │ │ └── MultiFactorAuthenticationBaseTicketValidationException.java
│ │ │ │ └── util
│ │ │ │ └── MultiFactorUtils.java
│ │ └── resources
│ │ │ └── META-INF
│ │ │ └── spring
│ │ │ └── mfa-context.xml
│ └── test
│ │ ├── resources
│ │ └── log4j.xml
│ │ ├── java
│ │ └── net
│ │ │ └── unicon
│ │ │ └── cas
│ │ │ └── mfa
│ │ │ ├── web
│ │ │ └── support
│ │ │ │ └── DefaultMultiFactorAuthenticationSupportingWebApplicationServiceTests.java
│ │ │ ├── util
│ │ │ └── MultiFactorUtilsTests.java
│ │ │ ├── authentication
│ │ │ ├── DefaultCompositeAuthenticationTests.java
│ │ │ ├── RegexAuthenticationMethodTranslatorTests.java
│ │ │ └── principal
│ │ │ │ └── MultiFactorCredentialsTests.java
│ │ │ └── MultiFactorAuthenticationProtocolValidationSpecificationTests.java
│ │ └── groovy
│ │ └── net
│ │ └── unicon
│ │ └── cas
│ │ └── mfa
│ │ └── authentication
│ │ ├── OrderedMfaMethodRankingStrategyTests.groovy
│ │ ├── MultiFactorAuthenticationTransactionContextTests.groovy
│ │ └── principal
│ │ └── PrincipalAttributeMultiFactorAuthenticationRequestResolverTests.groovy
├── README.md
└── pom.xml
├── cas-mfa-web
├── maven
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── README.md
├── src
│ ├── main
│ │ └── webapp
│ │ │ └── WEB-INF
│ │ │ ├── spring-configuration
│ │ │ ├── common-context.xml
│ │ │ ├── mfaArgumentExtractorsConfiguration.xml
│ │ │ └── uniqueIdGenerators.xml
│ │ │ └── view
│ │ │ └── jsp
│ │ │ └── default
│ │ │ └── ui
│ │ │ ├── casUnknownPrincipalErrorView.jsp
│ │ │ └── casMfaUnrecognizedAuthnMethodErrorView.jsp
│ └── test
│ │ └── java
│ │ └── net
│ │ └── unicon
│ │ └── cas
│ │ └── mfa
│ │ └── web
│ │ └── flow
│ │ └── view
│ │ └── MultifactorLoginViewPrincipalAttributeGreeterTests.java
└── pom.xml
├── cas-mfa-duo-web
├── maven
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── pom.xml
└── src
│ └── main
│ └── webapp
│ ├── WEB-INF
│ ├── view
│ │ └── jsp
│ │ │ └── default
│ │ │ └── ui
│ │ │ └── casDuoLoginView.jsp
│ ├── cas-servlet-mfa-duo-two-factor.xml
│ └── webflow
│ │ └── mfa-duo-two-factor
│ │ └── mfa-duo-two-factor-webflow.xml
│ └── js
│ └── duo
│ └── Duo-Web-v2.min.js
├── .gitignore
├── travis
├── init-travis-build.sh
├── deploy-to-sonatype.sh
└── settings.xml
├── .travis.yml
├── NOTICE.txt
└── checkstyle-suppressions.xml
/maven/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unicon/cas-mfa/HEAD/maven/maven-wrapper.jar
--------------------------------------------------------------------------------
/cas-mfa-overlay/etc/authn-methods.conf:
--------------------------------------------------------------------------------
1 | [ {
2 | "rank" : 1,
3 | "name" : "duo-two-factor"
4 | } ]
5 |
--------------------------------------------------------------------------------
/cas-mfa-duo/maven/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unicon/cas-mfa/HEAD/cas-mfa-duo/maven/maven-wrapper.jar
--------------------------------------------------------------------------------
/cas-mfa-java/maven/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unicon/cas-mfa/HEAD/cas-mfa-java/maven/maven-wrapper.jar
--------------------------------------------------------------------------------
/cas-mfa-web/maven/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unicon/cas-mfa/HEAD/cas-mfa-web/maven/maven-wrapper.jar
--------------------------------------------------------------------------------
/cas-mfa-duo-web/maven/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unicon/cas-mfa/HEAD/cas-mfa-duo-web/maven/maven-wrapper.jar
--------------------------------------------------------------------------------
/cas-mfa-overlay/maven/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Unicon/cas-mfa/HEAD/cas-mfa-overlay/maven/maven-wrapper.jar
--------------------------------------------------------------------------------
/maven/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Maven download properties
2 | #Tue Dec 01 19:58:21 MST 2015
3 | distributionUrl=https\://repository.apache.org/content/repositories/releases/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
4 |
--------------------------------------------------------------------------------
/cas-mfa-duo/maven/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Maven download properties
2 | #Tue Dec 01 19:58:21 MST 2015
3 | distributionUrl=https\://repository.apache.org/content/repositories/releases/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
4 |
--------------------------------------------------------------------------------
/cas-mfa-java/maven/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Maven download properties
2 | #Tue Dec 01 19:58:21 MST 2015
3 | distributionUrl=https\://repository.apache.org/content/repositories/releases/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
4 |
--------------------------------------------------------------------------------
/cas-mfa-web/maven/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Maven download properties
2 | #Tue Dec 01 19:58:21 MST 2015
3 | distributionUrl=https\://repository.apache.org/content/repositories/releases/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
4 |
--------------------------------------------------------------------------------
/cas-mfa-duo-web/maven/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Maven download properties
2 | #Tue Dec 01 19:58:21 MST 2015
3 | distributionUrl=https\://repository.apache.org/content/repositories/releases/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
4 |
--------------------------------------------------------------------------------
/cas-mfa-overlay/maven/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Maven download properties
2 | #Tue Dec 01 19:58:21 MST 2015
3 | distributionUrl=https\://repository.apache.org/content/repositories/releases/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | !/.project
3 | .project
4 | .settings
5 | target
6 | test-output/
7 | bin/
8 | *.ipr
9 | *.iml
10 | *.iws
11 | .idea/
12 | .DS_Store
13 | .idea
14 | overlays/
15 | pom.xml.versionsBackup
16 | *.log
17 |
18 | **/.checkstyle
19 | **/rebel.xml
20 |
--------------------------------------------------------------------------------
/cas-mfa-overlay/etc/jetty/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/cas-mfa-web/README.md:
--------------------------------------------------------------------------------
1 | # Readme for cas-mfa-web
2 |
3 | ## What is this
4 |
5 | This is the multifactor extensions for CAS sub-module for Web components. Things that are not Java, that do not build into a .jar.
6 |
7 | For example: JSPs, deployment descriptors, customized and new Spring Web Flow XML and other Spring web framework configuration, etc.
8 |
9 | These components depend on the Java in the .jar built by the parallel `cas-mfa-java` module.
10 |
11 | ## How do I build this
12 |
13 | *Good question*. To be defined and documented.
14 |
--------------------------------------------------------------------------------
/cas-mfa-duo/src/main/java/com/duosecurity/DuoWebException.java:
--------------------------------------------------------------------------------
1 | package com.duosecurity;
2 |
3 | /**
4 | * Duo security integration code copied from: https://github.com/duosecurity/duo_java .
5 | * @author Duo Security
6 | */
7 | public class DuoWebException extends Exception {
8 |
9 | private static final long serialVersionUID = 451949380095167112L;
10 |
11 | /**
12 | * Instantiates a new Duo web exception.
13 | *
14 | * @param message the message
15 | */
16 | public DuoWebException(final String message) {
17 | super(message);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/travis/init-travis-build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo -e "Building branch: ${TRAVIS_BRANCH}"
4 | echo -e "Build directory: ${TRAVIS_BUILD_DIR}"
5 | echo -e "Build id: ${TRAVIS_BUILD_ID}"
6 | echo -e "Builder number: ${TRAVIS_BUILD_NUMBER}"
7 | echo -e "Job id: ${TRAVIS_JOB_ID}"
8 | echo -e "Job number: ${TRAVIS_JOB_NUMBER}"
9 | echo -e "Repo slug: ${TRAVIS_REPO_SLUG}"
10 | echo -e "OS name: ${TRAVIS_OS_NAME}"
11 |
12 | if [ "$TRAVIS_SECURE_ENV_VARS" == "false" ]
13 | then
14 | echo -e "Secure environment variables are NOT available...\n"
15 | else
16 | echo -e "Secure environment variables are available...\n"
17 | fi
18 |
--------------------------------------------------------------------------------
/travis/deploy-to-sonatype.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo -e "Evaluating change before pushing to Sonatype..."
4 |
5 | # Only invoke the deployment to Sonatype when it's not a PR and only for master
6 | if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
7 | echo -e "Starting to deploy to Sonatype..."
8 | mvn deploy --settings ./travis/settings.xml
9 | echo -e "Successfully deployed SNAPSHOT artifacts to Sonatype under Travis job ${TRAVIS_JOB_NUMBER}"
10 | else
11 | echo -e "Skipped Sonatype deployment. This is either a pull request or a change on a different branch other than master"
12 | fi
13 | echo -e "Fnished deploying to Sonatype."
14 |
--------------------------------------------------------------------------------
/travis/settings.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | sonatype-nexus-snapshots
13 | ${SONATYPE_USER}
14 | ${SONATYPE_PWD}
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/authentication/CompositeAuthentication.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.authentication;
2 |
3 | import java.util.Set;
4 |
5 | import org.jasig.cas.authentication.Authentication;
6 |
7 | /**
8 | * A composite authentication that specifically is able to collect
9 | * authentication methods fulfilled in the chain.
10 | * @author Misagh Moayyed
11 | */
12 | public interface CompositeAuthentication extends Authentication {
13 |
14 | /**
15 | * Retrieves the collection of authentication methods available in the list
16 | * of authentication attributes.
17 | * @return collection of authentication methods
18 | */
19 | Set getSatisfiedAuthenticationMethods();
20 | }
21 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | sudo: false
3 | env:
4 | global:
5 | - secure: HGkZ6LlYQDmC3ppP8UAOY6TmfddLZ5bt6UTdrh2SG3FDgBpA7L6tGyq4JyKco5OKO7N6oFcrbmYIAY2thEDxCrtcOGCvLhkxYv6uxqKt32Yeknosk5F4/JNHCu/bEFIoyIyz/RzW5QvoF27kTb7BZ3fdjPbU39k9V1rYIU6/Oqw=
6 | - secure: FuhW99CpzFj/iPR9dgLhhkw6UFJltWb2HDLLXGMmLb/OKMAQjenV+yAIao5v5KaD6LTZqFe4Ugi+XIzepCSBFayJFsdLDNYb8Bp/bINaq9t3kmsSXE0e3LUGs8wO6rgHgmVv6WpscTjSt7uvZsiuKwYzaSnivcXTEfMxF72Q8mw=
7 | branches:
8 | only:
9 | - master
10 | before_install:
11 | - chmod -R 777 ./travis/init-travis-build.sh
12 | - ./travis/init-travis-build.sh
13 | install:
14 | - mvn -T 10 install -Dmaven.javadoc.skip=true -B -V
15 | script:
16 | - mvn clean package -q
17 | after_success:
18 | - chmod -R 777 ./travis/deploy-to-sonatype.sh
19 | - ./travis/deploy-to-sonatype.sh
20 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/test/resources/log4j.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/web/flow/view/MultiFactorLoginViewPrincipalGreeter.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.web.flow.view;
2 |
3 | import org.jasig.cas.authentication.principal.Principal;
4 | import org.springframework.binding.message.MessageContext;
5 |
6 | /**
7 | * Defines an abstraction by which principals can be greeted in the view.
8 | * @author Misagh Moayyed
9 | */
10 | public interface MultiFactorLoginViewPrincipalGreeter {
11 | /**
12 | * Return the identifier that is to used to greet the credentials
13 | * in the view.
14 | * @param p the principal we are trying to welcome to the view.
15 | * @param messageContext context to resolve the message code associated with the greeting
16 | * @return the greetee
17 | */
18 | String getPersonToGreet(Principal p, MessageContext messageContext);
19 | }
20 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/authentication/AuthenticationMethodConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.authentication;
2 |
3 | /**
4 | * Defines where authentication methods come from, which are
5 | * supported and how they are loaded into the application context.
6 | * @author Misagh Moayyed
7 | */
8 | public interface AuthenticationMethodConfigurationProvider {
9 | /**
10 | * Contains authentication method.
11 | *
12 | * @param name the name
13 | * @return true if the method is found
14 | */
15 | boolean containsAuthenticationMethod(String name);
16 |
17 | /**
18 | * Gets authentication method.
19 | *
20 | * @param name the name
21 | * @return the authentication method, or null if none is found.
22 | */
23 | AuthenticationMethod getAuthenticationMethod(String name);
24 | }
25 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/resources/META-INF/spring/mfa-context.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
--------------------------------------------------------------------------------
/cas-mfa-overlay/src/main/webapp/WEB-INF/spring-configuration/propertyFileConfigurer.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/cas-mfa-duo/src/main/java/com/duosecurity/Util.java:
--------------------------------------------------------------------------------
1 | package com.duosecurity;
2 |
3 | import java.security.InvalidKeyException;
4 | import java.security.NoSuchAlgorithmException;
5 |
6 | import javax.crypto.Mac;
7 | import javax.crypto.spec.SecretKeySpec;
8 |
9 | public class Util {
10 |
11 | private Util() {}
12 |
13 | public static String hmacSign(final String skey, final String data)
14 | throws NoSuchAlgorithmException, InvalidKeyException {
15 | final SecretKeySpec key = new SecretKeySpec(skey.getBytes(), "HmacSHA1");
16 | final Mac mac = Mac.getInstance("HmacSHA1");
17 | mac.init(key);
18 | final byte[] raw = mac.doFinal(data.getBytes());
19 | return bytesToHex(raw);
20 | }
21 |
22 | public static String bytesToHex(final byte[] b) {
23 | String result = "";
24 | for (int i = 0; i < b.length; i++) {
25 | result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
26 | }
27 | return result;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/web/support/AuthenticationMethodVerifier.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.web.support;
2 |
3 | import org.jasig.cas.authentication.principal.WebApplicationService;
4 |
5 | import javax.servlet.http.HttpServletRequest;
6 |
7 | /**
8 | * Strategy interface for verifying requested mfa authentication methods.
9 | *
10 | * @author Dmitriy Kopylenko
11 | * @author Unicon inc.
12 | */
13 | public interface AuthenticationMethodVerifier {
14 |
15 | /**
16 | * Verify requested mfa authentication method.
17 | *
18 | * @param authenticationMethod requested authentication method
19 | * @param targetService targetService
20 | * @param request Http request
21 | * @return true if the authn method is supported and verified
22 | */
23 | boolean verifyAuthenticationMethod(String authenticationMethod, WebApplicationService targetService, HttpServletRequest request);
24 | }
25 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/web/flow/event/ErroringMultiFactorAuthenticationSpringWebflowEventBuilder.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.web.flow.event;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.webflow.execution.Event;
6 | import org.springframework.webflow.execution.RequestContext;
7 |
8 | /**
9 | * Builds the error event on MFA ops.
10 | * @author Misagh Moayyed
11 | */
12 | public class ErroringMultiFactorAuthenticationSpringWebflowEventBuilder
13 | implements MultiFactorAuthenticationSpringWebflowEventBuilder {
14 |
15 | private final Logger logger = LoggerFactory.getLogger(getClass());
16 |
17 | /**
18 | * The Constant MFA_ERROR_EVENT_ID.
19 | */
20 | public static final String MFA_ERROR_EVENT_ID = "error";
21 |
22 | @Override
23 | public Event buildEvent(final RequestContext context) {
24 | logger.debug("Building event id {}", MFA_ERROR_EVENT_ID);
25 | return new Event(this, MFA_ERROR_EVENT_ID);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/web/flow/ConfigurableSpringWebflowExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.web.flow;
2 |
3 | import org.springframework.webflow.engine.support.TransitionExecutingFlowExecutionExceptionHandler;
4 |
5 | /**
6 | * A extension of {@link TransitionExecutingFlowExecutionExceptionHandler} that exposes configuration
7 | * for convenience directly via a constructor, such that handlers can be configured via explicit spring beans.
8 | * @author Misagh Moayyed
9 | */
10 | public final class ConfigurableSpringWebflowExceptionHandler extends TransitionExecutingFlowExecutionExceptionHandler {
11 |
12 | /**
13 | * Initialize the handler with the exception class to handle, and the state to which the flow must move.
14 | * @param exceptionClass exception class to handle
15 | * @param state state to which the flow moves.
16 | */
17 | public ConfigurableSpringWebflowExceptionHandler(final Class exceptionClass, final String state) {
18 | super();
19 | add(exceptionClass, state);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/cas-mfa-web/src/main/webapp/WEB-INF/spring-configuration/common-context.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
11 |
12 |
18 |
19 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/ticket/UnacceptableMultiFactorAuthenticationMethodException.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.ticket;
2 |
3 | /**
4 | * Multifactor authentication exception that is thrown
5 | * when the request authentication method cannot be accepted/provided
6 | * by this CAS server.
7 | * @author Misagh Moayyed
8 | * @see net.unicon.cas.mfa.AbstractMultiFactorAuthenticationProtocolValidationSpecification
9 | */
10 | public class UnacceptableMultiFactorAuthenticationMethodException extends MultiFactorAuthenticationBaseTicketValidationException {
11 |
12 | private static final long serialVersionUID = -8544747236126342213L;
13 |
14 | /**
15 | * Constructor to spin up the exception instance.
16 | * @param code error code
17 | * @param msg error message
18 | * @param authnMethod authentication method associated with the error
19 | */
20 | public UnacceptableMultiFactorAuthenticationMethodException(final String code, final String msg, final String authnMethod) {
21 | super(code, msg, authnMethod);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/ticket/UnrecognizedMultiFactorAuthenticationMethodException.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.ticket;
2 |
3 | /**
4 | * Multifactor authentication exception that is thrown
5 | * when the requested authentication method cannot be accepted
6 | * or isn't support by this CAS server.
7 | * @author Misagh Moayyed
8 | * @see net.unicon.cas.mfa.AbstractMultiFactorAuthenticationProtocolValidationSpecification
9 | */
10 | public class UnrecognizedMultiFactorAuthenticationMethodException extends MultiFactorAuthenticationBaseTicketValidationException {
11 |
12 | private static final long serialVersionUID = -8544747236126342213L;
13 |
14 | /**
15 | * Constructor to spin up the exception instance.
16 | * @param code error code
17 | * @param msg error message
18 | * @param authnMethod authentication method associated with the error
19 | */
20 | public UnrecognizedMultiFactorAuthenticationMethodException(final String code, final String msg, final String authnMethod) {
21 | super(code, msg, authnMethod);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/web/flow/event/MultiFactorAuthenticationSpringWebflowEventBuilder.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.web.flow.event;
2 |
3 | import org.springframework.webflow.execution.Event;
4 | import org.springframework.webflow.execution.RequestContext;
5 |
6 | /**
7 | * Describes the necessary mechanics for building multifactor event ids
8 | * for spring webflow from one transition to another.
9 | * @author Misagh Moayyed
10 | */
11 | public interface MultiFactorAuthenticationSpringWebflowEventBuilder {
12 |
13 | /**
14 | * The Constant MFA_EVENT_ID_PREFIX.
15 | */
16 | String MFA_EVENT_ID_PREFIX = "mfa-";
17 |
18 | /**
19 | * Builds the MFA event required for the next transition to occur.
20 | *
21 | * @param context the context
22 | * @return the event
23 | * @throws java.lang.IllegalStateException if no matching transitions exists
24 | * for this particular event. Implementations may want to check the request context
25 | * for the validity of the configured event before passing it on.
26 | */
27 | Event buildEvent(RequestContext context);
28 | }
29 |
--------------------------------------------------------------------------------
/cas-mfa-duo/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | cas-mfa
5 | net.unicon
6 | 2.0.0-RC4-SNAPSHOT
7 |
8 | 4.0.0
9 | cas-mfa-duo
10 | CAS MFA Duo
11 |
12 | Module containing Duo security support code as well as CAS' authentication subsystem code
13 | built on top of Duo.
14 |
15 | jar
16 |
17 |
18 |
19 | org.jasig.cas
20 | cas-server-core
21 |
22 |
23 |
24 | org.codehaus.groovy
25 | groovy
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/authentication/AuthenticationMethodTranslator.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.authentication;
2 |
3 | import org.jasig.cas.authentication.principal.WebApplicationService;
4 |
5 | /**
6 | * Defines operations that are to translate a received/retrieved authentication method
7 | * into one that CAS can recognize. This is useful in cases where principal attributes
8 | * have defined arbitrary names for the MFA trigger, or that service providers are unable
9 | * to change submitted parameter names in the request to trigger MFA.
10 | * @author Misagh Moayyed
11 | */
12 | public interface AuthenticationMethodTranslator {
13 | /**
14 | * Translate an authentication method to one that CAS can recognize.
15 | * Implementations may choose to decide what should happen if no mapping
16 | * is found between the source and target authentication methods.
17 | * @param targetService the target service
18 | * @param receivedAuthenticationMethod the received authentication method
19 | * @return the translated method name
20 | */
21 | String translate(WebApplicationService targetService, String receivedAuthenticationMethod);
22 | }
23 |
--------------------------------------------------------------------------------
/cas-mfa-overlay/src/main/webapp/WEB-INF/classes/services/HTTPSandIMAPS-10000001.json:
--------------------------------------------------------------------------------
1 | {
2 | "@class" : "org.jasig.cas.services.RegexRegisteredService",
3 | "serviceId" : "^(https|imaps)://.*",
4 | "name" : "HTTPS and IMAPS",
5 | "id" : 10000001,
6 | "description" : "This service definition authorized all application urls that support HTTPS and IMAPS protocols.",
7 | "proxyPolicy" : {
8 | "@class" : "org.jasig.cas.services.RefuseRegisteredServiceProxyPolicy"
9 | },
10 | "evaluationOrder" : 0,
11 | "usernameAttributeProvider" : {
12 | "@class" : "org.jasig.cas.services.DefaultRegisteredServiceUsernameProvider"
13 | },
14 | "logoutType" : "BACK_CHANNEL",
15 | "attributeReleasePolicy" : {
16 | "@class" : "org.jasig.cas.services.ReturnAllowedAttributeReleasePolicy",
17 | "principalAttributesRepository" : {
18 | "@class" : "org.jasig.cas.authentication.principal.DefaultPrincipalAttributesRepository"
19 | },
20 | "authorizedToReleaseCredentialPassword" : false,
21 | "authorizedToReleaseProxyGrantingTicket" : false
22 | },
23 | "accessStrategy" : {
24 | "@class" : "org.jasig.cas.services.DefaultRegisteredServiceAccessStrategy",
25 | "enabled" : true,
26 | "ssoEnabled" : true
27 | }
28 | }
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/web/flow/NoAuthenticationContextAvailable.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.web.flow;
2 |
3 | /**
4 | * In the event that a left-over TGT exists from previous session, from which
5 | * an authentication context cannot be established, again, because the TGT is considered
6 | * invalid, this exception will be thrown.
7 | *
8 | * In particular, the flow is to handle this exception and navigate to the
9 | * appropriate state, without requiring any additional action from the user
10 | * such as closing the browser to clearing the cache thereby killing the TGT.
11 | * The flow is responsible for handling this annoyance.
12 | *
13 | *
Essentially, the responsibility of this exception is solely to
14 | * communicate a broken and existing TGT, or in other words, the inability
15 | * to construct the authentication object from either the flow context
16 | * or an existing TGT. Beyond that task, it will not do
17 | * or provide any interesting functionality.
18 | * @author Misagh Moayyed
19 | * @see GenerateMultiFactorCredentialsAction
20 | */
21 | public class NoAuthenticationContextAvailable extends RuntimeException {
22 | private static final long serialVersionUID = -1693098929280964735L;
23 | }
24 |
--------------------------------------------------------------------------------
/cas-mfa-web/src/main/webapp/WEB-INF/view/jsp/default/ui/casUnknownPrincipalErrorView.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 |
3 | Licensed to Jasig under one or more contributor license
4 | agreements. See the NOTICE file distributed with this work
5 | for additional information regarding copyright ownership.
6 | Jasig licenses this file to you under the Apache License,
7 | Version 2.0 (the "License"); you may not use this file
8 | except in compliance with the License. You may obtain a
9 | copy of the License at the following location:
10 |
11 | http://www.apache.org/licenses/LICENSE-2.0
12 |
13 | Unless required by applicable law or agreed to in writing,
14 | software distributed under the License is distributed on an
15 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | KIND, either express or implied. See the License for the
17 | specific language governing permissions and limitations
18 | under the License.
19 |
20 | --%>
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/cas-mfa-java/README.md:
--------------------------------------------------------------------------------
1 | # Readme for cas-mfa-java sub-module
2 |
3 | ## What is this
4 |
5 | This module is for the Java source code of the multifactor authentication extensions for CAS.
6 | It builds to a .jar.
7 |
8 | 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.
9 |
10 | Of course, it's kind of useless all by itself, since you also need Web application components, which live in the parallel `cas-mfa-web` directory. Those Web components depend on these Java components.
11 |
12 | This is kind of complicated and may not be the final answer here.
13 |
14 | ## How do I build it?
15 |
16 | In this directory, run
17 |
18 | mvn package
19 |
20 | This will yield a `target` directory containing, among other artifacts, a `cas-mfa-java-{VERSION}.jar`, where {VERSION} is, as of this writing, "0.0.1-SNAPSHOT". As in, `cas-mfa-java-0.0.1-SNAPSHOT.jar`.
21 |
22 | You'd then include that .jar in an application, e.g. by declaring it as a Maven dependency in a `pom.xml`.
23 |
24 | The `cas-mfa-web` project does this, and the top level (up one directory) `pom.xml` automates first building this .jar and then making use of it in the other (i.e., .war) artifacts it builds.
25 |
26 |
--------------------------------------------------------------------------------
/NOTICE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2014, The Evergreen State College, University of Utah, Internet2 and/or the author or authors
2 |
3 | This project includes software developed by and/or licensed to Apereo,
4 | as per the copyright notice and license terms documented in the Jasig / Apereo CAS
5 | product distribution and source code themselves.
6 | http://www.apereo.org/
7 |
8 | Licensed under the Apache License, Version 2.0 (the
9 | "License"); you may not use this software except in compliance
10 | with the License. You may obtain a copy of the License at:
11 |
12 | http://www.apache.org/licenses/LICENSE-2.0
13 |
14 | Unless required by applicable law or agreed to in writing,
15 | software distributed under the License is distributed on
16 | an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 | KIND, either express or implied. See the License for the
18 | specific language governing permissions and limitations
19 | under the License.
20 |
21 | This project includes or includes software based on:
22 | Jasig CAS Core under Apache 2
23 | Jasig CAS Web Application under Apache 2
24 | Jasig Central Authentication Service under Apache 2
25 |
26 | This project was partially supported by the National Strategy for Trusted Identities
27 | in Cyberspace (NSTIC) National Program Office and the National
28 | Institute of Standards and Technology (NIST).
29 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/authentication/DefaultAuthenticationMethodConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.authentication;
2 |
3 | import java.util.Map;
4 |
5 | /**
6 | * @author Misagh Moayyed
7 | */
8 | public class DefaultAuthenticationMethodConfigurationProvider implements AuthenticationMethodConfigurationProvider {
9 | private final Map authenticationMethodsMap;
10 |
11 | /**
12 | * Instantiates a new Default authentication method configuration provider.
13 | *
14 | * @param authenticationMethodsMap the authentication methods map
15 | */
16 | public DefaultAuthenticationMethodConfigurationProvider(final Map authenticationMethodsMap) {
17 | this.authenticationMethodsMap = authenticationMethodsMap;
18 | }
19 |
20 | @Override
21 | public boolean containsAuthenticationMethod(final String name) {
22 | return getAuthenticationMethod(name) != null;
23 | }
24 |
25 | @Override
26 | public AuthenticationMethod getAuthenticationMethod(final String name) {
27 | if (this.authenticationMethodsMap.containsKey(name)) {
28 | final Integer rank = this.authenticationMethodsMap.get(name);
29 | return new AuthenticationMethod(name, rank);
30 | }
31 | return null;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/web/support/UnrecognizedAuthenticationMethodException.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.web.support;
2 |
3 | /**
4 | * Thrown if an incoming authentication request specified an authentication
5 | * method that is not supported and/or recognized by the MFA configuration.
6 | * @author Misagh Moayyed
7 | * @see net.unicon.cas.mfa.web.support.AbstractMultiFactorAuthenticationArgumentExtractor
8 | */
9 | public class UnrecognizedAuthenticationMethodException extends RuntimeException {
10 |
11 | private static final long serialVersionUID = -4141126343252978132L;
12 |
13 | private final String authnMethod;
14 | private final String service;
15 |
16 | /**
17 | * Spin up the exception instance with the requested authentication method.
18 | * @param authnMethod the unsupported authentication method in the request
19 | * @param service the service we are trying to log into
20 | */
21 | public UnrecognizedAuthenticationMethodException(final String authnMethod, final String service) {
22 | this.authnMethod = authnMethod;
23 | this.service = service;
24 | }
25 |
26 | public final String getAuthenticationMethod() {
27 | return this.authnMethod;
28 | }
29 |
30 | public final String getService() {
31 | return this.service;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/cas-mfa-web/src/main/webapp/WEB-INF/view/jsp/default/ui/casMfaUnrecognizedAuthnMethodErrorView.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 |
3 | Licensed to Jasig under one or more contributor license
4 | agreements. See the NOTICE file distributed with this work
5 | for additional information regarding copyright ownership.
6 | Jasig licenses this file to you under the Apache License,
7 | Version 2.0 (the "License"); you may not use this file
8 | except in compliance with the License. You may obtain a
9 | copy of the License at the following location:
10 |
11 | http://www.apache.org/licenses/LICENSE-2.0
12 |
13 | Unless required by applicable law or agreed to in writing,
14 | software distributed under the License is distributed on an
15 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | KIND, either express or implied. See the License for the
17 | specific language governing permissions and limitations
18 | under the License.
19 |
20 | --%>
21 |
22 |
23 |
24 |
26 |
27 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/authentication/RegisteredServiceMfaRoleProcessor.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.authentication;
2 |
3 | import org.jasig.cas.authentication.Authentication;
4 | import org.jasig.cas.authentication.principal.WebApplicationService;
5 |
6 | import javax.validation.constraints.NotNull;
7 | import java.util.List;
8 |
9 | /**
10 | * Defines a mechanism that allows the service's attributes to be compared with the users attributes.
11 | *
12 | * @author John Gasper
13 | * @author Unicon, inc.
14 | */
15 | public interface RegisteredServiceMfaRoleProcessor {
16 |
17 | /**
18 | * mfa_attribute_name.
19 | */
20 | String MFA_ATTRIBUTE_NAME = "mfa_attribute_name";
21 |
22 | /**
23 | * mfa_attribute_name.
24 | */
25 | String MFA_ATTRIBUTE_PATTERN = "mfa_attribute_pattern";
26 |
27 | /**
28 | * Resolves the authn_method for a given service if it supports mfa_role and the user has the appropriate attribute.
29 | * @param authentication the user authentication object
30 | * @param targetService the target service being tested
31 | * @return a list (usually one) mfa authn request context.
32 | */
33 | List resolve(@NotNull Authentication authentication,
34 | @NotNull WebApplicationService targetService);
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/ticket/MultiFactorAuthenticationBaseTicketValidationException.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.ticket;
2 |
3 | /**
4 | * Base multifactor authentication exception class in the hierarchy.
5 | * Defines the authentication code, the error message and the requested
6 | * authentication method.
7 | * @author Misagh Moayyed
8 | * @see UnacceptableMultiFactorAuthenticationMethodException
9 | * @see UnrecognizedMultiFactorAuthenticationMethodException
10 | */
11 | public abstract class MultiFactorAuthenticationBaseTicketValidationException extends RuntimeException {
12 |
13 | private static final long serialVersionUID = 7880539766094343828L;
14 |
15 | private final String authenticationMethod;
16 | private final String code;
17 |
18 | /**
19 | * Initialize the exception object.
20 | * @param c the error code
21 | * @param msg the error message describing this exception
22 | * @param authnMethod the authentication method requested
23 | */
24 | public MultiFactorAuthenticationBaseTicketValidationException(final String c, final String msg, final String authnMethod) {
25 | super(msg);
26 | this.code = c;
27 | this.authenticationMethod = authnMethod;
28 | }
29 |
30 | public final String getAuthenticationMethod() {
31 | return this.authenticationMethod;
32 | }
33 |
34 | public final String getCode() {
35 | return this.code;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/test/java/net/unicon/cas/mfa/web/support/DefaultMultiFactorAuthenticationSupportingWebApplicationServiceTests.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.web.support;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import org.jasig.cas.authentication.principal.Response;
6 | import org.junit.Test;
7 | import org.junit.runner.RunWith;
8 | import org.junit.runners.JUnit4;
9 |
10 | @RunWith(JUnit4.class)
11 | public class DefaultMultiFactorAuthenticationSupportingWebApplicationServiceTests {
12 |
13 | /**
14 | * Test that an instance of {@link DefaultMultiFactorAuthenticationSupportingWebApplicationService}
15 | * properly implements getAuthenticationMethod() and ability to get a Response to direct the user to redirect to
16 | * the service with a ticket.
17 | */
18 | @Test
19 | public void testServiceness() {
20 | final DefaultMultiFactorAuthenticationSupportingWebApplicationService svc =
21 | new DefaultMultiFactorAuthenticationSupportingWebApplicationService("https://www.github.com",
22 | "https://www.github.com", null, Response.ResponseType.REDIRECT,
23 | "test_authn_method");
24 | assertEquals(svc.getAuthenticationMethod(), "test_authn_method");
25 | final Response res = svc.getResponse("testTicketId");
26 | assertNotNull(res);
27 | assertEquals(res.getResponseType(), Response.ResponseType.REDIRECT);
28 | assertEquals(res.getUrl(), "https://www.github.com?ticket=testTicketId");
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/cas-mfa-java/src/main/java/net/unicon/cas/mfa/authentication/principal/UnknownPrincipalMatchException.java:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.authentication.principal;
2 |
3 |
4 | import org.jasig.cas.authentication.Authentication;
5 |
6 | /**
7 | * An exception to indicate that a mismatch has been found between authenticated principals.
8 | * Credentials that are resolved into principals throughout the authentication flow are required
9 | * to be recognized by the same identifier {@link org.jasig.cas.authentication.principal.Principal#getId()}.
10 | *
For instance, if credentials are resolved into Principal 'A' as part of the first
11 | * leg of the multifactor authentication, and the second leg then resolves the credentials to into a Principal
12 | * that is identified by 'B', this exception will be thrown.
13 | * @author Misagh Moayyed
14 | * @see MultiFactorCredentials
15 | */
16 | public final class UnknownPrincipalMatchException extends RuntimeException {
17 | private static final long serialVersionUID = -6572930326804074536L;
18 |
19 | private final Authentication authentication;
20 |
21 | /**
22 | * Initialize the exception with the authentication given.
23 | * @param authentication the authentication context associated with this error.
24 | */
25 | public UnknownPrincipalMatchException(final Authentication authentication) {
26 | this.authentication = authentication;
27 | }
28 |
29 | public Authentication getAuthentication() {
30 | return authentication;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/cas-mfa-duo/src/main/groovy/net/unicon/cas/mfa/authentication/duo/DuoAuthenticationService.groovy:
--------------------------------------------------------------------------------
1 | package net.unicon.cas.mfa.authentication.duo
2 |
3 | import com.duosecurity.DuoWeb
4 | import groovy.util.logging.Slf4j
5 |
6 | /**
7 | * An abstraction that encapsulates interaction with Duo 2fa authentication service via its public API
8 | *