[java-identity-provider] branch master updated: IDP-465 - WIP attribute query consent subflow

Tom Zeller tzeller at dragonacea.biz
Fri Sep 21 17:21:32 EDT 2018


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

tzeller pushed a commit to branch master
in repository java-identity-provider.

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=0bd7e61b002c37032fd3da4738d0b8156f507b3f

The following commit(s) were added to refs/heads/master by this push:
       new  0bd7e61   IDP-465 - WIP attribute query consent subflow
0bd7e61 is described below

commit 0bd7e61b002c37032fd3da4738d0b8156f507b3f
Author: Tom Zeller <tzeller at dragonacea.biz>
AuthorDate: Fri Sep 21 15:52:05 2018 -0500

    IDP-465 - WIP attribute query consent subflow
    
    New intercept flow to apply consent to attribute queries.
    
    Still needs auditing / logging.
    
    https://issues.shibboleth.net/jira/browse/IDP-465
---
 .../conf/intercept/consent-intercept-config.xml    |  5 ++
 .../system/conf/profile-intercept-system.xml       |  3 +
 .../main/resources/system/conf/webflow-config.xml  |  1 +
 .../intercept/attribute-release-query-beans.xml    | 31 ++++++++
 .../intercept/attribute-release-query-flow.xml     | 90 ++++++++++++++++++++++
 .../flows/saml/saml2/attribute-query-beans.xml     | 17 ++++
 .../flows/saml/saml2/attribute-query-flow.xml      | 20 +++++
 .../SAML2TestStatusResponseTypeValidator.java      |  4 +-
 8 files changed, 170 insertions(+), 1 deletion(-)

diff --git a/idp-conf/src/main/resources/conf/intercept/consent-intercept-config.xml b/idp-conf/src/main/resources/conf/intercept/consent-intercept-config.xml
index 4e52be0..a089211 100644
--- a/idp-conf/src/main/resources/conf/intercept/consent-intercept-config.xml
+++ b/idp-conf/src/main/resources/conf/intercept/consent-intercept-config.xml
@@ -113,4 +113,9 @@
         </property>
     </bean>
 
+    <!--
+    Condition to evaluate to apply attribute-release consent to attribute queries.
+    -->
+    <bean id="shibboleth.consent.AttributeQuery.Condition" parent="shibboleth.Conditions.FALSE" />
+
 </beans>
\ No newline at end of file
diff --git a/idp-conf/src/main/resources/system/conf/profile-intercept-system.xml b/idp-conf/src/main/resources/system/conf/profile-intercept-system.xml
index 7a22e66..cdf1add 100644
--- a/idp-conf/src/main/resources/system/conf/profile-intercept-system.xml
+++ b/idp-conf/src/main/resources/system/conf/profile-intercept-system.xml
@@ -60,6 +60,9 @@
         </property>
     </bean>
 
+    <!-- Attribute release flow for attribute queries -->
+    <bean id="intercept/attribute-release-query" parent="shibboleth.consent.AttributeReleaseFlow" />
+
     <!-- Parent bean for terms of use consent flows. -->
     <bean id="shibboleth.consent.TermsOfUseFlow" abstract="true"
         class="net.shibboleth.idp.consent.flow.impl.ConsentFlowDescriptor"
diff --git a/idp-conf/src/main/resources/system/conf/webflow-config.xml b/idp-conf/src/main/resources/system/conf/webflow-config.xml
index df06b4c..97949db 100644
--- a/idp-conf/src/main/resources/system/conf/webflow-config.xml
+++ b/idp-conf/src/main/resources/system/conf/webflow-config.xml
@@ -120,6 +120,7 @@
                 <entry key="intercept/expiring-password" value="../system/flows/intercept/expiring-password-flow.xml" />
                 <entry key="intercept/terms-of-use" value="../system/flows/intercept/terms-of-use-flow.xml" />
                 <entry key="intercept/attribute-release" value="../system/flows/intercept/attribute-release-flow.xml" />
+                <entry key="intercept/attribute-release-query" value="../system/flows/intercept/attribute-release-query-flow.xml" />
                 <entry key="intercept/impersonate" value="../system/flows/intercept/impersonate-flow.xml" />
         
                 <!-- Inbound security processing of SAML messages, implemented as intercept flows. -->
