[java-plugin-shibd-saml] branch main updated: WIP on additional SAML data extraction.

Scott Cantor cantor.2 at osu.edu
Mon Sep 16 23:26:26 UTC 2024


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

scantor pushed a commit to branch main
in repository java-plugin-shibd-saml.

View the commit online:
http://git.shibboleth.net/view/?p=java-plugin-shibd-saml.git;a=commit;h=594e1897ba7948ec2e527d13cb07ff301d86c1e6

The following commit(s) were added to refs/heads/main by this push:
     new 594e189  WIP on additional SAML data extraction.
594e189 is described below

commit 594e1897ba7948ec2e527d13cb07ff301d86c1e6
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Sep 16 19:26:20 2024 -0400

    WIP on additional SAML data extraction.
---
 .../config/BrowserSSOProfileConfiguration.java     |  15 +
 .../idp/flows/sp/consumer/saml2/saml2-beans.xml    |  18 +-
 .../impl/BrowserSSOProfileConfiguration.java       |  29 ++
 .../saml2/profile/impl/ExtractSAMLAttributes.java  | 335 ++++++++++++++++++++-
 4 files changed, 383 insertions(+), 14 deletions(-)

diff --git a/sp-saml-api/src/main/java/net/shibboleth/sp/saml/saml2/profile/config/BrowserSSOProfileConfiguration.java b/sp-saml-api/src/main/java/net/shibboleth/sp/saml/saml2/profile/config/BrowserSSOProfileConfiguration.java
index 407b0ef..83a4466 100644
--- a/sp-saml-api/src/main/java/net/shibboleth/sp/saml/saml2/profile/config/BrowserSSOProfileConfiguration.java
+++ b/sp-saml-api/src/main/java/net/shibboleth/sp/saml/saml2/profile/config/BrowserSSOProfileConfiguration.java
@@ -66,6 +66,21 @@ public interface BrowserSSOProfileConfiguration extends SAMLArtifactConsumerProf
      */
     @Nullable String getResponseBinding(@Nullable final ProfileRequestContext profileRequestContext);
 
+    /**
+     * Get whether to perform extractioon of a set of "standard" information from a SAML response and
+     * assertions, primarily for compatibility with the older SP software.
+     * 
+     * <p>This is essentially a built-in extraction strategy that can be supplemented via
+     * {@link #getAttributeExtractionStrategy(ProfileRequestContext)}.</p> 
+     * 
+     * <p>Defaults to "true".</p>
+     * 
+     * @param profileRequestContext profile request context
+     * 
+     * @return whether to perform standard data extraction
+     */
+    boolean isExtractStandardAttributes(@Nullable final ProfileRequestContext profileRequestContext);
+    
     /**
      * Get a strategy function to apply to SAML responses to extract additional {@link IdPAttribute}
      * objects from the data.
diff --git a/sp-saml-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/consumer/saml2/saml2-beans.xml b/sp-saml-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/consumer/saml2/saml2-beans.xml
index 2850af4..f79800b 100644
--- a/sp-saml-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/consumer/saml2/saml2-beans.xml
+++ b/sp-saml-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/consumer/saml2/saml2-beans.xml
@@ -160,9 +160,25 @@
         </property>
     </bean>
 
+    <bean id="StandardExtractionStrategy"
+            class="net.shibboleth.sp.saml.saml2.profile.impl.ExtractSAMLAttributes.StandardExtractionStrategy"
+        p:issuerAttributeId="%{sp.saml.issuerAttributeId:}"
+        p:authnInstantAttributeId="%{sp.saml.authnInstantAttributeId:}"
+        p:authnContextClassRefAttributeId="%{sp.saml.authnContextClassRefAttributeId:}"
+        p:authnContextDeclRefAttributeId="%{sp.saml.authnContextDeclRefAttributeId:}"
+        p:sessionIndexAttributeId="%{sp.saml.sessionIndexAttributeId:}"
+        p:consentAttributeId="%{sp.saml.consentAttributeId:}"
+        p:authorityAttributeId="%{sp.saml.authorityAttributeId:}"
+        p:notBeforeAttributeId="%{sp.saml.notBeforeAttributeId:}"
+        p:notOnOrAfterAttributeId="%{sp.saml.notOnOrAfterAttributeId:}"
+        p:sessionNotOnOrAfterAttributeId="%{sp.saml.sessionNotOnOrAfterAttributeId:}"
+        p:addressAttributeId="%{sp.saml.addressAttributeId:}"
+        p:dNSNameAttributeId="%{sp.saml.dnsNameAttributeId:}" />
+
     <bean id="ExtractSAMLAttributes"
         class="net.shibboleth.sp.saml.saml2.profile.impl.ExtractSAMLAttributes" scope="prototype"
         p:responderLookupStrategy-ref="shibboleth.RelyingPartyIdLookup.Simple"
-        p:requesterLookupStrategy-ref="shibboleth.IssuerLookup.Simple" />
+        p:requesterLookupStrategy-ref="shibboleth.IssuerLookup.Simple"
+        p:standardExtractionStrategy-ref="StandardExtractionStrategy" />
 
 </beans>
diff --git a/sp-saml-impl/src/main/java/net/shibboleth/sp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java b/sp-saml-impl/src/main/java/net/shibboleth/sp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java
index baa3049..0a65837 100644
--- a/sp-saml-impl/src/main/java/net/shibboleth/sp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java
+++ b/sp-saml-impl/src/main/java/net/shibboleth/sp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java
@@ -80,6 +80,9 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionConsum
     /** Lookup function for response binding. */
     @Nonnull private Function<ProfileRequestContext,String> responseBindingLookupStrategy;
    
