[java-idp-plugin-duo] branch main updated: JDUO-56 - Audit the Duo 'factor' used when authenticating

Phil Smart philip.smart at jisc.ac.uk
Fri Mar 25 12:31:25 UTC 2022


This is an automated email from the git hooks/post-receive script.

philsmart pushed a commit to branch main
in repository java-idp-plugin-duo.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-duo.git;a=commit;h=1588b9962c704660ac80c0789284f1034bea935c

The following commit(s) were added to refs/heads/main by this push:
     new 1588b99  JDUO-56 - Audit the Duo 'factor' used when authenticating
1588b99 is described below

commit 1588b9962c704660ac80c0789284f1034bea935c
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Mar 25 12:30:39 2022 +0000

    JDUO-56 - Audit the Duo 'factor' used when authenticating
    
    - Add to factor used to the process log on authn success.
    
    https://shibboleth.atlassian.net/browse/JDUO-56
---
 .../idp/plugin/authn/duo/DuoOIDCAuthAPI.java       |   6 +
 .../impl/ValidateDuoTokenAuthenticationResult.java |  34 +++-
 .../plugin/authn/duo/impl/ValidateTokenClaims.java |   1 -
 .../authn/duo/impl/AbstractDuoActionTest.java      | 209 ++++++++++++++++++++-
 .../ValidateDuoTokenAuthenticationResultTest.java  |  62 +++++-
 5 files changed, 290 insertions(+), 22 deletions(-)

diff --git a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DuoOIDCAuthAPI.java b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DuoOIDCAuthAPI.java
index 0448dbd..00e82c6 100644
--- a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DuoOIDCAuthAPI.java
+++ b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DuoOIDCAuthAPI.java
@@ -52,6 +52,12 @@ public final class DuoOIDCAuthAPI {
     /** The name of the JSON authentication result object.*/
     @Nonnull @NotEmpty public static final String DUO_AUTH_RESULT_JSON_OBJECT = "auth_result";
     
+    /** The name of the JSON authentication context object.*/
+    @Nonnull @NotEmpty public static final String DUO_AUTH_CONTEXT_JSON_OBJECT = "auth_context";
+    
+    /** The name of the JSON authentication factor object.*/
+    @Nonnull @NotEmpty public static final String DUO_AUTH_FACTOR_JSON_OBJECT = "factor";
+    
     /** The name of the JSON result status property.*/
     @Nonnull @NotEmpty public static final String DUO_AUTH_RESULT_STATUS_JSON_OBJECT = "status";
     
diff --git a/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateDuoTokenAuthenticationResult.java b/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateDuoTokenAuthenticationResult.java
index 2a91e6c..0da17a4 100644
--- a/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateDuoTokenAuthenticationResult.java
+++ b/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateDuoTokenAuthenticationResult.java
@@ -183,7 +183,8 @@ public class ValidateDuoTokenAuthenticationResult extends AbstractValidationActi
             final String authResultStatusMsg = (String)statusMsgObj;
             
             if (DuoOIDCAuthAPI.DUO_AUTH_RESULT_ALLOW.equalsIgnoreCase(authResultStatus)){
-                log.info("{} Duo 2FA authentication succeeded for '{}'",getLogPrefix(),duoContext.getUsername());
+                log.info("{} Duo 2FA authentication succeeded for '{}', using second-factor '{}'",
+                        getLogPrefix(),duoContext.getUsername(), extractFactor());
                 //must build authentication before recording success. recordSuccess runs
                 //the cleanup hook which removes the Duo context and prevents useful operation
                 //of the contextToPrincipalMappingStrategy.
@@ -211,10 +212,34 @@ public class ValidateDuoTokenAuthenticationResult extends AbstractValidationActi
             recordFailure(profileRequestContext);
             return;
         }
-       
-        
-        
+      
+    }
+    
+    /**
+     * Extract the second-factor use for authentication. Taken from the auth_context. Will return
+     * {@literal 'unspecified'} if not found.
+     * 
+     * @return the second-factor used, or {@literal 'unspecified'} if not found. Should always be found.
+     */
+     @Nonnull private String extractFactor() {
         
+        String factor = "unspecified";
+        try {
+            final Map<String, Object> authnContextClaimObj = 
+                    claimsSet.getJSONObjectClaim(DuoOIDCAuthAPI.DUO_AUTH_CONTEXT_JSON_OBJECT);
+            
+            if (authnContextClaimObj != null) {         
+                final Object factorClaimObj = 
+                        authnContextClaimObj.get(DuoOIDCAuthAPI.DUO_AUTH_FACTOR_JSON_OBJECT);
+                if (factorClaimObj instanceof String) {
+                    factor = (String)factorClaimObj;
+                }
+            }
+        } catch (final ParseException e) {
+            // Do nothing, just return unknown
+        }
+        return factor;
+
     }
     
     /** {@inheritDoc} */
