[java-idp-plugin-oidc-rp] branch main updated: Add audit logging. Cleanup the flow.

Phil Smart philip.smart at jisc.ac.uk
Wed Aug 31 09:27:42 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-oidc-rp.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-oidc-rp.git;a=commit;h=5a008ebdd251b4b50fc2380e0276a2eb31ec4385

The following commit(s) were added to refs/heads/main by this push:
     new 5a008eb  Add audit logging. Cleanup the flow.
5a008eb is described below

commit 5a008ebdd251b4b50fc2380e0276a2eb31ec4385
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Wed Aug 31 10:27:36 2022 +0100

    Add audit logging. Cleanup the flow.
---
 .../impl/AbstractHttpOIDCAuthenticationAction.java |   2 +-
 .../AbstractOIDCAuthenticationResponseAction.java  |  10 +-
 .../impl/DefaultEndUserClaimsLookupStrategy.java   |  74 +++++++
 .../rp/impl/UnsupportedResponseTypeAction.java     |  45 ++++
 .../authn/oidc/rp/impl/UserInfoEndpointLookup.java |   1 -
 .../META-INF/net.shibboleth.idp/postconfig.xml     | 236 ++++++++++++++++++++-
 .../oidc-relying-party-authn-beans.xml             |  41 ++--
 .../oidc-relying-party-authn-flow.xml              |  90 ++++----
 .../ProxyAuthenticationFlowAuditExtractor.java     |  51 +++++
 .../plugin/authn/oidc/rp/impl/OIDCRPFlowTest.java  |  75 ++++++-
 .../plugin/authn/oidc/rp/impl/TestTokenHelper.java |   1 +
 .../flow/AbstractAuthnXmlFlowExecutionTests.java   |   3 +
 idp-oidc-rp-impl/src/test/resources/conf/audit.xml |  74 +++++++
 .../src/test/resources/logback-test.xml            |   8 +-
 14 files changed, 628 insertions(+), 83 deletions(-)

diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AbstractHttpOIDCAuthenticationAction.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AbstractHttpOIDCAuthenticationAction.java
index 738a730..3ce3c36 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AbstractHttpOIDCAuthenticationAction.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AbstractHttpOIDCAuthenticationAction.java
@@ -44,7 +44,7 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
  * 
  * @param <T> the response type of the object returned as a result of the request.
  */