+    /** Whether to perform standard response data extraction. */
+    @Nonnull private Predicate<ProfileRequestContext> extractStandardAttributesPredicate;
+    
     /** Lookup function for attribute extraction strategy. */
     @Nonnull Function<ProfileRequestContext,Function<ProfileRequestContext,Collection<IdPAttribute>>>
     attributeExtractionStrategyLookupStrategy;
@@ -108,6 +111,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionConsum
         attributeIndexLookupStrategy = FunctionSupport.constant(null);
         requestedAttributesLookupStrategy = FunctionSupport.constant(null);
         responseBindingLookupStrategy = FunctionSupport.constant(SAMLConstants.SAML2_POST_BINDING_URI);
+        extractStandardAttributesPredicate = PredicateSupport.alwaysTrue();
         attributeExtractionStrategyLookupStrategy = FunctionSupport.constant(null);
     }
 
@@ -417,6 +421,31 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionConsum
         responseBindingLookupStrategy =
                 Constraint.isNotNull(strategy, "Response binding lookup strategy cannot be null");
     }
+    
+
+    /** {@inheritDoc} */
+    public boolean isExtractStandardAttributes(@Nullable ProfileRequestContext profileRequestContext) {
+        return extractStandardAttributesPredicate.test(profileRequestContext);
+    }
+    
+    /**
+     * Set whether to perform standard data extraction.
+     * 
+     * @param flag flag to set
+     */
+    public void setExtractStandardAttributes(final boolean flag) {
+        extractStandardAttributesPredicate = flag ? PredicateSupport.alwaysTrue() : PredicateSupport.alwaysFalse();
+    }
+    
+    /**
+     * Set a condition for whether to perform standard data extraction.
+     * 
+     * @param condition condition to set
+     */
+    public void setExtractStandardAttributesPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
+        extractStandardAttributesPredicate =
+                Constraint.isNotNull(condition, "Standard extraction predicate cannot be null");
+    }
 
     /** {@inheritDoc} */
     @Nullable public Function<ProfileRequestContext,Collection<IdPAttribute>> getAttributeExtractionStrategy(
diff --git a/sp-saml-impl/src/main/java/net/shibboleth/sp/saml/saml2/profile/impl/ExtractSAMLAttributes.java b/sp-saml-impl/src/main/java/net/shibboleth/sp/saml/saml2/profile/impl/ExtractSAMLAttributes.java
index 8bbbec0..930168c 100644
--- a/sp-saml-impl/src/main/java/net/shibboleth/sp/saml/saml2/profile/impl/ExtractSAMLAttributes.java
+++ b/sp-saml-impl/src/main/java/net/shibboleth/sp/saml/saml2/profile/impl/ExtractSAMLAttributes.java
@@ -20,6 +20,7 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.opensaml.messaging.context.MessageContext;
 import org.opensaml.messaging.context.navigate.ChildContextLookup;
@@ -31,14 +32,26 @@ import org.opensaml.saml.metadata.resolver.MetadataResolver;
 import org.opensaml.saml.saml2.core.Assertion;
 import org.opensaml.saml.saml2.core.Attribute;
 import org.opensaml.saml.saml2.core.AttributeStatement;
+import org.opensaml.saml.saml2.core.AuthenticatingAuthority;
+import org.opensaml.saml.saml2.core.AuthnContext;
+import org.opensaml.saml.saml2.core.AuthnContextClassRef;
+import org.opensaml.saml.saml2.core.AuthnContextDeclRef;
+import org.opensaml.saml.saml2.core.AuthnStatement;
+import org.opensaml.saml.saml2.core.Conditions;
+import org.opensaml.saml.saml2.core.Issuer;
 import org.opensaml.saml.saml2.core.Response;
+import org.opensaml.saml.saml2.core.StatusResponseType;
+import org.opensaml.saml.saml2.core.SubjectLocality;
 import org.slf4j.Logger;
 
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
 
 import net.shibboleth.idp.attribute.AttributeDecodingException;
+import net.shibboleth.idp.attribute.DateTimeAttributeValue;
 import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.idp.attribute.IdPAttributeValue;
+import net.shibboleth.idp.attribute.StringAttributeValue;
 import net.shibboleth.idp.attribute.context.AttributeContext;
 import net.shibboleth.idp.attribute.filter.AttributeFilter;
 import net.shibboleth.idp.attribute.filter.AttributeFilterException;
@@ -56,8 +69,10 @@ import net.shibboleth.saml.profile.context.navigate.SAMLMetadataContextLookupFun
 import net.shibboleth.shared.annotation.constraint.Live;
 import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
 import net.shibboleth.shared.service.ServiceException;
 import net.shibboleth.shared.service.ServiceableComponent;
 import net.shibboleth.sp.profile.AbstractApplicationAction;
@@ -98,7 +113,10 @@ public class ExtractSAMLAttributes extends AbstractApplicationAction {
     
     /** Strategy used to create {@link AttributeContext} to hold results. */
     @Nonnull private Function<ProfileRequestContext,AttributeContext> attributeContextCreationStrategy;
-
+    
+    /** Strategy for pulling out "standard" data from the response. */
+    @Nullable private Function<SAMLTokenContext,Collection<IdPAttribute>> standardExtractionStrategy;
+    
     /** Context containing the token(s) to process. */
     @NonnullBeforeExec private SAMLTokenContext samlTokenContext;
     
@@ -177,6 +195,17 @@ public class ExtractSAMLAttributes extends AbstractApplicationAction {
                 Constraint.isNotNull(strategy, "AttributeContext creation strategy cannot be null");
     }
     
+    /**
+     * Set the strategy function to call for "standard" attribute extraction, if enabled.
+     * 
+     * @param strategy strategy function
+     */
+    public void setStandardExtractionStrategy(
+            @Nullable final Function<SAMLTokenContext,Collection<IdPAttribute>> strategy) {
+        checkSetterPreconditions();
+        standardExtractionStrategy = strategy;
+    }
+
     /** {@inheritDoc} */
     @Override
     protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -185,9 +214,9 @@ public class ExtractSAMLAttributes extends AbstractApplicationAction {
             return false;
         }
         
-        samlTokenContext = this.samlTokenContextLookupStrategy.apply(profileRequestContext);
-        if (samlTokenContext == null) {
-            log.debug("{} No SAMLAuthnContext available", getLogPrefix());
+        samlTokenContext = samlTokenContextLookupStrategy.apply(profileRequestContext);
+        if (samlTokenContext == null || samlTokenContext.getAuthnStatement() == null) {
+            log.debug("{} No SAMLAuthnContext or AuthnStatement available", getLogPrefix());
             ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
             return false;
         }
@@ -224,13 +253,31 @@ public class ExtractSAMLAttributes extends AbstractApplicationAction {
         
         processAttributes(profileRequestContext);
         
+        // TODO: NameID handling
+        
+        // Extract standard attributes.
+        if (standardExtractionStrategy != null &&
+                profileConfiguration.isExtractStandardAttributes(profileRequestContext)) {
+            log.debug("{} Extracting standard attributes", getLogPrefix());
+            final Collection<IdPAttribute> standards = standardExtractionStrategy.apply(samlTokenContext);
+            if (standards != null && !standards.isEmpty()) {
+                if (log.isDebugEnabled()) {
+                    log.debug("{} Extracted standard attributes: {}", getLogPrefix(),
+                            standards.stream().map(IdPAttribute::getId).collect(Collectors.toUnmodifiableList()));
+                }
+                final Collection<IdPAttribute> attributes = new ArrayList<>(attributeContext.getIdPAttributes().values());
+                attributes.addAll(standards);
+                attributeContext.setIdPAttributes(attributes);
+            }
+        }
+
         final Function<ProfileRequestContext,Collection<IdPAttribute>> aes =
                 profileConfiguration.getAttributeExtractionStrategy(profileRequestContext);
         if (aes != null) {
             log.debug("{} Applying custom attribute extraction strategy", getLogPrefix());
             final Collection<IdPAttribute> attributes = new ArrayList<>(attributeContext.getIdPAttributes().values());
             final Collection<IdPAttribute> newAttributes = aes.apply(profileRequestContext);
-            if (newAttributes != null) {
+            if (newAttributes != null && !newAttributes.isEmpty()) {
                 if (log.isDebugEnabled()) {
                     log.debug("{} Extracted attributes with custom strategy: {}", getLogPrefix(),
                             newAttributes.stream().map(IdPAttribute::getId).collect(Collectors.toUnmodifiableList()));
@@ -239,10 +286,18 @@ public class ExtractSAMLAttributes extends AbstractApplicationAction {
                 attributeContext.setIdPAttributes(attributes);
             }
         }
-        
-        // TODO: NameID handling
-        
-        // TODO: built-in variables if handled here
+    }
+    
+    /**
+     * Get the inbound {@link Response} message.
+     * 
+     * @param profileRequestContext profile request context
+     * 
+     * @return inbound message
+     */
+    @Nonnull private Response getResponse(@Nonnull final ProfileRequestContext profileRequestContext) {
+        final MessageContext inbound = profileRequestContext.ensureInboundMessageContext();
+        return (Response) inbound.ensureMessage();
     }
     
     /**
@@ -259,10 +314,7 @@ public class ExtractSAMLAttributes extends AbstractApplicationAction {
 
         try (final ServiceableComponent<AttributeTranscoderRegistry> component =
                 ensureApplication().getAttributeTranscoderRegistry().getServiceableComponent()) {
-            final MessageContext imc = profileRequestContext.getInboundMessageContext();
-            assert imc != null;
-            final Response response = (Response) imc.getMessage();
-            assert response != null;
+            final Response response = getResponse(profileRequestContext);
             for (final Assertion assertion : response.getAssertions()) {
                 for (final AttributeStatement statement : assertion.getAttributeStatements()) {
                     for (final Attribute designator : statement.getAttributes()) {
@@ -370,5 +422,262 @@ public class ExtractSAMLAttributes extends AbstractApplicationAction {
             .setAttributeIssuerID(issuerLookupStrategy.apply(profileRequestContext))
             .setAttributeRecipientID(requesterLookupStrategy.apply(profileRequestContext));
     }
+    
+    /**
+     * Built-in function to perform "standard" extraction of data into attributes.
+     */
+    public static class StandardExtractionStrategy implements Function<SAMLTokenContext,Collection<IdPAttribute>> {
+
+        /** Attribute ID holding issuer. */
+        @Nullable private String issuerAttributeId;
+        
+        /** Attribute ID holding authentication instant. */
+        @Nullable private String authnInstantAttributeId;
+
+        /** Attribute ID holding AuthnContext class ref. */
+        @Nullable private String authnContextClassRefAttributeId;
+
+        /** Attribute ID holding AuthnContext decl ref. */
+        @Nullable private String authnContextDeclRefAttributeId;
+
+        /** Attribute ID holding SessionIndex. */
+        @Nullable private String sessionIndexAttributeId;
+
+        /** Attribute ID holding Consent. */
+        @Nullable private String consentAttributeId;
+        
+        /** Attribute ID holding AuthenticationAuthority value(s). */
+        @Nullable private String authorityAttributeId;
+
+        /** Attribute ID holding NotBefore. */
+        @Nullable private String notBeforeAttributeId;
+
+        /** Attribute ID holding NotOnOrAfter. */
+        @Nullable private String notOnOrAfterAttributeId;
+
+        /** Attribute ID holding SessionNotOnOrAfter. */
+        @Nullable private String sessionNotOnOrAfterAttributeId;
+
+        /** Attribute ID holding Address. */
+        @Nullable private String addressAttributeId;
+
+        /** Attribute ID holding DNSName. */
+        @Nullable private String dnsNameAttributeId;
+        
+        /**
+         * Set {@link IdPAttribute} ID for {@link Issuer#getValue()}.
+         * 
+         * @param id attribute ID to use, null to omit
+         */
+        public void setIssuerAttributeId(@Nullable final String id) {
+            issuerAttributeId = StringSupport.trimOrNull(id);
+        }
+
+        /**
+         * Set {@link IdPAttribute} ID for {@link AuthnStatement#getAuthnInstant()}.
+         * 
+         * @param id attribute ID to use, null to omit
+         */
+        public void setAuthnInstantAttributeId(@Nullable final String id) {
+            authnInstantAttributeId = StringSupport.trimOrNull(id);
+        }
+
+        /**
+         * Set {@link IdPAttribute} ID for {@link AuthnContext#getAuthnContextClassRef()}.
+         * 
+         * @param id attribute ID to use, null to omit
+         */
+        public void setAuthnContextClassRefAttributeId(@Nullable final String id) {
+            authnContextClassRefAttributeId = StringSupport.trimOrNull(id);
+        }
+
+        /**
+         * Set {@link IdPAttribute} ID for {@link AuthnContext#getAuthnContextDeclRef()}.
+         * 
+         * @param id attribute ID to use, null to omit
+         */
+        public void setAuthnContextDeclRefAttributeId(@Nullable final String id) {
+            authnContextDeclRefAttributeId = StringSupport.trimOrNull(id);
+        }
+
+        /**
+         * Set {@link IdPAttribute} ID for {@link AuthnStatement#getSessionIndex()}.
+         * 
+         * @param id attribute ID to use, null to omit
+         */
+        public void setSessionIndexAttributeId(@Nullable final String id) {
+            sessionIndexAttributeId = StringSupport.trimOrNull(id);
+        }
+
+        /**
+         * Set {@link IdPAttribute} ID for {@link StatusResponseType#getConsent()}.
+         * 
+         * @param id attribute ID to use, null to omit
+         */
+        public void setConsentAttributeId(@Nullable final String id) {
+            consentAttributeId = StringSupport.trimOrNull(id);
+        }
+
+        /**
+         * Set {@link IdPAttribute} ID for {@link AuthnContext#getAuthenticatingAuthorities()}.
+         * 
+         * @param id attribute ID to use, null to omit
+         */
+        public void setAuthenticatingAuthorityAttributeId(@Nullable final String id) {
+            authorityAttributeId = StringSupport.trimOrNull(id);
+        }
+
+        /**
+         * Set {@link IdPAttribute} ID for {@link Conditions#getNotBefore()}.
+         * 
+         * @param id attribute ID to use, null to omit
+         */
+        public void setNotBeforeAttributeId(@Nullable final String id) {
+            notBeforeAttributeId = StringSupport.trimOrNull(id);
+        }
+
+        /**
+         * Set {@link IdPAttribute} ID for {@link Conditions#getNotOnOrAfter()}.
+         * 
+         * @param id attribute ID to use, null to omit
+         */
+        public void setNotOnOrAfterAttributeId(@Nullable final String id) {
+            notOnOrAfterAttributeId = StringSupport.trimOrNull(id);
+        }
+
+        /**
+         * Set {@link IdPAttribute} ID for {@link AuthnStatement#getSessionNotOnOrAfter()}.
+         * 
+         * @param id attribute ID to use, null to omit
+         */
+        public void setSessionNotOnOrAfterAttributeId(@Nullable final String id) {
+            sessionNotOnOrAfterAttributeId = StringSupport.trimOrNull(id);
+        }
+        
+        /**
+         * Set {@link IdPAttribute} ID for {@link SubjectLocality#getAddress()}.
+         * 
+         * @param id attribute ID to use, null to omit
+         */
+        public void setAddressAttributeId(@Nullable final String id) {
+            addressAttributeId = StringSupport.trimOrNull(id);
+        }
+
+        /**
+         * Set {@link IdPAttribute} ID for {@link SubjectLocality#getDNSName()}.
+         * 
+         * @param id attribute ID to use, null to omit
+         */
+        public void setDNSNameAttributeId(@Nullable final String id) {
+            dnsNameAttributeId = StringSupport.trimOrNull(id);
+        }
+
+        /** {@inheritDoc} */
+        @Nullable public Collection<IdPAttribute> apply(@Nullable final SAMLTokenContext samlTokenContext) {
+            final AuthnStatement statement = samlTokenContext != null ? samlTokenContext.getAuthnStatement() : null;
+            if (statement == null) {
+                return null;
+            }
+
+            final Assertion assertion = (Assertion) statement.getParent();
+            assert assertion != null;
+            
+            final Collection<IdPAttribute> attributes = new ArrayList<>();
+            
+            if (issuerAttributeId != null) {
+                final Issuer issuer = assertion.getIssuer();
+                if (issuer != null && issuer.getValue() != null) {
+                    final IdPAttribute attr = new IdPAttribute(issuerAttributeId);
+                    attr.setValues(CollectionSupport.singletonList(new StringAttributeValue(issuer.getValue())));
+                    attributes.add(attr);
+                }
+            }
+            
+            if (authnInstantAttributeId != null && statement.getAuthnInstant() != null) {
+                final IdPAttribute attr = new IdPAttribute(authnInstantAttributeId);
+                attr.setValues(CollectionSupport.singletonList(new DateTimeAttributeValue(statement.getAuthnInstant())));
+                attributes.add(attr);
+            }
+
+            final AuthnContext ac = statement.getAuthnContext();
+            
+            final AuthnContextClassRef classRef = ac != null ? ac.getAuthnContextClassRef() : null;
+            if (authnContextClassRefAttributeId != null && classRef != null && classRef.getURI() != null) {
+                final IdPAttribute attr = new IdPAttribute(authnContextClassRefAttributeId);
+                attr.setValues(CollectionSupport.singletonList(new StringAttributeValue(classRef.getURI())));
+                attributes.add(attr);
+            }
+            
+            final AuthnContextDeclRef declRef = ac != null ? ac.getAuthnContextDeclRef() : null;
+            if (authnContextDeclRefAttributeId != null && declRef != null && declRef.getURI() != null) {
+                final IdPAttribute attr = new IdPAttribute(authnContextDeclRefAttributeId);
+                attr.setValues(CollectionSupport.singletonList(new StringAttributeValue(declRef.getURI())));
+                attributes.add(attr);
+            }
+
+            if (sessionIndexAttributeId != null && statement.getSessionIndex() != null) {
+                final IdPAttribute attr = new IdPAttribute(sessionIndexAttributeId);
+                attr.setValues(CollectionSupport.singletonList(new StringAttributeValue(statement.getSessionIndex())));
+                attributes.add(attr);
+            }
+            
+            if (consentAttributeId != null) {
+                final String consent = ((StatusResponseType) assertion.getParent()).getConsent();
+                if (consent != null) {
+                    final IdPAttribute attr = new IdPAttribute(consentAttributeId);
+                    attr.setValues(CollectionSupport.singletonList(new StringAttributeValue(consent)));
+                    attributes.add(attr);
+                }
+            }
+            
+            if (authorityAttributeId != null && ac != null && !ac.getAuthenticatingAuthorities().isEmpty()) {
+                final IdPAttribute attr = new IdPAttribute(authorityAttributeId);
+                attr.setValues(
+                    ac.getAuthenticatingAuthorities().stream()
+                        .map(AuthenticatingAuthority::getURI)
+                        .map(StringAttributeValue::new)
+                        .collect(CollectionSupport.nonnullCollector(
+                                Collectors.<IdPAttributeValue>toUnmodifiableList())).get());
+                attributes.add(attr);
+            }
+            
+            final Conditions conditions = assertion.getConditions();
+            
+            if (notBeforeAttributeId != null && conditions != null && conditions.getNotBefore() != null) {
+                final IdPAttribute attr = new IdPAttribute(notBeforeAttributeId);
+                attr.setValues(CollectionSupport.singletonList(new DateTimeAttributeValue(conditions.getNotBefore())));
+                attributes.add(attr);
+            }
+
+            if (notOnOrAfterAttributeId != null && conditions != null && conditions.getNotOnOrAfter() != null) {
+                final IdPAttribute attr = new IdPAttribute(notOnOrAfterAttributeId);
+                attr.setValues(CollectionSupport.singletonList(new DateTimeAttributeValue(conditions.getNotOnOrAfter())));
+                attributes.add(attr);
+            }
+            
+            if (sessionNotOnOrAfterAttributeId != null && statement.getSessionNotOnOrAfter() != null) {
+                final IdPAttribute attr = new IdPAttribute(sessionNotOnOrAfterAttributeId);
+                attr.setValues(CollectionSupport.singletonList(
+                        new DateTimeAttributeValue(statement.getSessionNotOnOrAfter())));
+                attributes.add(attr);
+            }
+            
+            final SubjectLocality locality = statement.getSubjectLocality();
+            
+            if (addressAttributeId != null && locality != null && locality.getAddress() != null) {
+                final IdPAttribute attr = new IdPAttribute(addressAttributeId);
+                attr.setValues(CollectionSupport.singletonList(new StringAttributeValue(locality.getAddress())));
+                attributes.add(attr);
+            }
+     
+            if (dnsNameAttributeId != null && locality != null && locality.getDNSName() != null) {
+                final IdPAttribute attr = new IdPAttribute(dnsNameAttributeId);
+                attr.setValues(CollectionSupport.singletonList(new StringAttributeValue(locality.getDNSName())));
+                attributes.add(attr);
+            }
+            
+            return attributes;
+        }
+    }
 
 }
\ 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