@@ -257,6 +282,7 @@ public class ValidateDuoTokenAuthenticationResult extends AbstractValidationActi
     public static class DuoOIDCCleanupHook implements Consumer<ProfileRequestContext> {
 
         /** {@inheritDoc} */
+        @Override
         public void accept(@Nullable final ProfileRequestContext input) {
             if (input != null) {
                 final AuthenticationContext authnCtx = input.getSubcontext(AuthenticationContext.class);
diff --git a/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateTokenClaims.java b/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateTokenClaims.java
index 0d9614e..0f34834 100644
--- a/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateTokenClaims.java
+++ b/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateTokenClaims.java
@@ -37,7 +37,6 @@ import net.shibboleth.idp.plugin.authn.duo.AbstractDuoAuthenticationAction;
 import net.shibboleth.idp.plugin.authn.duo.DuoException;
 import net.shibboleth.idp.plugin.authn.duo.context.DuoOIDCAuthenticationContext;
 import net.shibboleth.oidc.jwt.claims.ClaimsValidator;
-import net.shibboleth.oidc.jwt.claims.JWTClaimsValidation;
 import net.shibboleth.oidc.jwt.claims.JWTValidationException;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
diff --git a/idp-duo-impl/src/test/java/net/shibboleth/idp/plugin/authn/duo/impl/AbstractDuoActionTest.java b/idp-duo-impl/src/test/java/net/shibboleth/idp/plugin/authn/duo/impl/AbstractDuoActionTest.java
index 0f625f0..0a009e9 100644
--- a/idp-duo-impl/src/test/java/net/shibboleth/idp/plugin/authn/duo/impl/AbstractDuoActionTest.java
+++ b/idp-duo-impl/src/test/java/net/shibboleth/idp/plugin/authn/duo/impl/AbstractDuoActionTest.java
@@ -139,7 +139,7 @@ public abstract class AbstractDuoActionTest {
     }
     
     /**
-     * Create a dummy Duo plain (no sig or enc) JWT token with no auth_result.
+     * Create a dummy Duo plain (no sig or enc) JWT token with no factor in the auth_context.
      * 
      * @param authResult the authentication result e.g. allow.
      * @param authResultMessage a user friendly result message.
@@ -148,16 +148,83 @@ public abstract class AbstractDuoActionTest {
      * @param iat issued at.
      * @param authTime the auth time.
      * @param apiHost the api host
-     * @param factor the duo factor
      * @return the duo auth token.
      */
-    protected JWT createPlainDummyTokenNoAuthResult(@Nonnull final String authResult, 
+    protected JWT createPlainDummyTokenNoAuthFactor(@Nonnull final String authResult, 
             @Nonnull final String authResultMessage, @Nonnull final String aud,
+            @Nonnull final Instant exp, @Nonnull final Instant iat, 
+            @Nonnull final Instant authTime, @Nonnull final String apiHost) {
+        
+        final String jwtJson = createJWTJsonWithNoAuthFactor(authResult,authResultMessage,aud,
+            exp, iat, authTime, apiHost);
+        
+        try {
+           
+            final JWT jwt = new PlainJWT(new PlainHeader().toBase64URL(),
+                    new Base64URL(Base64Support.encodeURLSafe(jwtJson.getBytes())));
+            //test the claims exist by calling it
+            jwt.getJWTClaimsSet();
+            return jwt;
+        } catch (final EncodingException | ParseException e) {            
+            fail("Error creating the Mock JWT",e);
+        }
+        fail();
+        return null;
+    }
+    
+    /**
+     * Create a dummy Duo plain (no sig or enc) JWT token with no auth_result.
+     * 
+     * @param aud audience
+     * @param exp expiration time.
+     * @param iat issued at.
+     * @param authTime the auth time.
+     * @param apiHost the api host
+     * @param factor the duo factor
+     * @return the duo auth token.
+     */
+    protected JWT createPlainDummyTokenNoAuthResult(@Nonnull final String aud,
             @Nonnull final Instant exp, @Nonnull final Instant iat, 
             @Nonnull final Instant authTime, @Nonnull final String apiHost, 
             @Nonnull final String factor) {
         
-        final String jwtJson = createJWTJsonWithNoAuthResult(authResult,authResultMessage,aud,
+        final String jwtJson = createJWTJsonWithNoAuthResult(aud,
+            exp, iat, authTime, apiHost, factor);
+        
+        try {
+           
+            final JWT jwt = new PlainJWT(new PlainHeader().toBase64URL(),
+                    new Base64URL(Base64Support.encodeURLSafe(jwtJson.getBytes())));
+            //test the claims exist by calling it
+            jwt.getJWTClaimsSet();
+            return jwt;
+        } catch (final EncodingException | ParseException e) {            
+            fail("Error creating the Mock JWT",e);
+        }
+        fail();
+        return null;
+    }
+    
+    /**
+     * Create a dummy Duo plain (no sig or enc) JWT token with no auth_result status claim.
+     * 
+     * @param authResultMessage a user friendly result message.
+     * @param aud audience
+     * @param exp expiration time.
+     * @param iat issued at.
+     * @param authTime the auth time.
+     * @param apiHost the api host
+     * @param factor the duo factor
+     * @return the duo auth token.
+     */
+    protected JWT createPlainDummyTokenNoResultStatus(
+            @Nonnull final String authResultMessage, 
+            @Nonnull final String aud,
+            @Nonnull final Instant exp, @Nonnull final Instant iat, 
+            @Nonnull final Instant authTime, @Nonnull final String apiHost, 
+            @Nonnull final String factor) {
+        
+        final String jwtJson = createJWTJsonWithNoAuthStatus(authResultMessage, aud,
             exp, iat, authTime, apiHost, factor);
         
         try {
@@ -435,7 +502,8 @@ public abstract class AbstractDuoActionTest {
     }
     
     /**
-     * Create a JWT token in JSON without the auth_result element.
+     * Create a JWT token in JSON using the claims arguments, but without a factor claim
+     * in the auth_context.
      * 
      * @param authResult the authentication result e.g. allow.
      * @param authResultMessage a user friendly result message.
@@ -444,11 +512,74 @@ public abstract class AbstractDuoActionTest {
      * @param iat issued at.
      * @param authTime the auth time.
      * @param apiHost the api host.
-     * @param factor the factor.
      * @return the duo auth token.
      */
-    private String createJWTJsonWithNoAuthResult(@Nonnull final String authResult, 
+    private String createJWTJsonWithNoAuthFactor(@Nonnull final String authResult, 
             @Nonnull final String authResultMessage, @Nonnull final String aud,
+            @Nonnull final Instant exp, @Nonnull final Instant iat, 
+            @Nonnull final Instant authTime, @Nonnull final String apiHost) {
+        final String jwtJson = "{\n" + 
+                "    \"iss\": \"https://"+apiHost+"/oauth/v1/token\",\n" + 
+                "    \"sub\": \"jdoe\",\n" + 
+                "    \"preferred_username\": \"jdoe\",\n" + 
+                "    \"aud\": \""+aud+"\",\n" + 
+                "    \"exp\": "+Math.toIntExact(exp.getEpochSecond()) +",\n" + 
+                "    \"iat\": "+(double)iat.getEpochSecond()+",\n" + 
+                "    \"auth_time\": "+authTime.getEpochSecond()+",\n" + 
+                "    \"auth_result\": {\n" + 
+                "        \"status_msg\": \""+authResultMessage+"\",\n" + 
+                "        \"status\": \""+authResult+"\",\n" + 
+                "        \"result\": \""+authResult+"\"\n" + 
+                "    },\n" + 
+                "    \"auth_context\": {\n" + 
+                "        \"result\": \"success\",\n" + 
+                "        \"timestamp\": 1599749128,\n" + 
+                "        \"auth_device\": {\n" + 
+                "            \"ip\": \"1.1.1.1\",\n" + 
+                "            \"name\": \"+44 999999\",\n" + 
+                "            \"location\": {\n" + 
+                "                \"state\": \"State\",\n" + 
+                "                \"city\": \"City\",\n" + 
+                "                \"country\": \"Country\"\n" + 
+                "            }\n" + 
+                "        },\n" + 
+                "        \"txid\": \"1684599c-bb16-4250-af85-904291bfe7cc\",\n" + 
+                "        \"event_type\": \"authentication\",\n" + 
+                "        \"reason\": \"user_approved\",\n" + 
+                "        \"access_device\": {\n" + 
+                "            \"hostname\": null,\n" + 
+                "            \"ip\": \"1.1.1.1\",\n" + 
+                "            \"location\": {\n" + 
+                "                \"state\": \"State\",\n" + 
+                "                \"city\": \"City\",\n" + 
+                "                \"country\": \"Country\"\n" + 
+                "            }\n" + 
+                "        },\n" + 
+                "        \"application\": {\n" + 
+                "            \"key\": \"DIU6GEFWG5LIUTVV2M3N\",\n" + 
+                "            \"name\": \"Shibboleth Integration Testing\"\n" + 
+                "        },\n" + 
+                "        \"user\": {\n" + 
+                "            \"key\": \"DUGL8U46QGJSOUJWG59W\",\n" + 
+                "            \"name\": \"jdoe\"\n" + 
+                "        }\n" + 
+                "    }\n" + 
+                "}"; 
+        return jwtJson;
+    }
+    
+    /**
+     * Create a JWT token in JSON without the auth_result element.
+     * 
+     * @param aud audience
+     * @param exp expiration time.
+     * @param iat issued at.
+     * @param authTime the auth time.
+     * @param apiHost the api host.
+     * @param factor the factor.
+     * @return the duo auth token.
+     */
+    private String createJWTJsonWithNoAuthResult(@Nonnull final String aud,
             @Nonnull final Instant exp, @Nonnull final Instant iat, 
             @Nonnull final Instant authTime, @Nonnull final String apiHost, 
             @Nonnull final String factor) {
@@ -498,6 +629,70 @@ public abstract class AbstractDuoActionTest {
         return jwtJson;
     }
     
+    /**
+     * Create a JWT token in JSON without the auth_result element.
+     * 
+     * @param authResultMessage a user friendly result message
+     * @param aud audience
+     * @param exp expiration time.
+     * @param iat issued at.
+     * @param authTime the auth time.
+     * @param apiHost the api host.
+     * @param factor the factor.
+     * @return the duo auth token.
+     */
+    private String createJWTJsonWithNoAuthStatus(@Nonnull final String authResultMessage, 
+            @Nonnull final String aud,
+            @Nonnull final Instant exp, @Nonnull final Instant iat, 
+            @Nonnull final Instant authTime, @Nonnull final String apiHost, 
+            @Nonnull final String factor) {
+        final String jwtJson = "{\n" + 
+                "    \"iss\": \"https://"+apiHost+"/oauth/v1/token\",\n" + 
+                "    \"sub\": \"jdoe\",\n" + 
+                "    \"preferred_username\": \"jdoe\",\n" + 
+                "    \"iat\": "+(double)iat.getEpochSecond()+",\n" + 
+                "    \"auth_time\": "+authTime.getEpochSecond()+",\n" + 
+                "    \"auth_result\": {\n" + 
+                "    \"status_msg\": \""+authResultMessage+"\"\n" + 
+                "    },\n" + 
+                "    \"auth_context\": {\n" + 
+                "        \"result\": \"success\",\n" + 
+                "        \"timestamp\": 1599749128,\n" + 
+                "        \"auth_device\": {\n" + 
+                "            \"ip\": \"1.1.1.1\",\n" + 
+                "            \"name\": \"+44 999999\",\n" + 
+                "            \"location\": {\n" + 
+                "                \"state\": \"State\",\n" + 
+                "                \"city\": \"City\",\n" + 
+                "                \"country\": \"Country\"\n" + 
+                "            }\n" + 
+                "        },\n" + 
+                "        \"txid\": \"1684599c-bb16-4250-af85-904291bfe7cc\",\n" + 
+                "        \"event_type\": \"authentication\",\n" + 
+                "        \"reason\": \"user_approved\",\n" + 
+                "        \"access_device\": {\n" + 
+                "            \"hostname\": null,\n" + 
+                "            \"ip\": \"1.1.1.1\",\n" + 
+                "            \"location\": {\n" + 
+                "                \"state\": \"State\",\n" + 
+                "                \"city\": \"City\",\n" + 
+                "                \"country\": \"Country\"\n" + 
+                "            }\n" + 
+                "        },\n" + 
+                "        \"application\": {\n" + 
+                "            \"key\": \"DIU6GEFWG5LIUTVV2M3N\",\n" + 
+                "            \"name\": \"Shibboleth Integration Testing\"\n" + 
+                "        },\n" + 
+                "        \"factor\": \""+factor+"\",\n" + 
+                "        \"user\": {\n" + 
+                "            \"key\": \"DUGL8U46QGJSOUJWG59W\",\n" + 
+                "            \"name\": \"jdoe\"\n" + 
+                "        }\n" + 
+                "    }\n" + 
+                "}"; 
+        return jwtJson;
+    }
+    
     /**
      * Create a JWT token in JSON using the claims arguments present, but missing the 'aud' and
      * 'exp' claims.
diff --git a/idp-duo-impl/src/test/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateDuoTokenAuthenticationResultTest.java b/idp-duo-impl/src/test/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateDuoTokenAuthenticationResultTest.java
index a976fea..afc68c6 100644
--- a/idp-duo-impl/src/test/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateDuoTokenAuthenticationResultTest.java
+++ b/idp-duo-impl/src/test/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateDuoTokenAuthenticationResultTest.java
@@ -84,7 +84,7 @@ public class ValidateDuoTokenAuthenticationResultTest extends AbstractDuoActionT
     }
     
     /**
-     * Test successful execution.
+     * Test unsuccessful execution when there is no auth_result claim.
      * 
      * @throws ComponentInitializationException on error.
      */
@@ -93,16 +93,55 @@ public class ValidateDuoTokenAuthenticationResultTest extends AbstractDuoActionT
         addDuoContext();
         addDuoIntegrationToContext();
         addAttemptedFlow("authn/DuoOIDC");
-        dc.setAuthToken(createPlainDummyTokenNoAuthResult(DuoOIDCAuthAPI.DUO_AUTH_RESULT_ALLOW,"Login Succesful",CLIENT_ID,
+        dc.setAuthToken(createPlainDummyTokenNoAuthResult(CLIENT_ID,
                 Instant.now().plus(1,ChronoUnit.MINUTES),Instant.now(), Instant.now(), "api.duosecurity.com", "duo_push"));
         dc.setUsername("jdoe");
         action.initialize();
         
         final Event event = action.execute(src);
-        // success here is a null event
         assertEventId(event, AuthnEventIds.AUTHN_EXCEPTION);
     }
     
+    /**
+     * Test unsuccessful execution when there is no auth_result status claim.
+     * 
+     * @throws ComponentInitializationException on error.
+     */
+    @Test
+    public void testExecuteNoAuthStatus() throws ComponentInitializationException {
+        addDuoContext();
+        addDuoIntegrationToContext();
+        addAttemptedFlow("authn/DuoOIDC");
+        dc.setAuthToken(createPlainDummyTokenNoResultStatus("Login Succesful", CLIENT_ID,
+                Instant.now().plus(1,ChronoUnit.MINUTES),Instant.now(), Instant.now(), "api.duosecurity.com", "duo_push"));
+        dc.setUsername("jdoe");
+        action.initialize();
+        
+        final Event event = action.execute(src);
+        assertEventId(event, AuthnEventIds.AUTHN_EXCEPTION);
+    }
+    
+    /**
+     * Test successful execution, but there is no 'factor' to log. 
+     * 
+     * @throws ComponentInitializationException on error.
+     */
+    @Test
+    public void testExecuteNoAuthContextFactor() throws ComponentInitializationException {
+        addDuoContext();
+        addDuoIntegrationToContext();
+        addAttemptedFlow("authn/DuoOIDC");
+        dc.setAuthToken(createPlainDummyTokenNoAuthFactor(DuoOIDCAuthAPI.DUO_AUTH_RESULT_ALLOW,
+                "Login Succesful", CLIENT_ID,
+                Instant.now().plus(1,ChronoUnit.MINUTES),Instant.now(), Instant.now(), "api.duosecurity.com"));
+        dc.setUsername("jdoe");
+        action.initialize();
+        
+        final Event event = action.execute(src);
+        // success here is a null event
+        assertNull(event);
+    }
+    
     /**
      * Test the correct invalid authentication state is signalled when no Duo context is supplied.
      * 
@@ -133,7 +172,8 @@ public class ValidateDuoTokenAuthenticationResultTest extends AbstractDuoActionT
         action.setClassifiedMessages(classifiedMessages);
         
         dc.setAuthToken(createPlainDummyToken(DuoOIDCAuthAPI.DUO_AUTH_RESULT_DENY,"Account locked",CLIENT_ID, 
-                Instant.now().plus(1,ChronoUnit.MINUTES),Instant.now(), Instant.now(), "api.duosecurity.com", "duo_push"));
+                Instant.now().plus(1,ChronoUnit.MINUTES),Instant.now(), Instant.now(), 
+                "api.duosecurity.com", "duo_push"));
         dc.setUsername("jdoe");
         action.initialize();
         
@@ -173,7 +213,8 @@ public class ValidateDuoTokenAuthenticationResultTest extends AbstractDuoActionT
         addAttemptedFlow("authn/DuoOIDC");
         //made up fail message, will terminate on the duo site in reality.
         dc.setAuthToken(createPlainDummyToken(DuoOIDCAuthAPI.DUO_AUTH_RESULT_DENY,"Login Failed",CLIENT_ID, 
-                Instant.now().plus(1,ChronoUnit.MINUTES),Instant.now(), Instant.now(), "api.duosecurity.com", "duo_push"));
+                Instant.now().plus(1,ChronoUnit.MINUTES),Instant.now(), Instant.now(), 
+                "api.duosecurity.com", "duo_push"));
         dc.setUsername("jdoe");
         action.initialize();
         
@@ -192,16 +233,17 @@ public class ValidateDuoTokenAuthenticationResultTest extends AbstractDuoActionT
         addDuoIntegrationToContext();
         addAttemptedFlow("authn/DuoOIDC");
         dc.setAuthToken(createPlainDummyToken(DuoOIDCAuthAPI.DUO_AUTH_RESULT_ALLOW,"Login Succesful",CLIENT_ID,
-                Instant.now().plus(1,ChronoUnit.MINUTES),Instant.now(), Instant.now(), "api.duosecurity.com", "duo_push"));
+                Instant.now().plus(1,ChronoUnit.MINUTES),Instant.now(), Instant.now(), 
+                "api.duosecurity.com", "duo_push"));
         dc.setUsername("jdoe");
         
         action.setContextToPrincipalMappingStrategy(prc ->{
            
-           DuoOIDCAuthenticationContext duoContext = 
+           final DuoOIDCAuthenticationContext duoContext = 
                    prc.getSubcontext(AuthenticationContext.class).getSubcontext(DuoOIDCAuthenticationContext.class);
            final List<Principal> p = new ArrayList<>();
            try {
-            if ("duo_push".equals((String)duoContext.getAuthToken().getJWTClaimsSet()
+            if ("duo_push".equals(duoContext.getAuthToken().getJWTClaimsSet()
                        .getJSONObjectClaim("auth_context").get("factor"))){
                    p.add(new AuthnContextClassRefPrincipal("http://example.com/duoPush"));
                }
@@ -239,11 +281,11 @@ public class ValidateDuoTokenAuthenticationResultTest extends AbstractDuoActionT
         
         action.setContextToPrincipalMappingStrategy(prc ->{
            
-           DuoOIDCAuthenticationContext duoContext = 
+           final DuoOIDCAuthenticationContext duoContext = 
                    prc.getSubcontext(AuthenticationContext.class).getSubcontext(DuoOIDCAuthenticationContext.class);
            final List<Principal> p = new ArrayList<>();
            try {
-               if ("sms".equals((String)duoContext.getAuthToken().getJWTClaimsSet()
+               if ("sms".equals(duoContext.getAuthToken().getJWTClaimsSet()
                           .getJSONObjectClaim("auth_context").get("factor"))){
                       p.add(new AuthnContextClassRefPrincipal("http://example.com/sms"));
                   }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list