-public class AbstractHttpOIDCAuthenticationAction<T> extends AbstractOIDCAuthenticationResponseAction {
+public abstract class AbstractHttpOIDCAuthenticationAction<T> extends AbstractOIDCAuthenticationResponseAction {
     
     /** Class logger.*/
     @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractHttpOIDCAuthenticationAction.class);
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AbstractOIDCAuthenticationResponseAction.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AbstractOIDCAuthenticationResponseAction.java
index 085c60a..18bcc46 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AbstractOIDCAuthenticationResponseAction.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AbstractOIDCAuthenticationResponseAction.java
@@ -45,10 +45,10 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
 /**
  * 
  * Abstract class for actions performing actions on {@link AuthenticationResponse} located under
- * {@link ProfileRequestContext#getOutboundMessageContext()#getM}.
+ * the {@link ProfileRequestContext#getOutboundMessageContext())}.
  * 
  */
-abstract class AbstractOIDCAuthenticationResponseAction extends AbstractAuthenticationAction {
+public abstract class AbstractOIDCAuthenticationResponseAction extends AbstractAuthenticationAction {
 
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractOIDCAuthenticationResponseAction.class);
@@ -92,7 +92,7 @@ abstract class AbstractOIDCAuthenticationResponseAction extends AbstractAuthenti
      * 
      * @return the authentication response.
      */
-    @Nullable public AuthenticationSuccessResponse getAuthenticationResponse() {
+    @Nullable protected AuthenticationSuccessResponse getAuthenticationResponse() {
         return authnResponse;
     }
     
@@ -101,7 +101,7 @@ abstract class AbstractOIDCAuthenticationResponseAction extends AbstractAuthenti
      * 
      * @return the authentication request.
      */
-    @Nullable public OIDCAuthenticationRequest getAuthenticationRequest() {
+    @Nullable protected OIDCAuthenticationRequest getAuthenticationRequest() {
         return authnRequest;
     }
 
@@ -111,7 +111,7 @@ abstract class AbstractOIDCAuthenticationResponseAction extends AbstractAuthenti
      * 
      * @return The provider metadata context.
      */
-    @Nullable public OIDCProviderMetadataContext getProviderMetadataContext() {
+    @Nullable protected OIDCProviderMetadataContext getProviderMetadataContext() {
         return providerMetadataContext;
     }
 
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/DefaultEndUserClaimsLookupStrategy.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/DefaultEndUserClaimsLookupStrategy.java
new file mode 100644
index 0000000..0cf9d83
--- /dev/null
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/DefaultEndUserClaimsLookupStrategy.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.plugin.authn.oidc.rp.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+
+import com.nimbusds.openid.connect.sdk.claims.ClaimsSet;
+
+import net.shibboleth.idp.plugin.authn.oidc.rp.context.EndUserClaimsContext;
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+/** Function that extracts the end-user's claims from the {@link EndUserClaimsContext}.*/
+ at ThreadSafe
+public class DefaultEndUserClaimsLookupStrategy implements Function<ProfileRequestContext, ClaimsSet> {
+    
+    /** Strategy used to look up the {@link EndUserClaimsContext}. */
+    @Nonnull 
+    private final Function<ProfileRequestContext, EndUserClaimsContext> endUserClaimsContextLookupStrategy;
+
+    /**
+     * 
+     * Constructor.
+     *
+     * @param strategy the end-user claims context lookup strategy to use.
+     */
+    public DefaultEndUserClaimsLookupStrategy(@Nullable @ParameterName(name="endUserClaimsContextLookupStrategy") 
+            final Function<ProfileRequestContext, EndUserClaimsContext> strategy) {
+        if (strategy != null) {
+            endUserClaimsContextLookupStrategy = 
+                    Constraint.isNotNull(strategy, "EndUserClaimsContext lookup strategy can not be null");
+        } else {
+            endUserClaimsContextLookupStrategy =
+                    new ChildContextLookup<>(EndUserClaimsContext.class).compose(
+                            new InboundMessageContextLookup());
+        }
+    }
+
+
+    @Override
+    @Nullable public ClaimsSet apply(@Nonnull final ProfileRequestContext prc) {
+        
+        final EndUserClaimsContext endUserContext = endUserClaimsContextLookupStrategy.apply(prc);
+        
+        if (endUserContext != null && endUserContext.getEndUserClaims() != null) {
+            return endUserContext.getEndUserClaims();
+        }
+        return null;
+    }
+
+}
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/UnsupportedResponseTypeAction.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/UnsupportedResponseTypeAction.java
new file mode 100644
index 0000000..feee9c7
--- /dev/null
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/UnsupportedResponseTypeAction.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.plugin.authn.oidc.rp.impl;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.oidc.profile.core.OidcEventIds;
+
+/** Simple action to log the response was to an unsupported grant type.*/
+public class UnsupportedResponseTypeAction extends AbstractProfileAction {
+    
+    /** Class logger. */
+    @Nonnull private final Logger log = LoggerFactory.getLogger(UnsupportedResponseTypeAction.class);
+    
+    @Override
+    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+        log.error("{} Response type is not supported", getLogPrefix());
+        ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_RESPONSE_TYPE);
+        return;
+    }
+    
+    
+
+}
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/UserInfoEndpointLookup.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/UserInfoEndpointLookup.java
index 615fa12..29370c5 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/UserInfoEndpointLookup.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/UserInfoEndpointLookup.java
@@ -89,7 +89,6 @@ public class UserInfoEndpointLookup extends AbstractHttpOIDCAuthenticationAction
           try {              
               final UserInfoResponse responseObject = handleRequest(profileRequestContext);
               userInfoCtx.setUserInfo(responseObject);
-
           } catch (final OIDCRPException e) {
               log.error("{} Unable to return claims from UserInfo endpoint",getLogPrefix(),e);
               ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.AUTHN_EXCEPTION);
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index d19dd9a..e021f89 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -117,13 +117,24 @@
     <bean id="shibboleth.ChildLookup.Proxy.MessageContextLookup.Outbound" 
     class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.OutboundMessageContextFromProxyPRC"/>
     
+    <bean id="shibboleth.MessageLookup.oidc.rp.OIDCAuthenticationRequest"
+        class="org.opensaml.messaging.context.navigate.MessageLookup"
+        c:type="#{ T(net.shibboleth.oidc.profile.core.OIDCAuthenticationRequest) }" />
+        
+    <bean id="shibboleth.MessageLookup.oidc.rp.AuthenticationResponse"
+        class="org.opensaml.messaging.context.navigate.MessageLookup"
+        c:type="#{ T(com.nimbusds.openid.connect.sdk.AuthenticationResponse) }" />
+    
     <!-- Aliases to use in the flow config -->
     <alias name="shibboleth.ChildLookup.Proxy.MessageContextLookup.Inbound" alias="InboundMessageContextFromRootPRC"/>
     <alias name="shibboleth.ChildLookup.Proxy.MessageContextLookup.Outbound" alias="OutboundMessageContextFromRootPRC"/>
     <alias name="shibboleth.ChildLookup.Proxy.ProxyProfileRequestContext" alias="ProxyProfileRequestContextLookup"/>
     
-    
+    <!-- lookup strategies required by the postconfig in addition to the flow -->
+    <bean id="shibboleth.authn.oidc.rp.DefaultIDTokenLookupStrategy"
+        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.DefaultIDTokenLookupStrategy" />
 
+        
     <!-- The authentication flow descriptor -->
 
     <bean id="authn/OIDCRelyingParty" parent="shibboleth.AuthenticationFlow"
@@ -212,37 +223,246 @@
 
 
     <!-- 
-        Add some auditors, should be in the audit-system.xml
+        Some RP audit extractors
      -->
+         
+    <bean id="shibboleth.oidc.rp.DefaultPostLookupAuditExtractors" lazy-init="true"
+            class="org.springframework.beans.factory.config.MapFactoryBean">
+        <property name="sourceMap">
+            <map>
+                <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.idp.authn.AuthnAuditFields.AUTHN_FLOW_ID"/>
+                    </key>
+                    <bean class="net.shibboleth.idp.plugin.authn.oidc.rp.audit.impl.ProxyAuthenticationFlowAuditExtractor" />
+                </entry>
+                
+               <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.oidc.profile.audit.AuditFields.PROXY_ISSUER"/>
+                    </key>
+                    <ref bean="shibboleth.RelyingPartyIdLookup.Simple" />
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.oidc.profile.audit.AuditFields.PROXY_CLIENT_ID"/>
+                    </key>
+                    <ref bean="shibboleth.ResponderIdLookup.Simple" />
+                </entry>
+            </map>
+        </property>
+    </bean>
+    
+    <bean id="shibboleth.oidc.rp.DefaultPostRequestAuditExtractors" lazy-init="true"
+            class="org.springframework.beans.factory.config.MapFactoryBean">
+        <property name="sourceMap">
+            <map>
+                <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.oidc.profile.audit.AuditFields.RESPONSE_TYPE"/>
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.ResponseTypeAuditExtractor">
+                         <constructor-arg>
+                            <bean parent="shibboleth.Functions.Compose"
+                                c:g-ref="shibboleth.MessageLookup.oidc.rp.OIDCAuthenticationRequest"
+                                c:f-ref="shibboleth.MessageContextLookup.Outbound" />
+                        </constructor-arg>
+                    </bean>
+                </entry>
+                 <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.oidc.profile.audit.AuditFields.RESPONSE_MODE"/>
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.ResponseModeAuditExtractor">
+                         <constructor-arg>
+                            <bean parent="shibboleth.Functions.Compose"
+                                c:g-ref="shibboleth.MessageLookup.oidc.rp.OIDCAuthenticationRequest"
+                                c:f-ref="shibboleth.MessageContextLookup.Outbound" />
+                        </constructor-arg>
+                    </bean>
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.oidc.profile.audit.AuditFields.SCOPE"/>
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.ScopeAuditExtractor">
+                         <constructor-arg>
+                            <bean parent="shibboleth.Functions.Compose"
+                                c:g-ref="shibboleth.MessageLookup.oidc.rp.OIDCAuthenticationRequest"
+                                c:f-ref="shibboleth.MessageContextLookup.Outbound" />
+                        </constructor-arg>
+                    </bean>
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.oidc.profile.audit.AuditFields.FORCE_AUTHN"/>
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.ForceAuthnAuditExtractor">
+                        <constructor-arg>
+                            <bean parent="shibboleth.Functions.Compose"
+                                c:g-ref="shibboleth.MessageLookup.oidc.rp.OIDCAuthenticationRequest"
+                                c:f-ref="shibboleth.MessageContextLookup.Outbound" />
+                        </constructor-arg>
+                    </bean>
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant
+                            static-field="net.shibboleth.oidc.profile.audit.AuditFields.NONCE"/>
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.NonceAuditExtractor">
+                         <constructor-arg>
+                            <bean parent="shibboleth.Functions.Compose"
+                                c:g-ref="shibboleth.MessageLookup.oidc.rp.OIDCAuthenticationRequest"
+                                c:f-ref="shibboleth.MessageContextLookup.Outbound" />
+                        </constructor-arg>
+                    </bean>
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant
+                            static-field="net.shibboleth.oidc.profile.audit.AuditFields.AUTHORIZATION_ENDPOINT"/>
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.AuthorizationEndpointAuditExtractor">
+                         <constructor-arg>
+                            <bean parent="shibboleth.Functions.Compose"
+                                c:g-ref="shibboleth.MessageLookup.oidc.rp.OIDCAuthenticationRequest"
+                                c:f-ref="shibboleth.MessageContextLookup.Outbound" />
+                        </constructor-arg>
+                    </bean>
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant
+                            static-field="net.shibboleth.oidc.profile.audit.AuditFields.REDIRECT_URI"/>
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.RedirectURIAuditExtractor">
+                         <constructor-arg>
+                            <bean parent="shibboleth.Functions.Compose"
+                                c:g-ref="shibboleth.MessageLookup.oidc.rp.OIDCAuthenticationRequest"
+                                c:f-ref="shibboleth.MessageContextLookup.Outbound" />
+                        </constructor-arg>
+                    </bean>
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant
+                            static-field="net.shibboleth.oidc.profile.audit.AuditFields.REDIRECT_URI"/>
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.RedirectURIAuditExtractor">
+                         <constructor-arg>
+                            <bean parent="shibboleth.Functions.Compose"
+                                c:g-ref="shibboleth.MessageLookup.oidc.rp.OIDCAuthenticationRequest"
+                                c:f-ref="shibboleth.MessageContextLookup.Outbound" />
+                        </constructor-arg>
+                    </bean>
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.oidc.profile.audit.AuditFields.ACRS"/>
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.AuthenticationContextClassReferencesAuditExtractor">
+                         <constructor-arg>
+                            <bean parent="shibboleth.Functions.Compose"
+                                c:g-ref="shibboleth.MessageLookup.oidc.rp.OIDCAuthenticationRequest"
+                                c:f-ref="shibboleth.MessageContextLookup.Outbound" />
+                        </constructor-arg>
+                    </bean>
+                </entry>
+            </map>
+        </property>
+    </bean>
      
      <bean id="shibboleth.oidc.rp.DefaultAuthenticationResponseAuditExtractors" lazy-init="true"
             class="org.springframework.beans.factory.config.MapFactoryBean">
         <property name="sourceMap">
             <map>
-                <!-- No entries for now -->
+                <entry>
+                    <key>
+                        <util:constant
+                            static-field="net.shibboleth.oidc.profile.audit.AuditFields.INBOUND_MESSAGE_CLASS" />
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.InboundMessageClassLookupFunction" />
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant static-field="net.shibboleth.oidc.profile.audit.AuditFields.AUTHENTICATION_RESULT"/>
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.AuthenticationResponseStatusAuditExtractor">
+                         <constructor-arg>
+                            <bean parent="shibboleth.Functions.Compose"
+                                c:g-ref="shibboleth.MessageLookup.oidc.rp.AuthenticationResponse"
+                                c:f-ref="shibboleth.MessageContextLookup.Inbound" />
+                        </constructor-arg>
+                    </bean>
+                </entry>
             </map>
         </property>
     </bean>
     
-    
+    <bean id="shibboleth.authn.oidc.rp.DefaultIDTokenClaimsSetLookupStrategy"
+        class="net.shibboleth.oidc.profile.audit.impl.ClaimSetFromJWTLookupStrategy" 
+        c:jwtLookupStrategy-ref="shibboleth.authn.oidc.rp.DefaultIDTokenLookupStrategy">        
+    </bean>
+   
+    <bean id="shibboleth.authn.oidc.rp.DefaultEndUserClaimsLookupStrategy"
+        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.DefaultEndUserClaimsLookupStrategy" 
+        c:endUserClaimsContextLookupStrategy="#{getObject('shibboleth.authn.oidc.rp.EndUserClaimsContextLookupStrategy')}"/>
+        
     <bean id="shibboleth.oidc.rp.DefaultTokenResponseAuditExtractors" lazy-init="true"
             class="org.springframework.beans.factory.config.MapFactoryBean">
         <property name="sourceMap">
             <map>
-                <!-- No entries for now -->
+                 <entry>
+                    <key>
+                        <util:constant
+                            static-field="net.shibboleth.oidc.profile.audit.AuditFields.SUB_VALUE" />
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.StringBasedJWTClaimAuditExtractor" 
+                        p:claimName="sub" 
+                        p:claimsSetLookupStrategy-ref="shibboleth.authn.oidc.rp.DefaultIDTokenClaimsSetLookupStrategy"/>
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant
+                            static-field="net.shibboleth.oidc.profile.audit.AuditFields.AUDIENCE" />
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.StringListBasedJWTClaimAuditExtractor" 
+                        p:claimName="aud" 
+                        p:claimsSetLookupStrategy-ref="shibboleth.authn.oidc.rp.DefaultIDTokenClaimsSetLookupStrategy"/>
+                </entry>
+                <entry>
+                    <key>
+                        <util:constant
+                            static-field="net.shibboleth.oidc.profile.audit.AuditFields.AUTHN_INSTANT" />
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.DateBasedJWTClaimAuditExtractor" 
+                        p:claimName="auth_time" 
+                        p:claimsSetLookupStrategy-ref="shibboleth.authn.oidc.rp.DefaultIDTokenClaimsSetLookupStrategy"/>
+                </entry>
             </map>
         </property>
     </bean>
     
-    
-    <bean id="shibboleth.oidc.rp.DefaultUserInfoResponseAuditExtractors" lazy-init="true"
+    <!-- Extract audit information post id_token and (if configured) userinfo response. Nothing by default. -->
+    <bean id="shibboleth.oidc.rp.DefaultPostResponseAuditExtractors" lazy-init="true"
             class="org.springframework.beans.factory.config.MapFactoryBean">
         <property name="sourceMap">
             <map>
-                <!-- No entries for now -->
+                <!-- <entry>
+                    <key>
+                        <util:constant
+                            static-field="net.shibboleth.oidc.profile.audit.AuditFields.FIELD" />
+                    </key>
+                    <bean class="net.shibboleth.oidc.profile.audit.impl.StringBasedJWTClaimAuditExtractor" 
+                        p:claimName="name" 
+                        p:claimsSetLookupStrategy-ref="shibboleth.authn.oidc.rp.DefaultEndUserClaimsLookupStrategy"/>
+                </entry> -->
             </map>
         </property>
     </bean>
     
+  
+    
 
 </beans>
\ No newline at end of file
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
index 40182e4..242b84f 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
@@ -100,7 +100,7 @@
     <!-- TODO check shibboleth.oidc.rp is sensible in the getObjects -->
     <bean id="PostLookupPopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
-        p:fieldExtractors="#{getObject('shibboleth.oidc.rp.PostLookupAuditExtractors') ?: getObject('shibboleth.DefaultPostLookupAuditExtractors')}" />
+        p:fieldExtractors="#{getObject('shibboleth.oidc.rp.PostLookupAuditExtractors') ?: getObject('shibboleth.oidc.rp.DefaultPostLookupAuditExtractors')}" />
     
 
     <bean id="InitializeAuthorizationRequest"
@@ -151,12 +151,8 @@
         
     <bean id="PostRequestPopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
-        p:fieldExtractors="#{getObject('shibboleth.oidc.rp.PostRequestAuditExtractors') ?: getObject('shibboleth.DefaultPostRequestAuditExtractors')}" />
-       
-     <bean id="AuthenticationResponsePopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext"
-        p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
-        p:fieldExtractors="#{getObject('shibboleth.oidc.rp.AuthenticationResponseAuditExtractors') ?: getObject('shibboleth.oidc.rp.DefaultAuthenticationResponseAuditExtractors')}" />
-    
+        p:fieldExtractors="#{getObject('shibboleth.oidc.rp.PostRequestAuditExtractors') ?: getObject('shibboleth.oidc.rp.DefaultPostRequestAuditExtractors')}" />
+        
     <bean id="WriteAuditLog" class="net.shibboleth.idp.profile.audit.impl.WriteAuditLog" scope="prototype"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:formattingMap-ref="shibboleth.AuditFormattingMap"
@@ -348,6 +344,11 @@
         </property>
     </bean>
     
+    <bean id="AuthenticationResponsePopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext"
+        p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
+        p:fieldExtractors="#{getObject('shibboleth.oidc.rp.AuthenticationResponseAuditExtractors') ?: getObject('shibboleth.oidc.rp.DefaultAuthenticationResponseAuditExtractors')}" />
+   
+    
     <bean id="IsCodeFlow" class="net.shibboleth.idp.plugin.authn.oidc.rp.config.logic.IsCodeFlowPredicate"/>
     <bean id="IsHybridFlow" class="net.shibboleth.idp.plugin.authn.oidc.rp.config.logic.IsHybridFlowPredicate"/>
     <bean id="IsImplicitFlow" class="net.shibboleth.idp.plugin.authn.oidc.rp.config.logic.IsImplicitFlowPredicate"/>
@@ -537,10 +538,7 @@
         p:claimsValidator="#{getObject('shibboleth.authn.oidc.rp.idtoken.IDTokenClaimsValidator') 
            ?: getObject('DefaultIDTokenClaimsValidator')}"
         p:jwtLookupStrategy="#{getObject('shibboleth.authn.oidc.rp.idtoken.IDTokenLookupStrategy') 
-           ?: getObject('DefaultIDTokenLookupStrategy')}" />
-
-    <bean id="DefaultIDTokenLookupStrategy"
-        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.DefaultIDTokenLookupStrategy" />
+           ?: getObject('shibboleth.authn.oidc.rp.DefaultIDTokenLookupStrategy')}" />
 
     <bean id="DefaultIDTokenClaimsValidator"
         class="net.shibboleth.oidc.security.jwt.claims.impl.ChainingJWTClaimsValidator"