diff --git a/idp-conf/src/main/resources/system/flows/intercept/attribute-release-query-beans.xml b/idp-conf/src/main/resources/system/flows/intercept/attribute-release-query-beans.xml
new file mode 100644
index 0000000..31febcc
--- /dev/null
+++ b/idp-conf/src/main/resources/system/flows/intercept/attribute-release-query-beans.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:context="http://www.springframework.org/schema/context" xmlns:c="http://www.springframework.org/schema/c"
+    xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
+    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">
+
+    <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"
+        p:placeholderPrefix="%{" p:placeholderSuffix="}" />
+
+    <bean class="net.shibboleth.ext.spring.config.IdentifiableBeanPostProcessor" />
+    <bean class="net.shibboleth.idp.profile.impl.ProfileActionBeanPostProcessor" />
+
+    <bean id="AttributeReleaseStorageContextLookupStrategy" class="com.google.common.base.Functions"
+        factory-method="constant" c:_0="intercept/attribute-release" />
+
+    <bean id="ReadAttributeReleaseConsentFromStorage"
+        class="net.shibboleth.idp.consent.flow.storage.impl.ReadConsentFromStorage" scope="prototype"
+        p:storageKeyLookupStrategy-ref="shibboleth.consent.UserAndRelyingPartyStorageKey"
+        p:storageSerializer-ref="shibboleth.consent.ConsentSerializer"
+        p:storageContextLookupStrategy-ref="AttributeReleaseStorageContextLookupStrategy" />
+
+    <bean id="ReadAttributeReleaseGlobalConsentFromStorage"
+        class="net.shibboleth.idp.consent.flow.storage.impl.ReadConsentFromStorage" scope="prototype"
+        p:storageKeyLookupStrategy-ref="shibboleth.consent.UserStorageKey"
+        p:storageContextLookupStrategy-ref="AttributeReleaseStorageContextLookupStrategy" />
+
+</beans>
diff --git a/idp-conf/src/main/resources/system/flows/intercept/attribute-release-query-flow.xml b/idp-conf/src/main/resources/system/flows/intercept/attribute-release-query-flow.xml
new file mode 100644
index 0000000..8d73e84
--- /dev/null
+++ b/idp-conf/src/main/resources/system/flows/intercept/attribute-release-query-flow.xml
@@ -0,0 +1,90 @@
+<flow xmlns="http://www.springframework.org/schema/webflow"
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"
+      parent="intercept.abstract">
+
+    <!-- Rudimentary impediment to direct execution of subflow. -->
+    <input name="calledAsSubflow" type="boolean" required="true" />
+
+
+    <!-- Attribute consent setup. -->
+    
+    <on-start>
+        <evaluate expression="AttributeConsentFlowDescriptorLookupStrategy.apply(opensamlProfileRequestContext)"
+            result="flowScope.attributeReleaseFlowDescriptor" />
+    </on-start>
+    
+    <action-state id="AttributeConsentSetup">
+        <evaluate expression="InitializeConsentContext" />
+        <evaluate expression="InitializeAttributeConsentContext" />
+        <evaluate expression="PopulateAttributeConsentContext" />
+        <!-- <evaluate expression="PopulatePreConsentAuditContext" /> -->
+        <evaluate expression="'proceed'" />
+
+        <transition on="proceed" to="ReadConsentFromStorage" />
+    </action-state>
+
+    <!-- Read consent from storage. -->
+
+    <action-state id="ReadConsentFromStorage">
+        <evaluate expression="ReadAttributeReleaseConsentFromStorage" />
+        <evaluate expression="'proceed'" />
+
+        <transition on="proceed" to="TestForReadGlobalAttributeConsentFromStorage" />
+    </action-state>
+
+    <decision-state id="TestForReadGlobalAttributeConsentFromStorage">
+        <if test="attributeReleaseFlowDescriptor.globalConsentAllowed"
+            then="ReadGlobalAttributeConsentFromStorage" else="CheckPreviousConsents" />
+    </decision-state>
+
+    <action-state id="ReadGlobalAttributeConsentFromStorage">
+        <evaluate expression="ReadAttributeReleaseGlobalConsentFromStorage" />
+        <evaluate expression="'proceed'" />
+
+        <transition on="proceed" to="TestForGlobalAttributeConsent" />
+    </action-state> 
+
+    <!-- If global consent has been given by user, skip the rest of the flow. -->
+    
+    <decision-state id="TestForGlobalAttributeConsent">
+        <if test="GlobalAttributeConsentPredicate.apply(opensamlProfileRequestContext)"
+            then="proceed" else="CheckPreviousConsents" />
+    </decision-state>
+    
+    <!-- If neither consent nor global consent was given previously, return an error -->
+    <decision-state id="CheckPreviousConsents">
+        <if test="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.consent.context.ConsentContext)).getPreviousConsents().isEmpty()"
+            then="InvalidProfileContext"
+            else="ReleaseAttributes" />
+    </decision-state>
+
+    <!-- Release attributes consented to as well as non-consentable attributes from attribute context. -->
+    
+    <!-- TODO auditing ? -->
+    
+    <action-state id="ReleaseAttributes">
+        <evaluate expression="ReleaseAttributes" />
+        <evaluate expression="'proceed'" />
+        
+        <transition on="proceed" to="proceed" />
+    </action-state>
+
+    <end-state id="proceed" />
+
+    <end-state id="Log">
+        <on-entry>
+            <!-- Log violation. -->
+            <evaluate expression="T(org.slf4j.LoggerFactory).getLogger('net.shibboleth.idp.attributeReleaseQuery').warn('Log end-state')" />
+        </on-entry>
+    </end-state>
+
+    <global-transitions>
+        <!-- Catch "InvalidAttributeContext" and short-circuit this intercept flow. -->
+        <transition on="InvalidAttributeContext" to="proceed" />
+    </global-transitions>
+
+    <bean-import resource="attribute-release-beans.xml" />
+    <bean-import resource="attribute-release-query-beans.xml" />
+
+</flow>
diff --git a/idp-conf/src/main/resources/system/flows/saml/saml2/attribute-query-beans.xml b/idp-conf/src/main/resources/system/flows/saml/saml2/attribute-query-beans.xml
index 77036b7..4d80acb 100644
--- a/idp-conf/src/main/resources/system/flows/saml/saml2/attribute-query-beans.xml
+++ b/idp-conf/src/main/resources/system/flows/saml/saml2/attribute-query-beans.xml
@@ -16,6 +16,7 @@
         p:placeholderPrefix="%{" p:placeholderSuffix="}" />
     
     <import resource="common-beans.xml" />