@@ -761,6 +759,8 @@
         </constructor-arg>
     </bean>
 
+    <bean id="shibboleth.authn.oidc.rp.DefaultUserInfoTokenLookupStrategy"
+        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.DefaultUserInfoTokenLookupStrategy" />
 
     <bean id="ValidateUserInfoTokenClaims" scope="prototype"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.ValidateTokenClaims"
@@ -770,15 +770,13 @@
         p:claimsValidator="#{getObject('shibboleth.authn.oidc.rp.userinfo.UserInfoTokenClaimsValidator') 
            ?: getObject('DefaultUserInfoTokenClaimsValidator')}"
         p:jwtLookupStrategy="#{getObject('shibboleth.authn.oidc.rp.userinfo.UserInfoTokenLookupStrategy') 
-           ?: getObject('DefaultUserInfoTokenLookupStrategy')}" />
+           ?: getObject('shibboleth.authn.oidc.rp.DefaultUserInfoTokenLookupStrategy')}" />
 
     <bean id="DefaultUserInfoTokenClaimsValidator"
         class="net.shibboleth.oidc.security.jwt.claims.impl.ChainingJWTClaimsValidator"
         p:claimValidators-ref="UserInfoClaimsValidators" />
 
-    <bean id="DefaultUserInfoTokenLookupStrategy"
-        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.DefaultUserInfoTokenLookupStrategy" />
-        
+    
     <bean id="UserInfoTokenRequiredClaimsValidator"
         class="net.shibboleth.oidc.security.jwt.claims.impl.RequiredClaimsValidator">
         <property name="requiredClaims">
@@ -802,11 +800,6 @@
         <ref bean="AudienceClaimsValidator" />
     </util:list>
     
-    <bean id="UserInfoResponsePopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext"
-        p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
-        p:fieldExtractors="#{getObject('shibboleth.oidc.rp.UserInfoResponseAuditExtractors') ?: getObject('shibboleth.oidc.rp.DefaultUserInfoResponseAuditExtractors')}" />
-    
-
     <!-- This is a very simplified and hard coded version of the claims verification used for a JWT. Maybe look to replace -->
     <bean id="ValidateUserInfoPlainResponseClaims" scope="prototype"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.ValidateUserInfoJSONObjectClaims"
@@ -817,8 +810,11 @@
     <bean id="ProcessEndUserClaims" class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.ProcessEndUserClaims"
         scope="prototype" p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup" />
-
-
+        
+    <bean id="PostResponsePopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext"
+        p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
+        p:fieldExtractors="#{getObject('shibboleth.oidc.rp.PostResponseAuditExtractors') ?: getObject('shibboleth.oidc.rp.DefaultPostResponseAuditExtractors')}" />
+    
     <bean id="CheckUserInfoPlainResponseTypeCondition"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.messaging.context.logic.UserInfoPlainResponseTypeCondition" />
 
@@ -834,6 +830,7 @@
         p:attributeFilter-ref="shibboleth.AttributeFilterService"
         p:transcoderRegistry-ref="shibboleth.AttributeRegistryService" />
         