+    <import resource="../../../../conf/intercept/consent-intercept-config.xml" />
 
     <bean id="InitializeProfileRequestContext"
         class="net.shibboleth.idp.profile.impl.InitializeProfileRequestContext" scope="prototype"
@@ -68,4 +69,20 @@
         </property>
     </bean>
 
+    <bean id="PopulateConsentInterceptContext"
+        class="net.shibboleth.idp.profile.interceptor.impl.PopulateProfileInterceptorContext" scope="prototype">
+        <property name="availableFlows">
+            <bean class="org.springframework.beans.factory.config.ListFactoryBean">
+                <property name="sourceList">
+                    <list>
+                        <ref bean="intercept/attribute-release-query" />
+                    </list>
+                </property>
+            </bean>
+        </property>
+        <property name="activeFlowsLookupStrategy">
+            <bean class="com.google.common.base.Functions" factory-method="constant" c:_0="#{ {'attribute-release-query' } }" />
+        </property>
+    </bean>
+
 </beans>
diff --git a/idp-conf/src/main/resources/system/flows/saml/saml2/attribute-query-flow.xml b/idp-conf/src/main/resources/system/flows/saml/saml2/attribute-query-flow.xml
index 193266b..c747bd4 100644
--- a/idp-conf/src/main/resources/system/flows/saml/saml2/attribute-query-flow.xml
+++ b/idp-conf/src/main/resources/system/flows/saml/saml2/attribute-query-flow.xml
@@ -18,7 +18,27 @@
         <evaluate expression="ResolveAttributes" />
         <evaluate expression="FilterAttributes" />
         <evaluate expression="FilterByQueriedAttributes" />
+        <evaluate expression="'proceed'" />
+        <transition on="proceed" to="CheckConsentCondition" />
+    </action-state>
+
+    <decision-state id="CheckConsentCondition">
+        <if test="flowRequestContext.getActiveFlow().getApplicationContext().getBean('shibboleth.consent.AttributeQuery.Condition').apply(opensamlProfileRequestContext)"
+            then="ConsentSetup" else="ContinueProfileWork" />
+    </decision-state>
+
+    <action-state id="ConsentSetup">
+        <evaluate expression="PopulateConsentInterceptContext" />
+        <evaluate expression="opensamlProfileRequestContext.getSubcontext(T(net.shibboleth.idp.profile.context.ProfileInterceptorContext)).setAttemptedFlow(flowRequestContext.getActiveFlow().getApplicationContext().getBean('intercept/attribute-release-query'))" />
+        <transition on="success" to="ConsentFlow" />
+    </action-state>
+
+    <subflow-state id="ConsentFlow" subflow="intercept/attribute-release-query">
+        <input name="calledAsSubflow" value="true" />
+        <transition on="proceed" to="ContinueProfileWork"/>
+    </subflow-state>
 
+    <action-state id="ContinueProfileWork">
         <evaluate expression="AddResponseShell" />
         <evaluate expression="AddInResponseToToResponse" />
         
diff --git a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/saml2/SAML2TestStatusResponseTypeValidator.java b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/saml2/SAML2TestStatusResponseTypeValidator.java
index 83396d1..11cac53 100644
--- a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/saml2/SAML2TestStatusResponseTypeValidator.java
+++ b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/saml2/SAML2TestStatusResponseTypeValidator.java
@@ -109,7 +109,9 @@ public class SAML2TestStatusResponseTypeValidator {
         Assert.assertEquals(status.getStatusCode().getValue(), statusCode);
         if (statusCode != StatusCode.SUCCESS) {
             Assert.assertEquals(status.getStatusMessage().getMessage(), statusMessage);
-            Assert.assertEquals(status.getStatusCode().getStatusCode().getValue(), statusCodeNested);
+            if (status.getStatusCode().getStatusCode() != null) {
+                Assert.assertEquals(status.getStatusCode().getStatusCode().getValue(), statusCodeNested);
+            }
         }
     }
 }

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


More information about the commits mailing list