+    <bean id="UnsupportedResponseTypeAction" class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.UnsupportedResponseTypeAction"/>
         
      <!-- Can override one or more of the beans above. Note, the property override is mostly to allow tests
     to change the location of the user config file. -->
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml
index 84aa7f9..e5a7ef3 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml
@@ -6,7 +6,7 @@
 
     <!-- This is a login flow for proxied authentication implemented via OIDC -->
 
-    <!-- OP discovery? -->
+    <!-- OP discovery e.g. webfinger -->
     <on-start>
         <!-- If installed, this can bypass discovery. -->
         <evaluate
@@ -30,11 +30,12 @@
         <evaluate expression="OIDCProviderMetadataLookup" />
         <evaluate expression="InitializeRelyingPartyContext" />
         <evaluate expression="SelectRelyingPartyConfiguration" />
-
         <evaluate expression="PostLookupPopulateAuditContext" />
+        
         <evaluate expression="InitializeOutboundMessageContext" />
         <evaluate expression="SelectProfileConfiguration" />
         <evaluate expression="InitializeOAuth2ClientContext" />
+        
         <evaluate expression="InitializeAuthorizationRequest" />
         <evaluate expression="AddResponseTypeAndMode" />
         <evaluate expression="AddScopes" />
@@ -43,16 +44,16 @@
         <evaluate expression="AddEndpointURI" />
         <evaluate expression="AddRequestedClaims" />
         <evaluate expression="AddRedirectURI"/>
-        <evaluate expression="AddAuthenticationContextClassReferences" />
+        <evaluate expression="AddAuthenticationContextClassReferences" />        
         <evaluate expression="PostRequestPopulateAuditContext" />
+        
         <evaluate expression="WriteAuditLog" />
         <!-- <evaluate expression="InitializeMessageChannelSecurityContext" /> -->
         <evaluate expression="'proceed'" />
-
         <transition on="proceed" to="RequestObjectRequiredAndSupported" />
     </action-state>
 
-    <!-- Is a request object required by the config, and does the OP support it? -->
+    <!-- Is a request object required by the configuration, and does the OP support it? -->
     <decision-state id="RequestObjectRequiredAndSupported">
         <if test="RequestObjectRequiredAndSupportedPredicate.test(ProxyProfileRequestContextLookup.apply(opensamlProfileRequestContext))"
             then="BuildRequestObject" 
@@ -63,7 +64,10 @@
         <evaluate expression="PopulateRequestObjectSignatureSigningParameters" />
         <evaluate expression="PopulateRequestObjectEncryptionParameters" />
         <evaluate expression="BuildRequestObject" />
-        <!-- We can not sign and encrypt the RO here. That is left to the preEncodeMessageHandlers. -->
+        <!-- 
+            We can not sign and encrypt the RO here (we need state from WF execution key). 
+            That is left to the preEncodeMessageHandlers. 
+        -->
         <evaluate expression="'proceed'" />
         <transition on="proceed" to="AuthnRequest" />
     </action-state>
@@ -82,7 +86,10 @@
         <transition to="ValidateResponse" />
     </view-state>
 
-    <!--  Generally validate the response, in a way that is agnostic to the grant_type -->
+    <!--  
+        Generally validate the response in a way that is agnostic to the 
+        response_type and authentication flow used.
+    -->
     <action-state id="ValidateResponse">
         <evaluate expression="ValidateExternalAuthenticationContext" />
         <evaluate expression="AuthenticationResponsePopulateAuditContext" />
@@ -94,24 +101,24 @@
         id_token matched against the original provider metadata). 
         -->
         <evaluate expression="AddPeerEntityContextToInboundMessage" />
-        <evaluate expression="'proceed'" />
-        <transition on="proceed" to="SwitchOnGrantType" />
-        <on-exit>
-            <evaluate expression="WriteAuditLog" />
-        </on-exit>
+        <evaluate expression="'proceed'" />        
+        <transition on="proceed" to="SwitchOnAuthenticationFlowType" />
     </action-state>
 
-    <!-- Switch flow path based on OIDC grant_type used. Only code flow is actually supported currently. -->
-    <decision-state id="SwitchOnGrantType">
+    <!-- 
+        Switch webflow path based on the implied OIDC authentication flow taken from the response_type used. 
+        Only the 'code' response_type and hence Authorization/Authentication Code Flow is actually supported. 
+    -->
+    <decision-state id="SwitchOnAuthenticationFlowType">
         <if test="IsCodeFlow.test(OutboundMessageContextFromRootPRC.apply(opensamlProfileRequestContext))" 
-            then="CodeFlow" />
+            then="AuthorizationCodeFlow" />
         <if test="IsHybridFlow.test(OutboundMessageContextFromRootPRC.apply(opensamlProfileRequestContext))" 
             then="HybridFlow" />
         <if test="IsImplicitFlow.test(OutboundMessageContextFromRootPRC.apply(opensamlProfileRequestContext))"
             then="ImplicitFlow" else="UnsupportedFlow" />
     </decision-state>
 
-    <action-state id="CodeFlow">        
+    <action-state id="AuthorizationCodeFlow">        
         <evaluate expression="InitializeOAuth2ClientAuthenticationContext" />
         <evaluate expression="ExchangeCodeForAccessToken" />
         <evaluate expression="ValidateOAuthAccessTokenResponse" />
@@ -125,21 +132,17 @@
         <evaluate expression="TokenResponsePopulateAuditContext" />
         <evaluate expression="'proceed'" />
         <transition on="proceed" to="CheckUserInfoClaimsRequired" />
-        <on-exit>
-            <evaluate expression="WriteAuditLog" />
-        </on-exit>
     </action-state>
 
-
+    <!--  Should we use the access_token to request UserInfo claims? -->
     <decision-state id="CheckUserInfoClaimsRequired">
         <if test="CheckUserInfoRequiredCondition.test(ProxyProfileRequestContextLookup.apply(opensamlProfileRequestContext))"
             then="UserInfoRequest" else="FinalizeResponse" />
-        <!-- if else here, we need to set id_token claims into EndUserClaimsContext -->
     </decision-state>
 
     <action-state id="UserInfoRequest">
         <evaluate expression="UserInfoEndpointLookup" />
-        <!-- Something needs to check TLS server certificate? -->
+        <!-- Something needs to check TLS server certificate? Not sure, performed by HTTP Client -->
         <evaluate expression="'proceed'" />
         <transition on="proceed" to="CheckUserInfoResponseType" />
     </action-state>
@@ -157,34 +160,31 @@
         <evaluate expression="PopulateUserInfoTokenSignatureValidationParameters" />
         <evaluate expression="HandleUserInfoTokenValidation" />
         <evaluate expression="ValidateUserInfoTokenClaims" />
-        <evaluate expression="UserInfoResponsePopulateAuditContext" />
         <evaluate expression="'proceed'" />
         <transition on="proceed" to="FinalizeResponse" />
-        <on-exit>
-            <evaluate expression="WriteAuditLog" />
-        </on-exit>
     </action-state>
 
     <!-- Plain UserInfo response types will skip straight to this stage -->
     <action-state id="ValidateUserInfoPlainClaimsSet">
         <evaluate expression="ValidateUserInfoPlainResponseClaims" />
-        <evaluate expression="UserInfoResponsePopulateAuditContext" />
         <evaluate expression="'proceed'" />
         <transition on="proceed" to="FinalizeResponse" />
-        <on-exit>
-            <evaluate expression="WriteAuditLog" />
-        </on-exit>
     </action-state>
 
     <action-state id="FinalizeResponse">
-        <evaluate expression="ProcessEndUserClaims" />
+        <evaluate expression="ProcessEndUserClaims" />        
+        <evaluate expression="PostResponsePopulateAuditContext" />
         <evaluate expression="ValidateOIDCAuthentication" />
-        <evaluate expression="'proceed'" />
+        <evaluate expression="WriteAuditLog" />
+        <evaluate expression="'proceed'" />        
         <!-- Subject canonicalization -->
-        <transition on="proceed" to="proceed" />
+        <transition on="proceed" to="proceed" />   
     </action-state>
 
-    <!-- Placeholders for flows which are not supported, and would not work without some front-end impl. -->
+    <!-- 
+        Placeholders for flows which are not supported, and would not work without some front-end JavaScript
+        pulling out authentication response parameters from URL fragments and sending to the callback endpoint.
+    -->
     <action-state id="HybridFlow">
         <evaluate expression="'proceed'" />
         <transition on="proceed" to="UnsupportedFlow" />
@@ -195,12 +195,18 @@
         <transition on="proceed" to="UnsupportedFlow" />
     </action-state>
 
-    <action-state id="UnsupportedFlow">
+    <action-state id="UnsupportedFlow">         
+        <evaluate expression="UnsupportedResponseTypeAction"/>   
+        <!-- 
+            It should never get to the below transition, the above action creates an error 
+            event that should be caught by the global transition 
+        -->
         <evaluate expression="'proceed'" />
-        <transition on="proceed" to="END" />
+        <transition on="proceed" to="ReselectFlow" />
     </action-state>
     
-   <!--  <subflow-state id="CallSubjectCanonicalization" subflow="c14n">
+    
+    <!--  <subflow-state id="CallSubjectCanonicalization" subflow="c14n">
         <input name="calledAsSubflow" value="true" />
         <transition on="proceed" to="proceed" />
         
@@ -208,6 +214,16 @@
         <transition on="SubjectCanonicalizationError" to="ReselectFlow" />
     </subflow-state> -->
 
+    <global-transitions>        
+        <!-- Route everything out as a graceful failure to allow subsequent options to run. -->
+        <transition on="#{!'proceed'.equals(currentEvent.id)}" to="ReselectFlow">           
+           <evaluate expression="T(org.opensaml.core.metrics.MetricsSupport).getMetricRegistry().counter('net.shibboleth.idp.authn.oidc.rp.failures').inc()" />
+           <evaluate expression="WriteAuditLog" />
+        </transition>
+    </global-transitions>
+    
+   
+
     <bean-import resource="oidc-relying-party-authn-beans.xml" />
 
 </flow>
diff --git a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/audit/impl/ProxyAuthenticationFlowAuditExtractor.java b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/audit/impl/ProxyAuthenticationFlowAuditExtractor.java
new file mode 100644
index 0000000..1845949
--- /dev/null
+++ b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/audit/impl/ProxyAuthenticationFlowAuditExtractor.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.plugin.authn.oidc.rp.audit.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.BaseContext;
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.idp.authn.context.AuthenticationContext;
+
+/** 
+ * {@link Function} that returns the authentication flow ID from the attempted flow of the
+ * parent context used to satisfy a request. Assuming the parent is an {@link AuthenticationContext}
+ * as is the case in a proxy request.
+ */
+public class ProxyAuthenticationFlowAuditExtractor implements Function<ProfileRequestContext,String> {
+
+    /** {@inheritDoc} */
+    @Override
+    @Nullable public String apply(@Nullable final ProfileRequestContext input) {
+
+        final BaseContext baseContext = input.getParent();
+        if (baseContext instanceof AuthenticationContext) {
+            final AuthenticationContext authnCtx = (AuthenticationContext)baseContext;
+            if (authnCtx != null && authnCtx.getAttemptedFlow()!= null) {
+                return authnCtx.getAttemptedFlow().getId();
+            }
+        }
+        
+        return null;
+    }
+    
+}
diff --git a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/OIDCRPFlowTest.java b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/OIDCRPFlowTest.java
index 135ba3c..0fa1ed2 100644
--- a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/OIDCRPFlowTest.java
+++ b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/OIDCRPFlowTest.java
@@ -36,6 +36,7 @@ import org.apache.http.ssl.SSLContextBuilder;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.opensaml.core.config.InitializationException;
+import org.opensaml.core.metrics.impl.MetricRegistryInitializer;
 import org.opensaml.messaging.context.MessageContext;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.security.credential.Credential;
@@ -72,6 +73,7 @@ import net.shibboleth.idp.authn.context.RequestedPrincipalContext;
 import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
 import net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl;
 import net.shibboleth.idp.authn.principal.UsernamePrincipal;
+import net.shibboleth.idp.plugin.authn.oidc.rp.context.EndUserClaimsContext;
 import net.shibboleth.idp.plugin.authn.oidc.rp.context.OAuth2ClientContext;
 import net.shibboleth.idp.plugin.authn.oidc.rp.context.OIDCPeerEntityContext;
 import net.shibboleth.idp.plugin.authn.test.flow.AbstractAuthnXmlFlowExecutionTests;
@@ -246,11 +248,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         
         addBeanDefinition(builderContext, "shibboleth.DefaultFlowStartAuditExtractors",BeanDefinitionBuilder.
                 genericBeanDefinition(HashMap.class).getBeanDefinition());
-        
-        addBeanDefinition(builderContext, "shibboleth.AbstractPopulateAuditContext",BeanDefinitionBuilder.
-                genericBeanDefinition(net.shibboleth.idp.profile.audit.impl.PopulateAuditContext.class)
-                .setAbstract(true).getBeanDefinition());
-        
+       
         
         addBeanDefinition(builderContext, "shibboleth.PropertySourcesPlaceholderConfigurer",BeanDefinitionBuilder.
                 genericBeanDefinition(org.springframework.context.support.PropertySourcesPlaceholderConfigurer.class)
@@ -299,10 +297,23 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
             log.error("Could not initialise the algorithm registry");
             fail();
         }
+        
+       
+        try {
+            final MetricRegistryInitializer metricInit = new MetricRegistryInitializer();
+            metricInit.init();
+        } catch (final InitializationException e) {
+            log.error("Could not initialise the metric registry");
+            fail();
+        }
+        
+        // The audit system beans
+        loadBeanDefinitionsFromXmlFile(builderContext, 
+                new ClassPathResource("conf/audit.xml"), null);
   
         loadBeanDefinitionsFromXmlFile(builderContext, 
                 new ClassPathResource("META-INF/net.shibboleth.idp/postconfig.xml"),
-                null);
+                null);        
         
         // Note, is the relying-party which loads the profile config in the postconfig.
         // So properties for the profile config need to go here.
@@ -318,7 +329,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
                 new ClassPathResource("attribute/registry/postconfig.xml"), null);
         
         loadBeanDefinitionsFromXmlFile(builderContext, 
-                new ClassPathResource("attribute/filter/attribute-filter-system.xml"), null);
+                new ClassPathResource("attribute/filter/attribute-filter-system.xml"), null);        
         
         // Add a signing key incase it is used
         loadBeanDefinitionsFromXmlFile(builderContext, 
@@ -1196,9 +1207,57 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         resumeFlow(externalContext);
         
         //assert success conditions
-        assertFlowExecutionEnded();
+        // will end on ValidateResponse action
+        assertCurrentStateEquals("ValidateResponse");      
         assertNotNull(prc.getSubcontext(AuthenticationContext.class));
         assertNull(prc.getSubcontext(SubjectCanonicalizationContext.class));      
         
     }
+    
+    /** 
+     * Test the flow terminates correctly when an unsupported flow is used - which is unlikely to get
+     * this far.
+     * 
+     * @throws Exception on error.
+     */
+    @Test 
+    public void testAuthnFlowFromAuthorizationCallback_UnsupportedOIDCFlow() 
+            throws Exception {
+        
+        setFlowPath(FLOW);
+        setFlowModelResources(flowResources);
+        setSubflows(subflows);        
+        
+        final Map<String,String> mockProperties = Map.of(  
+                "idp.entityID", "http://idp.example.com/",
+                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID);
+        
+        setMockProperties(mockProperties);
+        
+        final var flowExecution = (FlowExecutionImpl)getFlowExecutionFactory()
+                .createFlowExecution(getFlowDefinition());
+        
+        final ProfileRequestContext prc = populateBasicContextTreeFromAuthnResponse(flowExecution); 
+                        
+        // Add a response type that suggests this flow was triggered by the IMPLICIT grant.
+        final OIDCAuthenticationRequest request = 
+                (OIDCAuthenticationRequest)prc.getSubcontext(AuthenticationContext.class)
+                .getSubcontext(ProfileRequestContext.class).getOutboundMessageContext().getMessage();
+        
+        request.setResponseType(ResponseType.IDTOKEN);
+        
+        assertNotNull(request);
+        updateFlowExecution(flowExecution);
+        
+        //set start view and ending event to transition on.
+        externalContext.setEventId("proceed");
+        setCurrentState("AuthnRequest");       
+        resumeFlow(externalContext);
+  
+        assertFlowExecutionEnded();
+        // Flow did not produce an end-user message context
+        assertNull(prc.getSubcontext(AuthenticationContext.class).getSubcontext(ProfileRequestContext.class)
+                .getInboundMessageContext().getSubcontext(EndUserClaimsContext.class));
+
+    }
 }
diff --git a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/TestTokenHelper.java b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/TestTokenHelper.java
index 5be9ef2..445ff07 100644
--- a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/TestTokenHelper.java
+++ b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/TestTokenHelper.java
@@ -82,6 +82,7 @@ public final class TestTokenHelper {
                 .claim("nonce", nonce)
                 .claim("azp", clientId)
                 .claim("name",name)
+                .claim("auth_time", new Date())
                 .issueTime(new Date())
                 .expirationTime(Date.from(Instant.now().plusSeconds(120)))
                 .build();
diff --git a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/test/flow/AbstractAuthnXmlFlowExecutionTests.java b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/test/flow/AbstractAuthnXmlFlowExecutionTests.java
index f894e65..76055dc 100644
--- a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/test/flow/AbstractAuthnXmlFlowExecutionTests.java
+++ b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/test/flow/AbstractAuthnXmlFlowExecutionTests.java
@@ -372,6 +372,9 @@ public abstract class AbstractAuthnXmlFlowExecutionTests extends CustomAbstractX
                 .setParentName("shibboleth.Functions.Compose")
                 .addConstructorArgReference("shibboleth.Functions.ProxyProfileRequestAuthenticationContext")
                 .addConstructorArgValue(new WebflowRequestContextProfileRequestContextLookup()).getBeanDefinition());
+        
+        // Setup the audit context
+        
                        
     }
     
diff --git a/idp-oidc-rp-impl/src/test/resources/conf/audit.xml b/idp-oidc-rp-impl/src/test/resources/conf/audit.xml
new file mode 100644
index 0000000..8c78cb3
--- /dev/null
+++ b/idp-oidc-rp-impl/src/test/resources/conf/audit.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+    xmlns:context="http://www.springframework.org/schema/context"
+    xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
+    xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+                        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+    default-init-method="initialize"
+    default-destroy-method="destroy">
+    
+    <!-- COPIED FROM THE MAIN IDP-CONF TO INIT THE AUDIT SYSTEM, ALSO CONTAINS BEANS FROM ELSEWHERE -->
+    
+    <bean id="shibboleth.AbstractPopulateAuditContext" abstract="true"
+        class="net.shibboleth.idp.profile.audit.impl.PopulateAuditContext" scope="prototype"
+        p:formattingMapParser-ref="shibboleth.AuditFormattingMapParser"
+        p:dateTimeFormat="#{getObject('shibboleth.AuditDateTimeFormat')}"
+        p:useDefaultTimeZone="#{getObject('shibboleth.AuditDefaultTimeZone') ?: false}"
+        p:fieldReplacements="#{getObject('shibboleth.AuditFieldReplacementMap')}" />
+        
+    <bean id="shibboleth.AuditFormattingMapParser"
+        class="net.shibboleth.idp.profile.audit.impl.PopulateAuditContext.FormattingMapParser"
+        c:_0-ref="shibboleth.AuditFormattingMap" />
+    
+
+    <!--
+    This bean defines a mapping between audit log categories and formatting strings.
+    -->
+    <!-- <util:map id="shibboleth.AuditFormattingMap">
+        <entry key="Shibboleth-Audit" value="%a|%ST|%T|%u|%SP|%i|%ac|%t|%attr|%n|%f|%SSO|%XX|%XA|%b|%bb|%e|%S|%SS|%s|%UA" />
+    </util:map> -->
+    
+    <!-- This is not the default logging format in a normal install! -->
+    <util:map id="shibboleth.AuditFormattingMap">
+        <entry key="Shibboleth-Audit" value="%a|%ST|%T|%u|%SP|%i|%ac|%AF|%t|%attr|%n|%f|%SSO|%XX|%XA|%b|%bb|%e|%S|%SS|%s|%UA|%DEST|%RS|%RDURI|%fauth|%RESPT|%RESPM|%scope|%ACRS|%AUTHZR|%aud|%t|%SUBUI" />
+    </util:map>
+
+    <!-- Override the format of date/time fields in the log and/or convert to default time zone. -->
+    <!--
+    <bean id="shibboleth.AuditDateTimeFormat" class="java.lang.String" c:_0="yyyy-MM-dd'T'HH:mm:ss.SSSZZ" />
+    <util:constant id="shibboleth.AuditDefaultTimeZone" static-field="java.lang.Boolean.TRUE" />
+    -->
+
+    <!-- Allows auditing to be disabled selectively for particular profiles/flows. -->
+    <util:list id="shibboleth.AuditSuppressedProfiles">
+        <value>http://shibboleth.net/ns/profiles/status</value>
+        <value>http://shibboleth.net/ns/profiles/mdquery</value>
+    </util:list>
+
+    <!--
+    You can freely add/change this map to map constants or frequently appearing strings into
+    shorter values in the audit log.
+    -->
+    <util:map id="shibboleth.AuditFieldReplacementMap">
+        <entry key="urn:oasis:names:tc:SAML:1.0:am:password" value="password" />
+        <entry key="urn:oasis:names:tc:SAML:2.0:ac:classes:Password" value="password" />
+        <entry key="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" value="password" />
+        <entry key="urn:mace:shibboleth:1.0:nameIdentifier" value="transient" />
+        <entry key="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" value="transient" />
+        <entry key="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" value="persistent" />
+        <entry key="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" value="emailAddress" />
+        <entry key="urn:oasis:names:tc:SAML:2.0:status:Success" value="Success" />
+        <entry key="urn:oasis:names:tc:SAML:2.0:status:Requester" value="Requester" />
+        <entry key="urn:oasis:names:tc:SAML:2.0:status:Responder" value="Responder" />
+        <entry key="http://www.w3.org/2009/xmlenc11#aes128-gcm" value="AES128-GCM" />
+        <entry key="http://www.w3.org/2009/xmlenc11#aes192-gcm" value="AES192-GCM" />
+        <entry key="http://www.w3.org/2009/xmlenc11#aes256-gcm" value="AES256-GCM" />
+        <entry key="http://www.w3.org/2001/04/xmlenc#aes128-cbc" value="AES128-CBC" />
+        <entry key="http://www.w3.org/2001/04/xmlenc#aes192-cbc" value="AES192-CBC" />
+        <entry key="http://www.w3.org/2001/04/xmlenc#aes256-cbc" value="AES256-CBC" />
+    </util:map>
+
+</beans>
diff --git a/idp-oidc-rp-impl/src/test/resources/logback-test.xml b/idp-oidc-rp-impl/src/test/resources/logback-test.xml
index 2e54ae8..8efbe68 100644
--- a/idp-oidc-rp-impl/src/test/resources/logback-test.xml
+++ b/idp-oidc-rp-impl/src/test/resources/logback-test.xml
@@ -6,7 +6,9 @@
     <logger name="net.shibboleth.idp.plugin.authn" level="TRACE"/>
     <logger name="org.springframework" level="INFO"/>
     <logger name="org.opensaml.xmlsec.config.GlobalAlgorithmRegistryInitializer" level="DEBUG"/>
-    <logger name="org.opensaml.xmlsec.algorithm" level="DEBUG"/>
+    <logger name="org.opensaml.xmlsec.algorithm" level="DEBUG"/>    
+    <logger name="net.shibboleth.idp.profile.audit.impl" level="TRACE"/>
+    
     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
         <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
             <pattern>%level [%logger:%line] - %msg%n</pattern>
@@ -19,4 +21,8 @@
         <appender-ref ref="STDOUT" />
     </root>
     
+    <logger name="Shibboleth-Audit" level="ALL">
+        
+    </logger>
+    
 </configuration>
\ No newline at end of file

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


More information about the commits mailing list