Code clean up
authorlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Sat, 18 Aug 2007 11:15:49 +0000 (11:15 +0000)
committerlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Sat, 18 Aug 2007 11:15:49 +0000 (11:15 +0000)
Minor method renames
Add explicit incoming/outgoing bindings to handler config
Add in stubs for artifact handlers
Create Shibboleth SSO endpoint selector that validates against metadata

git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@2332 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

16 files changed:
resources/classpath/schema/shibboleth-2.0-idp-profile-handler.xsd
resources/conf/handler.xml
resources/conf/internal.xml
src/edu/internet2/middleware/shibboleth/idp/config/profile/AbstractSAMLProfileHandlerBeanDefinitionParser.java
src/edu/internet2/middleware/shibboleth/idp/config/profile/saml1/SAML1AttributeQueryProfileHandlerBeanDefinitionParser.java
src/edu/internet2/middleware/shibboleth/idp/config/profile/saml2/SAML2AttributeQueryProfileHandlerBeanDefinitionParser.java
src/edu/internet2/middleware/shibboleth/idp/config/profile/saml2/SAML2SSOProfileHandlerBeanDefinitionParser.java
src/edu/internet2/middleware/shibboleth/idp/profile/AbstractSAMLProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/AbstractSAML1ProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/AttributeQueryProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/ShibbolethSSODecoder.java [new file with mode: 0644]
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/ShibbolethSSOEndpointSelector.java [new file with mode: 0644]
src/edu/internet2/middleware/shibboleth/idp/profile/saml1/ShibbolethSSOProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/AbstractSAML2ProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/AttributeQueryProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/SSOProfileHandler.java

index a9edb29..190abc1 100644 (file)
                         </xsd:documentation>
                     </xsd:annotation>
                 </xsd:attribute>
-                <xsd:attribute name="decodingBinding" type="xsd:anyURI"
-                    default="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
-                    <xsd:annotation>
-                        <xsd:documentation>
-                            The URI of the binding used when decoding requests from relying parties.
-                        </xsd:documentation>
-                    </xsd:annotation>
-                </xsd:attribute>
-                <xsd:attribute name="securityPolicyFactoryId" type="xsd:string"
-                    default="shibboleth.SAML2SSOMessageSecurityPolicyFactory">
-                    <xsd:annotation>
-                        <xsd:documentation>
-                            The component ID of the security policy factory to use with the profile handler.
-
-                            This setting should not be changed from its default unless the deployer fully understands
-                            the inter-relationship between IdP components.
-                        </xsd:documentation>
-                    </xsd:annotation>
-                </xsd:attribute>
-                <xsd:attribute name="outboundBindingEnumeration"
-                    default="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
-                    <xsd:annotation>
-                        <xsd:documentation>
-                            An ordered list of outbound bindings supported by this profile handler. The order provided
-                            establishs the precedence given the bindings such that, from the left to right, the first
-                            binding also supported by the relying party will be used.
-                        </xsd:documentation>
-                    </xsd:annotation>
-                    <xsd:simpleType>
-                        <xsd:list itemType="xsd:anyURI" />
-                    </xsd:simpleType>
-                </xsd:attribute>
             </xsd:extension>
         </xsd:complexContent>
     </xsd:complexType>
             <xsd:documentation>Configuration type for SAML 2 Attribute Query profile handlers.</xsd:documentation>
         </xsd:annotation>
         <xsd:complexContent>
-            <xsd:extension base="SAML2ProfileHandler">
-                <xsd:attribute name="securityPolicyFactoryId" type="xsd:string"
-                    default="shibboleth.SAML2AttributeQueryMessageSecurityPolicyFactory">
-                    <xsd:annotation>
-                        <xsd:documentation>
-                            The component ID of the security policy factory to use with the profile handler.
-
-                            This setting should not be changed from its default unless the deployer fully understands
-                            the inter-relationship between IdP components.
-                        </xsd:documentation>
-                    </xsd:annotation>
-                </xsd:attribute>
-            </xsd:extension>
+            <xsd:extension base="SAML2ProfileHandler" />
         </xsd:complexContent>
     </xsd:complexType>
 
                         </xsd:documentation>
                     </xsd:annotation>
                 </xsd:attribute>
-                <xsd:attribute name="outboundBindingEnumeration"
-                    default="urn:oasis:names:tc:SAML:1.0:profiles:browser-post">
-                    <xsd:annotation>
-                        <xsd:documentation>
-                            An ordered list of outbound bindings supported by this profile handler. The order provided
-                            establishs the precedence given the bindings such that, from the left to right, the first
-                            binding also supported by the relying party will be used.
-                        </xsd:documentation>
-                    </xsd:annotation>
-                    <xsd:simpleType>
-                        <xsd:list itemType="xsd:anyURI" />
-                    </xsd:simpleType>
-                </xsd:attribute>
             </xsd:extension>
         </xsd:complexContent>
     </xsd:complexType>
             <xsd:documentation>Configuration type for SAML 1 Attribute Query profile handlers.</xsd:documentation>
         </xsd:annotation>
         <xsd:complexContent>
-            <xsd:extension base="SAML1ProfileHandler">
-                <xsd:attribute name="securityPolicyFactoryId" type="xsd:string"
-                    default="shibboleth.SAML1AttributeQueryMessageSecurityPolicyFactory">
-                    <xsd:annotation>
-                        <xsd:documentation>
-                            The component ID of the security policy factory to use with the profile handler.
-
-                            This setting should not be changed from its default unless the deployer fully understands
-                            the inter-relationship between IdP components.
-                        </xsd:documentation>
-                    </xsd:annotation>
-                </xsd:attribute>
-            </xsd:extension>
+            <xsd:extension base="SAML1ProfileHandler" />
         </xsd:complexContent>
     </xsd:complexType>
 
         </xsd:annotation>
         <xsd:complexContent>
             <xsd:extension base="IdPProfileHandlerType">
-                <xsd:attribute name="messageDecoderFactoryId" type="xsd:string"
-                    default="shibboleth.MessageDecoderFactory">
+                <xsd:attribute name="idGeneratorId" type="xsd:string" default="shibboleth.IdGenerator">
                     <xsd:annotation>
                         <xsd:documentation>
-                            The component ID of the message decoder to use with the profile handler.
+                            The component ID of a generator used to generated things like response and assertion IDs.
 
                             This setting should not be changed from its default unless the deployer fully understands
                             the inter-relationship between IdP components.
                         </xsd:documentation>
                     </xsd:annotation>
                 </xsd:attribute>
-                <xsd:attribute name="messageEncoderFactoryId" type="xsd:string"
-                    default="shibboleth.MessageEncoderFactory">
+                <xsd:attribute name="inboundBinding" type="xsd:anyURI" use="required">
                     <xsd:annotation>
                         <xsd:documentation>
-                            The component ID of the message encoder to use with the profile handler.
-
-                            This setting should not be changed from its default unless the deployer fully understands
-                            the inter-relationship between IdP components.
+                            The SAML message binding used by inbound messages.
                         </xsd:documentation>
                     </xsd:annotation>
                 </xsd:attribute>
-                <xsd:attribute name="idGeneratorId" type="xsd:string" default="shibboleth.IdGenerator">
+                <xsd:attribute name="outboundBindingEnumeration" >
                     <xsd:annotation>
                         <xsd:documentation>
-                            The component ID of a generator used to generated things like response and assertion IDs.
-
-                            This setting should not be changed from its default unless the deployer fully understands
-                            the inter-relationship between IdP components.
+                            An ordered list of outbound bindings supported by this profile handler. The order provided
+                            establishes the precedence given the bindings such that, from the left to right, the first
+                            binding also supported by the relying party will be used.
                         </xsd:documentation>
                     </xsd:annotation>
+                    <xsd:simpleType>
+                        <xsd:list itemType="xsd:anyURI" />
+                    </xsd:simpleType>
                 </xsd:attribute>
             </xsd:extension>
         </xsd:complexContent>
index d966c54..f071e80 100644 (file)
         <RequestPath>/status</RequestPath>
     </ProfileHandler>
 
-    <ProfileHandler xsi:type="ShibbolethSSO">
+    <ProfileHandler xsi:type="ShibbolethSSO"
+                    inboundBinding="urn:mace:shibboleth:1.0:profiles:AuthnRequest"
+                    outboundBindingEnumeration="urn:oasis:names:tc:SAML:1.0:profiles:browser-post 
+                                                urn:oasis:names:tc:SAML:1.0:profiles:artifact-01">
         <RequestPath>/shibboleth/SSO</RequestPath>
     </ProfileHandler>
     
-    <ProfileHandler xsi:type="SAML1AttributeQuery">
+    <ProfileHandler xsi:type="SAML1AttributeQuery" 
+                    inboundBinding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding"
+                    outboundBinding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding">
         <RequestPath>/saml1/SOAP/AttributeQuery</RequestPath>
     </ProfileHandler>
     
-    <ProfileHandler xsi:type="SAML2SSO">
+    <ProfileHandler xsi:type="SAML2SSO" 
+                    inboundBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+                    outboundBindingEnumeration="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST 
+                                                urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact">
         <RequestPath>/saml2/POST/SSO</RequestPath>
     </ProfileHandler>
 
-    <ProfileHandler xsi:type="SAML2SSO" decodingBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect">
+    <ProfileHandler xsi:type="SAML2SSO" 
+                    inboundBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
+                    outboundBindingEnumeration="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST 
+                                                urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact">
         <RequestPath>/saml2/Redirect/SSO</RequestPath>
     </ProfileHandler>
     
-    <ProfileHandler xsi:type="SAML2AttributeQuery">
+    <ProfileHandler xsi:type="SAML2AttributeQuery"
+                    inboundBinding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
+                    outboundBindingEnumeration="urn:oasis:names:tc:SAML:2.0:bindings:SOAP">
         <RequestPath>/saml2/SOAP/AttributeQuery</RequestPath>
     </ProfileHandler>
     
@@ -35,7 +48,7 @@
     </AuthenticationHandler>
     
     <AuthenticationHandler xsi:type="UsernamePassword" 
-                           jaasConfigurationLocation="file://$IDP_HOME/conf/login.confg">
+                           jaasConfigurationLocation="file://$IDP_HOME/conf/login.config">
         <AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthenticationMethod>
     </AuthenticationHandler>
 
index 45c03f5..391634a 100644 (file)
@@ -1,10 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
 <beans xmlns="http://www.springframework.org/schema/beans" 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-2.0.xsd">
-    
+    xmlns:util="http://www.springframework.org/schema/util"
+    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
+                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
+
     <!-- Spring configuration file that boostraps OpenSAML -->
-    <bean id="shibboleth.OpensamlConfig" class="edu.internet2.middleware.shibboleth.common.config.OpensamlConfigBean" lazy-init="false">
+    <bean id="shibboleth.OpensamlConfig" class="edu.internet2.middleware.shibboleth.common.config.OpensamlConfigBean"
+        lazy-init="false">
         <constructor-arg>
             <list>
                 <bean id="default" class="org.opensaml.util.resource.ClasspathResource">
                 </bean>
                 <bean id="saml2MetadataQuery" class="org.opensaml.util.resource.ClasspathResource">
                     <constructor-arg value="/saml2-metadata-query-config.xml" />
-                </bean>               
+                </bean>
             </list>
         </constructor-arg>
     </bean>
-    
+
     <bean id="shibboleth.IdGenerator" class="org.opensaml.common.impl.SecureRandomIdentifierGenerator">
         <constructor-arg value="SHA1PRNG" />
     </bean>
 
-    <bean id="shibboleth.VelocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean" >
+    <bean id="shibboleth.VelocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
         <property name="velocityProperties">
             <props>
                 <prop key="resource.loader">classpath, string</prop>
@@ -67,8 +70,9 @@
             </props>
         </property>
     </bean>
-    
-    <bean id="shibboleth.TemplateEngine" class="edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector.TemplateEngine" >
+
+    <bean id="shibboleth.TemplateEngine"
+        class="edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.dataConnector.TemplateEngine">
         <constructor-arg ref="shibboleth.VelocityEngine" />
     </bean>
 
         <property name="ignoreElementContentWhitespace" value="true" />
         <property name="namespaceAware" value="true" />
     </bean>
-    
-    <bean id="shibboleth.SAML2SSOMessageSecurityPolicyFactory"
-          parent="shibboleth.BaseSAML2SecurityPolicyFactory">
-        <property name="issuerRole">
-            <bean id="shibboleth.SAML2SSORole" class="javax.xml.namespace.QName">
-                <constructor-arg value="urn:oasis:names:tc:SAML:2.0:metadata" />
-                <constructor-arg value="SPSSODescriptor" />
+
+    <util:map id="shibboleth.MessageDecoders">
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST</value>
+            </key>
+            <bean id="shibboleth.SAML2HttpPostDecoder" class="org.opensaml.saml2.binding.decoding.HTTPPostDecoder">
+                <constructor-arg ref="shibboleth.ParserPool" />
             </bean>
-        </property>
-    </bean>
-    
-    <bean id="shibboleth.SAML2AttributeQueryMessageSecurityPolicyFactory"
-          parent="shibboleth.BaseSAML2SecurityPolicyFactory">
-        <property name="issuerRole">
-            <bean id="shibboleth.SAML2AttributeQueryRole" class="javax.xml.namespace.QName">
-                <constructor-arg value="urn:oasis:names:tc:SAML:2.0:metadata" />
-                <constructor-arg value="SPSSODescriptor" />
+        </entry>
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect</value>
+            </key>
+            <bean id="shibboleth.SAML2HttpRedirectDecoder"
+                class="org.opensaml.saml2.binding.decoding.HTTPRedirectDeflateDecoder">
+                <constructor-arg ref="shibboleth.ParserPool" />
             </bean>
-        </property>
-    </bean>
-    
-    <bean id="shibboleth.BaseSAML2SecurityPolicyFactory" abstract="true" class="org.opensaml.common.binding.security.SAMLSecurityPolicyFactory">
-        <property name="issuerProtocol" value="urn:oasis:names:tc:SAML:2.0:protocol" />
-        <property name="policyRuleFactories">
-            <list>
-                <ref bean="shibboleth.SAML2ProtocolMessageRuleFactory" />
-                <!-- Removed for testing -->
-                <!-- ref bean="shibboleth.MessageIssueInstantRuleFactory" /-->
-            </list>
-        </property>
-        <!-- Turn off for testing -->
-        <property name="requiredAuthenticatedIssuer" value="false" />
-    </bean>
-    
-    <bean id="shibboleth.SAML1AttributeQueryMessageSecurityPolicyFactory"
-          parent="shibboleth.BaseSAML1SecurityPolicyFactory">
-        <property name="issuerRole">
-            <bean id="shibboleth.SAML1AttributeQueryRole" class="javax.xml.namespace.QName">
-                <constructor-arg value="urn:oasis:names:tc:SAML:2.0:metadata" />
-                <constructor-arg value="SPSSODescriptor" />
+        </entry>
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact</value>
+            </key>
+            <bean id="shibboleth.SAML2HTTPArtifactDecoder"
+                class="org.opensaml.saml2.binding.decoding.HTTPArtifactDecoder">
+                <constructor-arg ref="shibboleth.ParserPool" />
             </bean>
-        </property>
-    </bean>
-    
-    <bean id="shibboleth.BaseSAML1SecurityPolicyFactory" abstract="true" class="org.opensaml.common.binding.security.SAMLSecurityPolicyFactory">
-        <property name="issuerProtocol" value="urn:oasis:names:tc:SAML:1.0:protocol" />
-        <property name="policyRuleFactories">
-            <list>
-                <ref bean="shibboleth.SAML1ProtocolMessageRuleFactory" />
-                <!-- Removed for testing -->
-                <!-- ref bean="shibboleth.MessageIssueInstantRuleFactory" /-->
-            </list>
-        </property>
-        <!-- Turn off for testing -->
-        <property name="requiredAuthenticatedIssuer" value="false" />
-    </bean>
-    
-    <bean id="shibboleth.SAML2ProtocolMessageRuleFactory" class="org.opensaml.saml2.binding.security.SAML2ProtocolMessageRuleFactory" />
-    
-    <bean id="shibboleth.SAML1ProtocolMessageRuleFactory" class="edu.internet2.middleware.shibboleth.common.binding.security.ShibbolethSAML1ProtocolMessageRuleFactory" />
-    
-    <bean id="shibboleth.MessageIssueInstantRuleFactory" class="org.opensaml.common.binding.security.IssueInstantRuleFactory">
-        <property name="clockSkew" value="5" />
-        <property name="expires" value="10" />
-    </bean>
-    
-    <bean id="shibboleth.MessageEncoderFactory" class="org.opensaml.common.binding.encoding.MessageEncoderFactory">
-        <property name="encoderBuilders">
-            <map>
-                <entry>
-                    <key>
-                        <value>urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST</value>
-                    </key>
-                    <bean id="shibboleth.SAML2HttpPostEncoderBuilder" class="org.opensaml.saml2.binding.encoding.HTTPPostEncoderBuilder">
-                        <constructor-arg ref="shibboleth.VelocityEngine" />
-                        <constructor-arg value="/templates/saml2-post-binding.vm"/>
-                    </bean>
-                </entry>
-                <entry>
-                    <key>
-                        <value>urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect</value>
-                    </key>
-                    <bean id="shibboleth.SAML2HttpRedirectEncoderBuilder" class="org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoderBuilder" />
-                </entry>
-                <entry>
-                    <key>
-                        <value>urn:oasis:names:tc:SAML:2.0:bindings:SOAP</value>
-                    </key>
-                    <bean id="shibboleth.SAML2HttpSoap11EncoderBuilder" class="org.opensaml.saml2.binding.encoding.HTTPSOAP11EncoderBuilder" />
-                </entry>
-                <entry>
-                    <key>
-                        <value>urn:oasis:names:tc:SAML:1.0:profiles:browser-post</value>
-                    </key>
-                    <bean id="shibboleth.SAML1HttpPostEncoderBuilder" class="org.opensaml.saml1.binding.encoding.HTTPPostEncoderBuilder">
-                        <constructor-arg ref="shibboleth.VelocityEngine" />
-                        <constructor-arg value="/templates/saml1-post-binding.vm"/>
-                    </bean>
-                </entry>
-                <entry>
-                    <key>
-                        <value>urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding</value>
-                    </key>
-                    <bean id="shibboleth.SAML1HttpSoap11EncoderBuilder" class="org.opensaml.saml1.binding.encoding.HTTPSOAP11EncoderBuilder" />
-                </entry>
-            </map>
-        </property>
-    </bean>
-    
-    <bean id="shibboleth.MessageDecoderFactory" class="org.opensaml.common.binding.decoding.MessageDecoderFactory">
-        <property name="decoderBuilders">
-            <map>
-                <entry>
-                    <key>
-                        <value>urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST</value>
-                    </key>
-                    <bean id="shibboleth.SAML2HttpPostDecoderBuilder" class="org.opensaml.saml2.binding.decoding.HTTPPostDecoderBuilder">
-                        <property name="parser" ref="shibboleth.ParserPool" />
-                    </bean>
-                </entry>
-                <entry>
-                    <key>
-                        <value>urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect</value>
-                    </key>
-                    <bean id="shibboleth.SAML2HttpRedirectDecoderBuilder" class="org.opensaml.saml2.binding.decoding.HTTPRedirectDeflateDecoderBuilder" >
-                        <property name="parser" ref="shibboleth.ParserPool" />
-                    </bean>
-                </entry>
-                <entry>
-                    <key>
-                        <value>urn:oasis:names:tc:SAML:2.0:bindings:SOAP</value>
-                    </key>
-                    <bean id="shibboleth.SAML2HttpSoap11DecoderBuilder" class="org.opensaml.saml2.binding.decoding.HTTPSOAP11DecoderBuilder" >
-                        <property name="parser" ref="shibboleth.ParserPool" />
-                    </bean>
-                </entry>
-                <entry>
-                    <key>
-                        <value>urn:oasis:names:tc:SAML:1.0:profiles:browser-post</value>
-                    </key>
-                    <bean id="shibboleth.SAML1HttpPostDecoderBuilder" class="org.opensaml.saml1.binding.decoding.HTTPPostDecoderBuilder" >
-                        <property name="parser" ref="shibboleth.ParserPool" />
-                    </bean>
-                </entry>
-                <entry>
-                    <key>
-                        <value>urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding</value>
-                    </key>
-                    <bean id="shibboleth.SAML1HttpSoap11DecoderBuilder" class="org.opensaml.saml1.binding.decoding.HTTPSOAP11DecoderBuilder" >
-                        <property name="parser" ref="shibboleth.ParserPool" />
-                    </bean>
-                </entry>
-            </map>
-        </property>
-    </bean>
-    
-    <bean id="shibboleth.SessionManager" class="edu.internet2.middleware.shibboleth.idp.session.impl.SessionManagerImpl" />
-    
+        </entry>
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:2.0:bindings:SOAP</value>
+            </key>
+            <bean id="shibboleth.SAML2HttpSoap11Decoder"
+                class="org.opensaml.saml2.binding.decoding.HTTPSOAP11Decoder">
+                <constructor-arg ref="shibboleth.ParserPool" />
+            </bean>
+        </entry>
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:1.0:profiles:browser-post</value>
+            </key>
+            <bean id="shibboleth.SAML1HttpPostDecoder" class="org.opensaml.saml1.binding.decoding.HTTPPostDecoder">
+                <constructor-arg ref="shibboleth.ParserPool" />
+            </bean>
+        </entry>
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:1.0:profiles:artifact-01</value>
+            </key>
+            <bean id="shibboleth.SAML1HttpArtifactDecoder" class="org.opensaml.saml1.binding.encoding.HTTPArtifactDecoder">
+            </bean>
+        </entry>
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding</value>
+            </key>
+            <bean id="shibboleth.SAML1HttpSoap11Decoder"
+                class="org.opensaml.saml1.binding.decoding.HTTPSOAP11Decoder">
+                <property name="parser" ref="shibboleth.ParserPool" />
+            </bean>
+        </entry>
+        <entry>
+            <key>
+                <value>urn:mace:shibboleth:1.0:profiles:AuthnRequest</value>
+            </key>
+            <bean id="shibboleth.ShibbolethSSODecoder"
+                class="org.opensaml.saml1.binding.decoding.ShibbolethSSODecoder">
+            </bean>
+        </entry>
+    </util:map>
+
+    <util:map id="shibboleth.MessageEncoders">
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST</value>
+            </key>
+            <bean id="shibboleth.SAML2HttpPostEncoder" class="org.opensaml.saml2.binding.encoding.HTTPPostEncoder">
+                <constructor-arg ref="shibboleth.VelocityEngine" />
+                <constructor-arg value="/templates/saml2-post-binding.vm" />
+            </bean>
+        </entry>
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect</value>
+            </key>
+            <bean id="shibboleth.SAML2HttpRedirectEncoder"
+                class="org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder" />
+        </entry>
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact</value>
+            </key>
+            <bean id="shibboleth.SAML2HTTPArtifactEncoder"
+                class="org.opensaml.saml2.binding.decoding.HTTPArtifactEncoder">
+            </bean>
+        </entry>
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:2.0:bindings:SOAP</value>
+            </key>
+            <bean id="shibboleth.SAML2HttpSoap11Encoder" class="org.opensaml.saml2.binding.encoding.HTTPSOAP11Encoder" />
+        </entry>
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:1.0:profiles:browser-post</value>
+            </key>
+            <bean id="shibboleth.SAML1HttpPostEncoder" class="org.opensaml.saml1.binding.encoding.HTTPPostEncoder">
+                <constructor-arg ref="shibboleth.VelocityEngine" />
+                <constructor-arg value="/templates/saml1-post-binding.vm" />
+            </bean>
+        </entry>
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:1.0:profiles:artifact-01</value>
+            </key>
+            <bean id="shibboleth.SAML1HttpArtifactEncoder" class="org.opensaml.saml1.binding.encoding.HTTPArtifactEncoder">
+            </bean>
+        </entry>
+        <entry>
+            <key>
+                <value>urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding</value>
+            </key>
+            <bean id="shibboleth.SAML1HttpSoap11EncoderBuilder"
+                class="org.opensaml.saml1.binding.encoding.HTTPSOAP11EncoderBuilder" />
+        </entry>
+    </util:map>
+
+    <bean id="shibboleth.SessionManager"
+        class="edu.internet2.middleware.shibboleth.idp.session.impl.SessionManagerImpl" />
+
     <bean id="shibboleth.SAML1AttributeAuthority"
-          class="edu.internet2.middleware.shibboleth.common.attribute.provider.ShibbolethSAML1AttributeAuthority">
-          <constructor-arg ref="shibboleth.AttributeResolver" />
-          <property name="filteringEngine" ref="shibboleth.AttributeFilterEngine" />
+        class="edu.internet2.middleware.shibboleth.common.attribute.provider.ShibbolethSAML1AttributeAuthority">
+        <constructor-arg ref="shibboleth.AttributeResolver" />
+        <property name="filteringEngine" ref="shibboleth.AttributeFilterEngine" />
     </bean>
-    
+
     <bean id="shibboleth.SAML2AttributeAuthority"
-          class="edu.internet2.middleware.shibboleth.common.attribute.provider.ShibbolethSAML2AttributeAuthority">
-          <constructor-arg ref="shibboleth.AttributeResolver" />
-          <property name="filteringEngine" ref="shibboleth.AttributeFilterEngine" />
+        class="edu.internet2.middleware.shibboleth.common.attribute.provider.ShibbolethSAML2AttributeAuthority">
+        <constructor-arg ref="shibboleth.AttributeResolver" />
+        <property name="filteringEngine" ref="shibboleth.AttributeFilterEngine" />
     </bean>
-    
+
     <bean id="shibboleth.ServletAttributeExporter"
         class="org.springframework.web.context.support.ServletContextAttributeExporter">
         <property name="attributes">
             </map>
         </property>
     </bean>
-    
+
 </beans>
\ No newline at end of file
index e764bdc..1601bcf 100644 (file)
@@ -17,6 +17,7 @@
 package edu.internet2.middleware.shibboleth.idp.config.profile;
 
 import org.apache.log4j.Logger;
+import org.opensaml.xml.util.XMLHelper;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 import org.w3c.dom.Element;
 
@@ -38,12 +39,15 @@ public abstract class AbstractSAMLProfileHandlerBeanDefinitionParser extends
         }
         super.doParse(config, builder);
 
-        builder.addPropertyReference("messageDecoderFactory", config.getAttributeNS(null,
-                "messageDecoderFactoryId"));
+        builder.addPropertyReference("idGenerator", config.getAttributeNS(null, "idGeneratorId"));
 
-        builder.addPropertyReference("messageEncoderFactory", config.getAttributeNS(null,
-                "messageEncoderFactoryId"));
+        builder.addPropertyReference("messageDecoders", "shibboleth.MessageDecoders");
 
-        builder.addPropertyReference("idGenerator", config.getAttributeNS(null, "idGeneratorId"));
+        builder.addPropertyReference("messageEncoders", "shibboleth.MessageEncoders");
+
+        builder.addPropertyValue("inboundBinding", config.getAttributeNodeNS(null, "inboundBinding"));
+
+        builder.addPropertyValue("supportedOutboundBindings", XMLHelper.getAttributeValueAsList(config
+                .getAttributeNodeNS(null, "outboundBindingEnumeration")));
     }
 }
\ No newline at end of file
index 12afc4f..f738162 100644 (file)
@@ -43,8 +43,5 @@ public class SAML1AttributeQueryProfileHandlerBeanDefinitionParser extends
     /** {@inheritDoc} */
     protected void doParse(Element config, BeanDefinitionBuilder builder) {
         super.doParse(config, builder);
-
-        builder.addPropertyReference("securityPolicyFactory", DatatypeHelper.safeTrimOrNullString(config
-                .getAttributeNS(null, "securityPolicyFactoryId")));
     }
 }
\ No newline at end of file
index e5bde0f..e62861c 100644 (file)
@@ -43,8 +43,5 @@ public class SAML2AttributeQueryProfileHandlerBeanDefinitionParser extends
     /** {@inheritDoc} */
     protected void doParse(Element config, BeanDefinitionBuilder builder) {
         super.doParse(config, builder);
-
-        builder.addPropertyReference("securityPolicyFactory", DatatypeHelper.safeTrimOrNullString(config
-                .getAttributeNS(null, "securityPolicyFactoryId")));
     }
 }
\ No newline at end of file
index ea30bb6..9120a2b 100644 (file)
@@ -50,8 +50,5 @@ public class SAML2SSOProfileHandlerBeanDefinitionParser extends AbstractSAML2Pro
                 "outboundBindingEnumeration")));
 
         builder.addConstructorArg(DatatypeHelper.safeTrimOrNullString(config.getAttributeNS(null, "decodingBinding")));
-
-        builder.addPropertyReference("securityPolicyFactory", DatatypeHelper.safeTrimOrNullString(config
-                .getAttributeNS(null, "securityPolicyFactoryId")));
     }
 }
\ No newline at end of file
index 709a5e3..ed66097 100644 (file)
 
 package edu.internet2.middleware.shibboleth.idp.profile;
 
+import java.util.List;
+import java.util.Map;
+
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.log4j.Logger;
 import org.opensaml.common.IdentifierGenerator;
 import org.opensaml.common.binding.decoding.SAMLMessageDecoder;
 import org.opensaml.common.binding.encoding.SAMLMessageEncoder;
+import org.opensaml.log.Level;
 import org.opensaml.saml2.metadata.provider.MetadataProvider;
+import org.opensaml.ws.message.encoder.MessageEncodingException;
 import org.opensaml.ws.transport.InTransport;
 import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
 
 import edu.internet2.middleware.shibboleth.common.log.AuditLogEntry;
+import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
 import edu.internet2.middleware.shibboleth.common.profile.provider.AbstractShibbolethProfileHandler;
+import edu.internet2.middleware.shibboleth.common.profile.provider.BaseSAMLProfileRequestContext;
 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.SAMLMDRelyingPartyConfigurationManager;
+import edu.internet2.middleware.shibboleth.idp.profile.saml2.BaseSAML2ProfileRequestContext;
 import edu.internet2.middleware.shibboleth.idp.session.Session;
 
 /**
@@ -40,14 +48,23 @@ public abstract class AbstractSAMLProfileHandler extends
     /** SAML message audit log. */
     private final Logger auditLog = Logger.getLogger(AuditLogEntry.AUDIT_LOGGER_NAME);
 
+    /** Class logger. */
+    private final Logger log = Logger.getLogger(AbstractSAMLProfileHandler.class);
+
     /** Generator of IDs which may be used for SAML assertions, requests, etc. */
     private IdentifierGenerator idGenerator;
 
-    /** Decoder used to extract message information from the inbound transport. */
-    private SAMLMessageDecoder messageDecoder;
+    /** All the SAML message decoders configured for the IdP. */
+    private Map<String, SAMLMessageDecoder> messageDecoders;
+
+    /** All the SAML message encoders configured for the IdP. */
+    private Map<String, SAMLMessageEncoder> messageEncoders;
+
+    /** SAML message binding used by inbound messages. */
+    private String inboundBinding;
 
-    /** Encoder used to bind information to the outbound message transport. */
-    private SAMLMessageEncoder messageEncoder;
+    /** SAML message bindings that may be used by outbound messages. */
+    private List<String> supportedOutboundBindings;
 
     /** Constructor. */
     protected AbstractSAMLProfileHandler() {
@@ -73,21 +90,30 @@ public abstract class AbstractSAMLProfileHandler extends
     }
 
     /**
-     * Gets the decoder used to extract message information from the inbound transport.
+     * Gets the SAML message binding used by inbound messages.
      * 
-     * @return decoder used to extract message information from the inbound transport
+     * @return SAML message binding used by inbound messages
      */
-    public SAMLMessageDecoder getMessageDecoder() {
-        return messageDecoder;
+    public String getInboundBinding() {
+        return inboundBinding;
     }
 
     /**
-     * Gets the encoder used to bind information to the outbound message transport.
+     * Gets all the SAML message decoders configured for the IdP indexed by SAML binding URI.
      * 
-     * @return encoder used to bind information to the outbound message transport
+     * @return SAML message decoders configured for the IdP indexed by SAML binding URI
      */
-    public SAMLMessageEncoder getMessageEncoder() {
-        return messageEncoder;
+    public Map<String, SAMLMessageDecoder> getMessageDecoders() {
+        return messageDecoders;
+    }
+
+    /**
+     * Gets all the SAML message encoders configured for the IdP indexed by SAML binding URI.
+     * 
+     * @return SAML message encoders configured for the IdP indexed by SAML binding URI
+     */
+    public Map<String, SAMLMessageEncoder> getMessageEncoders() {
+        return messageEncoders;
     }
 
     /**
@@ -105,6 +131,27 @@ public abstract class AbstractSAMLProfileHandler extends
     }
 
     /**
+     * Gets the SAML message bindings that may be used by outbound messages.
+     * 
+     * @return SAML message bindings that may be used by outbound messages
+     */
+    public List<String> getSupportedOutboundBindings() {
+        return supportedOutboundBindings;
+    }
+
+    /**
+     * Gets the user's session, if there is one.
+     * 
+     * @param inTransport current inbound transport
+     * 
+     * @return user's session
+     */
+    protected Session getUserSession(InTransport inTransport) {
+        String sessionId = getUserSessionId(inTransport);
+        return getSessionManager().getSession(sessionId);
+    }
+
+    /**
      * Gets the user's session ID from the current request.
      * 
      * @param inTransport current inbound transport
@@ -120,43 +167,98 @@ public abstract class AbstractSAMLProfileHandler extends
 
         return null;
     }
-    
+
     /**
-     * Gets the user's session, if there is one.
+     * Gets an ID generator which may be used for SAML assertions, requests, etc.
      * 
-     * @param inTransport current inbound transport
+     * @param generator an ID generator which may be used for SAML assertions, requests, etc
+     */
+    public void setIdGenerator(IdentifierGenerator generator) {
+        idGenerator = generator;
+    }
+
+    /**
+     * Sets the SAML message binding used by inbound messages.
      * 
-     * @return user's session
+     * @param binding SAML message binding used by inbound messages
      */
-    protected Session getUserSession(InTransport inTransport){
-        String sessionId = getUserSessionId(inTransport);
-        return getSessionManager().getSession(sessionId);
+    public void setInboundBinding(String binding) {
+        inboundBinding = binding;
     }
 
     /**
-     * Gets an ID generator which may be used for SAML assertions, requests, etc.
+     * Sets all the SAML message decoders configured for the IdP indexed by SAML binding URI.
      * 
-     * @param generator an ID generator which may be used for SAML assertions, requests, etc
+     * @param decoders SAML message decoders configured for the IdP indexed by SAML binding URI
      */
-    public void setIdGenerator(IdentifierGenerator generator) {
-        idGenerator = generator;
+    public void setMessageDecoders(Map<String, SAMLMessageDecoder> decoders) {
+        messageDecoders = decoders;
     }
 
     /**
-     * Sets the decoder used to extract message information from the inbound transport.
+     * Sets all the SAML message encoders configured for the IdP indexed by SAML binding URI.
      * 
-     * @param decoder decoder used to extract message information from the inbound transport
+     * @param encoders SAML message encoders configured for the IdP indexed by SAML binding URI
      */
-    public void setMessageDecoder(SAMLMessageDecoder decoder) {
-        messageDecoder = decoder;
+    public void setMessageEncoders(Map<String, SAMLMessageEncoder> encoders) {
+        messageEncoders = encoders;
     }
 
     /**
-     * Sets the encoder used to bind information to the outbound message transport.
+     * Sets the SAML message bindings that may be used by outbound messages.
      * 
-     * @param encoder encoder used to bind information to the outbound message transport
+     * @param bindings SAML message bindings that may be used by outbound messages
      */
-    public void setMessageEncoder(SAMLMessageEncoder encoder) {
-        messageEncoder = encoder;
+    public void setSupportedOutboundBindings(List<String> bindings) {
+        supportedOutboundBindings = bindings;
+    }
+
+    /**
+     * Encodes the request's SAML response and writes it to the servlet response.
+     * 
+     * @param requestContext current request context
+     * 
+     * @throws ProfileException thrown if no message encoder is registered for this profiles binding
+     */
+    protected void encodeResponse(BaseSAMLProfileRequestContext requestContext) throws ProfileException {
+        if (log.isDebugEnabled()) {
+            log.debug("Encoding response to SAML request " + requestContext.getInboundSAMLMessageId()
+                    + " from relying party " + requestContext.getPeerEntityId());
+        }
+
+        try {
+            SAMLMessageEncoder encoder = getMessageEncoders().get(requestContext.getPeerEntityEndpoint().getBinding());
+            if (encoder == null) {
+                throw new ProfileException("No outbound message encoder configured for binding "
+                        + requestContext.getPeerEntityEndpoint().getBinding());
+            }
+            requestContext.setMessageEncoder(encoder);
+            encoder.encode(requestContext);
+        } catch (MessageEncodingException e) {
+            throw new ProfileException("Unable to encode response to relying party: "
+                    + requestContext.getPeerEntityId(), e);
+        }
+    }
+    
+    /**
+     * Writes an aduit log entry indicating the successful response to the attribute request.
+     * 
+     * @param context current request context
+     */
+    protected void writeAuditLogEntry(BaseSAMLProfileRequestContext context) {
+        AuditLogEntry auditLogEntry = new AuditLogEntry();
+        auditLogEntry.setMessageProfile(getProfileId());
+        auditLogEntry.setPrincipalAuthenticationMethod(context.getPrincipalAuthenticationMethod());
+        auditLogEntry.setPrincipalName(context.getPrincipalName());
+        auditLogEntry.setAssertingPartyId(context.getLocalEntityId());
+        auditLogEntry.setRelyingPartyId(context.getPeerEntityId());
+        auditLogEntry.setRequestBinding(context.getMessageDecoder().getBindingURI());
+        auditLogEntry.setRequestId(context.getInboundSAMLMessageId());
+        auditLogEntry.setResponseBinding(context.getMessageEncoder().getBindingURI());
+        auditLogEntry.setResponseId(context.getOutboundSAMLMessageId());
+        if (context.getReleasedAttributes() != null) {
+            auditLogEntry.getReleasedAttributes().addAll(context.getReleasedAttributes());
+        }
+        getAduitLog().log(Level.CRITICAL, auditLogEntry);
     }
 }
\ No newline at end of file
index a4cb469..ee28c04 100644 (file)
@@ -216,7 +216,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
         assertion.setID(getIdGenerator().generateIdentifier());
         assertion.setIssueInstant(issueInstant);
         assertion.setVersion(SAMLVersion.VERSION_11);
-        assertion.setIssuer(requestContext.getAssertingPartyEntityId());
+        assertion.setIssuer(requestContext.getLocalEntityId());
 
         Conditions conditions = buildConditions(requestContext, issueInstant);
         assertion.setConditions(conditions);
@@ -303,7 +303,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
     protected NameIdentifier buildNameId(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext)
             throws ProfileException {
         if (log.isDebugEnabled()) {
-            log.debug("Building assertion NameIdentifier to relying party " + requestContext.getRelyingPartyEntityId()
+            log.debug("Building assertion NameIdentifier to relying party " + requestContext.getPeerEntityId()
                     + " for principal " + requestContext.getPrincipalName());
         }
         Map<String, BaseAttribute> principalAttributes = requestContext.getPrincipalAttributes();
@@ -491,17 +491,17 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
         try {
             if (log.isDebugEnabled()) {
                 log.debug("Resolving attributes for principal " + requestContext.getPrincipalName()
-                        + " of SAML request from relying party " + requestContext.getRelyingPartyEntityId());
+                        + " of SAML request from relying party " + requestContext.getPeerEntityId());
             }
             Map<String, BaseAttribute> principalAttributes = attributeAuthority.getAttributes(requestContext);
 
             requestContext.setAttributes(principalAttributes);
         } catch (AttributeRequestException e) {
             log.error("Error resolving attributes for SAML request from relying party "
-                    + requestContext.getRelyingPartyEntityId(), e);
+                    + requestContext.getPeerEntityId(), e);
             requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null, "Error resolving attributes"));
             throw new ProfileException("Error resolving attributes for SAML request from relying party "
-                    + requestContext.getRelyingPartyEntityId(), e);
+                    + requestContext.getPeerEntityId(), e);
         }
     }
 
@@ -520,7 +520,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
 
         if (log.isDebugEnabled()) {
             log.debug("Creating attribute statement in response to SAML request from relying party "
-                    + requestContext.getRelyingPartyEntityId());
+                    + requestContext.getPeerEntityId());
         }
 
         AbstractSAML1ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
@@ -561,7 +561,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
 
         if (log.isDebugEnabled()) {
             log.debug("Resolving principal name for subject of SAML request from relying party "
-                    + requestContext.getRelyingPartyEntityId());
+                    + requestContext.getPeerEntityId());
         }
 
         try {
@@ -569,11 +569,11 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
             requestContext.setPrincipalName(principal);
         } catch (AttributeRequestException e) {
             log.error("Error resolving attributes for SAML request from relying party "
-                    + requestContext.getRelyingPartyEntityId(), e);
+                    + requestContext.getPeerEntityId(), e);
             requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, StatusCode.REQUEST_DENIED,
                     "Error resolving principal"));
             throw new ProfileException("Error resolving attributes for SAML request from relying party "
-                    + requestContext.getRelyingPartyEntityId(), e);
+                    + requestContext.getPeerEntityId(), e);
         }
     }
 
@@ -590,7 +590,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
     protected void signAssertion(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext, Assertion assertion)
             throws ProfileException {
         if (log.isDebugEnabled()) {
-            log.debug("Determining if SAML assertion to relying party " + requestContext.getRelyingPartyEntityId()
+            log.debug("Determining if SAML assertion to relying party " + requestContext.getPeerEntityId()
                     + " should be signed");
         }
 
@@ -604,7 +604,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
             if (ssoDescriptor.getWantAssertionsSigned() != null) {
                 signAssertion = ssoDescriptor.getWantAssertionsSigned().booleanValue();
                 if (log.isDebugEnabled()) {
-                    log.debug("Entity metadata for relying party " + requestContext.getRelyingPartyEntityId()
+                    log.debug("Entity metadata for relying party " + requestContext.getPeerEntityId()
                             + " indicates to sign assertions: " + signAssertion);
                 }
             }
@@ -621,7 +621,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
 
         if (log.isDebugEnabled()) {
             log.debug("Determining signing credntial for assertion to relying party "
-                    + requestContext.getRelyingPartyEntityId());
+                    + requestContext.getPeerEntityId());
         }
         Credential signatureCredential = profileConfig.getSigningCredential();
         if (signatureCredential == null) {
@@ -635,7 +635,7 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
         }
 
         if (log.isDebugEnabled()) {
-            log.debug("Signing assertion to relying party " + requestContext.getRelyingPartyEntityId());
+            log.debug("Signing assertion to relying party " + requestContext.getPeerEntityId());
         }
         SAMLObjectContentReference contentRef = new SAMLObjectContentReference(assertion);
         Signature signature = signatureBuilder.buildObject(Signature.DEFAULT_ELEMENT_NAME);
@@ -644,26 +644,4 @@ public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHan
 
         Signer.signObject(signature);
     }
-
-    /**
-     * Writes an aduit log entry indicating the successful response to the attribute request.
-     * 
-     * @param context current request context
-     */
-    protected void writeAuditLogEntry(BaseSAML1ProfileRequestContext<?, ?, ?> context) {
-        AuditLogEntry auditLogEntry = new AuditLogEntry();
-        auditLogEntry.setMessageProfile(getProfileId());
-        auditLogEntry.setPrincipalAuthenticationMethod(context.getPrincipalAuthenticationMethod());
-        auditLogEntry.setPrincipalName(context.getPrincipalName());
-        auditLogEntry.setAssertingPartyId(context.getAssertingPartyEntityId());
-        auditLogEntry.setRelyingPartyId(context.getRelyingPartyEntityId());
-        auditLogEntry.setRequestBinding(getMessageDecoder().getBindingURI());
-        auditLogEntry.setRequestId(null);
-        auditLogEntry.setResponseBinding(getMessageEncoder().getBindingURI());
-        auditLogEntry.setResponseId(context.getOutboundSAMLMessageId());
-        if (context.getReleasedAttributes() != null) {
-            auditLogEntry.getReleasedAttributes().addAll(context.getReleasedAttributes());
-        }
-        getAduitLog().log(Level.CRITICAL, auditLogEntry);
-    }
 }
\ No newline at end of file
index dd314d6..5d07467 100644 (file)
@@ -19,18 +19,21 @@ package edu.internet2.middleware.shibboleth.idp.profile.saml1;
 import java.util.ArrayList;
 
 import org.apache.log4j.Logger;
+import org.opensaml.common.binding.BasicEndpointSelector;
+import org.opensaml.common.binding.decoding.SAMLMessageDecoder;
 import org.opensaml.common.xml.SAMLConstants;
 import org.opensaml.saml1.core.AttributeQuery;
 import org.opensaml.saml1.core.Request;
 import org.opensaml.saml1.core.Response;
 import org.opensaml.saml1.core.Statement;
 import org.opensaml.saml1.core.StatusCode;
+import org.opensaml.saml2.metadata.AssertionConsumerService;
 import org.opensaml.saml2.metadata.AttributeAuthorityDescriptor;
+import org.opensaml.saml2.metadata.Endpoint;
 import org.opensaml.saml2.metadata.SPSSODescriptor;
 import org.opensaml.saml2.metadata.provider.MetadataProvider;
 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
 import org.opensaml.ws.message.decoder.MessageDecodingException;
-import org.opensaml.ws.message.encoder.MessageEncodingException;
 import org.opensaml.ws.security.SecurityPolicyException;
 import org.opensaml.ws.transport.http.HTTPInTransport;
 import org.opensaml.ws.transport.http.HTTPOutTransport;
@@ -60,16 +63,17 @@ public class AttributeQueryProfileHandler extends AbstractSAML1ProfileHandler {
         try {
             if (requestContext.getRelyingPartyConfiguration() == null) {
                 log.error("SAML 1 Attribute Query profile is not configured for relying party "
-                        + requestContext.getRelyingPartyEntityId());
+                        + requestContext.getPeerEntityId());
                 requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, StatusCode.REQUEST_DENIED,
                         "SAML 1 Attribute Query profile is not configured for relying party "
-                                + requestContext.getRelyingPartyEntityId()));
+                                + requestContext.getPeerEntityId()));
                 samlResponse = buildErrorResponse(requestContext);
             }
 
             resolvePrincipal(requestContext);
             resolveAttributes(requestContext);
-
+            requestContext.setReleasedAttributes(requestContext.getPrincipalAttributes().keySet());
+            
             ArrayList<Statement> statements = new ArrayList<Statement>();
             statements.add(buildAttributeStatement(requestContext, "urn:oasis:names:tc:SAML:1.0:cm:sender-vouches"));
 
@@ -84,7 +88,7 @@ public class AttributeQueryProfileHandler extends AbstractSAML1ProfileHandler {
         encodeResponse(requestContext);
         writeAuditLogEntry(requestContext);
     }
-    
+
     /**
      * Decodes an incoming request and populates a created request context with the resultant information.
      * 
@@ -104,14 +108,19 @@ public class AttributeQueryProfileHandler extends AbstractSAML1ProfileHandler {
         MetadataProvider metadataProvider = getMetadataProvider();
 
         AttributeQueryContext requestContext = new AttributeQueryContext();
-        requestContext.setMessageInTransport(inTransport);
+        requestContext.setInboundMessageTransport(inTransport);
         requestContext.setInboundSAMLProtocol(SAMLConstants.SAML11P_NS);
-        requestContext.setMessageOutTransport(outTransport);
+        requestContext.setOutboundMessageTransport(outTransport);
         requestContext.setOutboundSAMLProtocol(SAMLConstants.SAML11P_NS);
         requestContext.setMetadataProvider(metadataProvider);
 
         try {
-            getMessageDecoder().decode(requestContext);
+            SAMLMessageDecoder decoder = getMessageDecoders().get(getInboundBinding());
+            if (decoder == null) {
+                throw new ProfileException("No message decoder configured for inbound binding " + getInboundBinding());
+            }
+            requestContext.setMessageDecoder(decoder);
+            decoder.decode(requestContext);
             if (log.isDebugEnabled()) {
                 log.debug("Decoded request");
             }
@@ -132,16 +141,17 @@ public class AttributeQueryProfileHandler extends AbstractSAML1ProfileHandler {
                 requestContext.setInboundSAMLMessageId(attributeRequest.getID());
                 requestContext.setInboundSAMLMessageIssueInstant(attributeRequest.getIssueInstant());
 
-                String relyingPartyId = requestContext.getRelyingPartyEntityId();
+                String relyingPartyId = requestContext.getPeerEntityId();
                 requestContext.setPeerEntityMetadata(metadataProvider.getEntityDescriptor(relyingPartyId));
                 requestContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
                 requestContext.setPeerEntityRoleMetadata(requestContext.getPeerEntityMetadata().getSPSSODescriptor(
                         SAMLConstants.SAML10P_NS));
                 RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(relyingPartyId);
                 requestContext.setRelyingPartyConfiguration(rpConfig);
+                requestContext.setPeerEntityEndpoint(selectEndpoint(requestContext));
 
                 String assertingPartyId = requestContext.getRelyingPartyConfiguration().getProviderId();
-                requestContext.setAssertingPartyEntityId(assertingPartyId);
+                requestContext.setLocalEntityId(assertingPartyId);
                 requestContext.setLocalEntityMetadata(metadataProvider.getEntityDescriptor(assertingPartyId));
                 requestContext.setLocalEntityRole(AttributeAuthorityDescriptor.DEFAULT_ELEMENT_NAME);
                 requestContext.setLocalEntityRoleMetadata(requestContext.getLocalEntityMetadata()
@@ -158,32 +168,30 @@ public class AttributeQueryProfileHandler extends AbstractSAML1ProfileHandler {
 
             } catch (MetadataProviderException e) {
                 log.error("Unable to locate metadata for asserting or relying party");
-                requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null,
-                        "Error locating party metadata"));
+                requestContext
+                        .setFailureStatus(buildStatus(StatusCode.RESPONDER, null, "Error locating party metadata"));
                 throw new ProfileException("Error locating party metadata");
             }
         }
     }
 
     /**
-     * Encodes the request's SAML response and writes it to the servlet response.
+     * Selects the appropriate endpoint for the relying party and stores it in the request context.
      * 
      * @param requestContext current request context
      * 
-     * @throws ProfileException thrown if no message encoder is registered for this profiles binding
+     * @return Endpoint selected from the information provided in the request context
      */
-    protected void encodeResponse(AttributeQueryContext requestContext) throws ProfileException {
-        if (log.isDebugEnabled()) {
-            log.debug("Encoding response to SAML request " + requestContext.getInboundSAMLMessageId()
-                    + " from relying party " + requestContext.getRelyingPartyEntityId());
-        }
-
-        try {
-            getMessageEncoder().encode(requestContext);
-        } catch (MessageEncodingException e) {
-            throw new ProfileException("Unable to encode response to relying party: "
-                    + requestContext.getRelyingPartyEntityId(), e);
-        }
+    protected Endpoint selectEndpoint(AttributeQueryContext requestContext) {
+        BasicEndpointSelector endpointSelector = new BasicEndpointSelector();
+        endpointSelector.setEndpointType(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
+        endpointSelector.setMetadataProvider(getMetadataProvider());
+        endpointSelector.setRelyingParty(requestContext.getPeerEntityMetadata());
+        endpointSelector.setRelyingPartyRole(requestContext.getPeerEntityRoleMetadata());
+        endpointSelector.setSamlRequest(requestContext.getInboundSAMLMessage());
+        endpointSelector.getSupportedIssuerBindings().addAll(getSupportedOutboundBindings());
+
+        return endpointSelector.selectEndpoint();
     }
 
     /** Basic data structure used to accumulate information as a request is being processed. */
diff --git a/src/edu/internet2/middleware/shibboleth/idp/profile/saml1/ShibbolethSSODecoder.java b/src/edu/internet2/middleware/shibboleth/idp/profile/saml1/ShibbolethSSODecoder.java
new file mode 100644 (file)
index 0000000..dd14252
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
+ *
+ * Licensed 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 edu.internet2.middleware.shibboleth.idp.profile.saml1;
+
+import org.apache.log4j.Logger;
+import org.opensaml.common.binding.decoding.SAMLMessageDecoder;
+import org.opensaml.ws.message.MessageContext;
+import org.opensaml.ws.message.decoder.BaseMessageDecoder;
+import org.opensaml.ws.message.decoder.MessageDecodingException;
+import org.opensaml.ws.transport.http.HTTPInTransport;
+import org.opensaml.xml.util.DatatypeHelper;
+
+import edu.internet2.middleware.shibboleth.idp.profile.saml1.ShibbolethSSOProfileHandler.ShibbolethSSORequestContext;
+
+/**
+ * Shibboleth 1.0 SSO authentication request message decoder.
+ */
+public class ShibbolethSSODecoder extends BaseMessageDecoder implements SAMLMessageDecoder {
+
+    /** Class logger. */
+    private final Logger log = Logger.getLogger(ShibbolethSSODecoder.class);
+
+    /** {@inheritDoc} */
+    public String getBindingURI() {
+        return "urn:mace:shibboleth:1.0:profiles:AuthnRequest";
+    }
+
+    /** {@inheritDoc} */
+    protected void doDecode(MessageContext messageContext) throws MessageDecodingException {
+        if (!(messageContext instanceof ShibbolethSSORequestContext)) {
+            log.error("Invalid message context type, this decoder only support ShibbolethSSORequestContext");
+            throw new MessageDecodingException(
+                    "Invalid message context type, this decoder only support ShibbolethSSORequestContext");
+        }
+
+        if (!(messageContext.getInboundMessageTransport() instanceof HTTPInTransport)) {
+            log.error("Invalid inbound message transport type, this decoder only support HTTPInTransport");
+            throw new MessageDecodingException(
+                    "Invalid inbound message transport type, this decoder only support HTTPInTransport");
+        }
+
+        ShibbolethSSORequestContext requestContext = (ShibbolethSSORequestContext) messageContext;
+        HTTPInTransport transport = (HTTPInTransport) messageContext.getInboundMessage();
+
+        String providerId = DatatypeHelper.safeTrimOrNullString(transport.getParameter("providerId"));
+        if (providerId == null) {
+            log.error("No providerId parameter given in Shibboleth SSO authentication request.");
+            throw new MessageDecodingException(
+                    "No providerId parameter given in Shibboleth SSO authentication request.");
+        }
+        requestContext.setPeerEntityId(providerId);
+
+        String shire = DatatypeHelper.safeTrimOrNullString(transport.getParameter("shire"));
+        if (shire == null) {
+            log.error("No shire parameter given in Shibboleth SSO authentication request.");
+            throw new MessageDecodingException("No shire parameter given in Shibboleth SSO authentication request.");
+        }
+        requestContext.setSpAssertionConsumerService(shire);
+
+        String target = DatatypeHelper.safeTrimOrNullString(transport.getParameter("target"));
+        if (target == null) {
+            log.error("No target parameter given in Shibboleth SSO authentication request.");
+            throw new MessageDecodingException("No target parameter given in Shibboleth SSO authentication request.");
+        }
+        requestContext.setRelayState(target);
+
+        String timeStr = DatatypeHelper.safeTrimOrNullString(transport.getParameter("time"));
+        if (timeStr != null) {
+            long time = Long.parseLong(timeStr);
+            requestContext.setTime(time);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/edu/internet2/middleware/shibboleth/idp/profile/saml1/ShibbolethSSOEndpointSelector.java b/src/edu/internet2/middleware/shibboleth/idp/profile/saml1/ShibbolethSSOEndpointSelector.java
new file mode 100644 (file)
index 0000000..241a925
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
+ *
+ * Licensed 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 edu.internet2.middleware.shibboleth.idp.profile.saml1;
+
+import java.util.List;
+
+import org.opensaml.common.binding.BasicEndpointSelector;
+import org.opensaml.saml2.metadata.Endpoint;
+import org.opensaml.xml.util.DatatypeHelper;
+
+/**
+ * An endpoint selector that may optionally take a SP-provided assertion consumer service URL, validate it against
+ * metadata, and return an endpoint based on it. If no URL is provided the {@link BasicEndpointSelector} selection is
+ * used.
+ */
+public class ShibbolethSSOEndpointSelector extends BasicEndpointSelector {
+
+    /** Assertion consumer service URL provided by SP. */
+    private String spAssertionConsumerService;
+
+    /**
+     * Gets the assertion consumer service URL provided by SP.
+     * 
+     * @return assertion consumer service URL provided by SP
+     */
+    public String getSpAssertionConsumerService() {
+        return spAssertionConsumerService;
+    }
+
+    /**
+     * Sets the assertion consumer service URL provided by SP.
+     * 
+     * @param acs assertion consumer service URL provided by SP
+     */
+    public void setSpAssertionConsumerService(String acs) {
+        spAssertionConsumerService = DatatypeHelper.safeTrimOrNullString(acs);
+    }
+
+    /** {@inheritDoc} */
+    public Endpoint selectEndpoint() {
+        if (spAssertionConsumerService != null) {
+            return selectEndpointByACS();
+        } else {
+            return super.selectEndpoint();
+        }
+    }
+
+    /**
+     * Selects the endpoint, from metadata, corresponding to the SP-provdided ACS URL.
+     * 
+     * @return endpoint corresponding to the SP-provdided ACS URL
+     */
+    protected Endpoint selectEndpointByACS() {
+        List<Endpoint> endpoints = getRelyingPartyRole().getEndpoints();
+        if (endpoints != null) {
+            for (Endpoint endpoint : endpoints) {
+                if (endpoint.getLocation().equalsIgnoreCase(spAssertionConsumerService)
+                        || endpoint.getResponseLocation().equalsIgnoreCase(spAssertionConsumerService)) {
+                    return endpoint;
+                }
+            }
+        }
+
+        return null;
+    }
+}
\ No newline at end of file
index 4208f40..57a98d3 100644 (file)
 package edu.internet2.middleware.shibboleth.idp.profile.saml1;
 
 import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
 import java.util.ArrayList;
-import java.util.List;
 
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletException;
@@ -30,7 +27,7 @@ import javax.servlet.http.HttpSession;
 
 import org.apache.log4j.Logger;
 import org.opensaml.common.SAMLObjectBuilder;
-import org.opensaml.common.binding.BasicEndpointSelector;
+import org.opensaml.common.binding.decoding.SAMLMessageDecoder;
 import org.opensaml.common.xml.SAMLConstants;
 import org.opensaml.saml1.core.AuthenticationStatement;
 import org.opensaml.saml1.core.Request;
@@ -46,7 +43,8 @@ import org.opensaml.saml2.metadata.IDPSSODescriptor;
 import org.opensaml.saml2.metadata.SPSSODescriptor;
 import org.opensaml.saml2.metadata.provider.MetadataProvider;
 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
-import org.opensaml.ws.message.encoder.MessageEncodingException;
+import org.opensaml.ws.message.decoder.MessageDecodingException;
+import org.opensaml.ws.security.SecurityPolicyException;
 import org.opensaml.ws.transport.http.HTTPInTransport;
 import org.opensaml.ws.transport.http.HTTPOutTransport;
 import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
@@ -77,29 +75,20 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
     /** URL of the authentication manager servlet. */
     private String authenticationManagerPath;
 
-    /** URI of SAML 1 bindings supported for outgoing message encoding. */
-    private ArrayList<String> supportedOutgoingBindings;
-
     /**
      * Constructor.
      * 
      * @param authnManagerPath path to the authentication manager servlet
-     * @param outgoingBindings URIs of SAML 1 bindings supported for outgoing message encoding
      * 
      * @throws IllegalArgumentException thrown if either the authentication manager path or encoding binding URI are
      *             null or empty
      */
-    public ShibbolethSSOProfileHandler(String authnManagerPath, List<String> outgoingBindings) {
+    public ShibbolethSSOProfileHandler(String authnManagerPath) {
         if (DatatypeHelper.isEmpty(authnManagerPath)) {
             throw new IllegalArgumentException("Authentication manager path may not be null");
         }
         authenticationManagerPath = authnManagerPath;
 
-        if (outgoingBindings == null || outgoingBindings.isEmpty()) {
-            throw new IllegalArgumentException("List of supported outgoing bindings may not be empty");
-        }
-        supportedOutgoingBindings = new ArrayList<String>(outgoingBindings);
-
         authnStatementBuilder = (SAMLObjectBuilder<AuthenticationStatement>) getBuilderFactory().getBuilder(
                 AuthenticationStatement.DEFAULT_ELEMENT_NAME);
 
@@ -151,7 +140,9 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
         HttpServletResponse httpResponse = ((HttpServletResponseAdapter) outTransport).getWrappedResponse();
         HttpSession httpSession = httpRequest.getSession(true);
 
-        LoginContext loginContext = buildLoginContext(httpRequest);
+        ShibbolethSSORequestContext requestContext = decodeRequest(inTransport, outTransport);
+        ShibbolethSSOLoginContext loginContext = requestContext.getLoginContext();
+
         if (getRelyingPartyConfiguration(loginContext.getRelyingPartyId()) == null) {
             log.error("Shibboleth SSO profile is not configured for relying party " + loginContext.getRelyingPartyId());
             throw new ProfileException("Shibboleth SSO profile is not configured for relying party "
@@ -174,6 +165,47 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
     }
 
     /**
+     * Decodes an incoming request and populates a created request context with the resultant information.
+     * 
+     * @param inTransport inbound message transport
+     * @param outTransport outbound message transport
+     * 
+     * @return the created request context
+     * 
+     * @throws ProfileException throw if there is a problem decoding the request
+     */
+    protected ShibbolethSSORequestContext decodeRequest(HTTPInTransport inTransport, HTTPOutTransport outTransport)
+            throws ProfileException {
+        HttpServletRequest httpRequest = ((HttpServletRequestAdapter) inTransport).getWrappedRequest();
+
+        ShibbolethSSORequestContext requestContext = new ShibbolethSSORequestContext();
+        requestContext.setInboundMessageTransport(inTransport);
+        requestContext.setOutboundMessageTransport(outTransport);
+
+        SAMLMessageDecoder decoder = getMessageDecoders().get(getInboundBinding());
+        requestContext.setMessageDecoder(decoder);
+        try {
+            decoder.decode(requestContext);
+        } catch (MessageDecodingException e) {
+            log.error("Error decoding Shibboleth SSO request", e);
+            throw new ProfileException("Error decoding Shibboleth SSO request", e);
+        } catch (SecurityPolicyException e) {
+            log.error("Shibboleth SSO request does not meet security policy requirements", e);
+            throw new ProfileException("Shibboleth SSO request does not meet security policy requirements", e);
+        }
+
+        ShibbolethSSOLoginContext loginContext = new ShibbolethSSOLoginContext();
+        loginContext.setRelyingParty(requestContext.getPeerEntityId());
+        loginContext.setSpAssertionConsumerService(requestContext.getSpAssertionConsumerService());
+        loginContext.setRelyingParty(requestContext.getRelayState());
+        loginContext.setAuthenticationEngineURL(authenticationManagerPath);
+        loginContext.setProfileHandlerURL(HttpHelper.getRequestUriWithoutContext(httpRequest));
+        requestContext.setLoginContext(loginContext);
+
+        return requestContext;
+    }
+
+    /**
      * Creates a response to the Shibboleth SSO and sends the user, with response in tow, back to the relying party
      * after they've been authenticated.
      * 
@@ -205,6 +237,7 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
             ArrayList<Statement> statements = new ArrayList<Statement>();
             statements.add(buildAuthenticationStatement(requestContext));
             if (requestContext.getProfileConfiguration().includeAttributeStatement()) {
+                requestContext.setRequestedAttributes(requestContext.getPrincipalAttributes().keySet());
                 statements.add(buildAttributeStatement(requestContext, "urn:oasis:names:tc:SAML:1.0:cm:bearer"));
             }
 
@@ -221,56 +254,6 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
     }
 
     /**
-     * Creates a login context from the incoming HTTP request.
-     * 
-     * @param request current HTTP request
-     * 
-     * @return the constructed login context
-     * 
-     * @throws ProfileException thrown if the incomming request did not contain a providerId, shire, and target
-     *             parameter
-     */
-    protected ShibbolethSSOLoginContext buildLoginContext(HttpServletRequest request) throws ProfileException {
-        ShibbolethSSOLoginContext loginContext = new ShibbolethSSOLoginContext();
-
-        try {
-            String providerId = DatatypeHelper.safeTrimOrNullString(request.getParameter("providerId"));
-            if (providerId == null) {
-                log.error("No providerId parameter in Shibboleth SSO request");
-                throw new ProfileException("No providerId parameter in Shibboleth SSO request");
-            }
-            loginContext.setRelyingParty(URLDecoder.decode(providerId, "UTF-8"));
-
-            RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(providerId);
-            if (rpConfig == null) {
-                log.error("No relying party configuration available for " + providerId);
-                throw new ProfileException("No relying party configuration available for " + providerId);
-            }
-            loginContext.getRequestedAuthenticationMethods().add(rpConfig.getDefaultAuthenticationMethod());
-
-            String acs = DatatypeHelper.safeTrimOrNullString(request.getParameter("shire"));
-            if (acs == null) {
-                log.error("No shire parameter in Shibboleth SSO request");
-                throw new ProfileException("No shire parameter in Shibboleth SSO request");
-            }
-            loginContext.setSpAssertionConsumerService(URLDecoder.decode(acs, "UTF-8"));
-
-            String target = DatatypeHelper.safeTrimOrNullString(request.getParameter("target"));
-            if (target == null) {
-                log.error("No target parameter in Shibboleth SSO request");
-                throw new ProfileException("No target parameter in Shibboleth SSO request");
-            }
-            loginContext.setSpTarget(URLDecoder.decode(target, "UTF-8"));
-        } catch (UnsupportedEncodingException e) {
-            // UTF-8 encoding required to be supported by all JVMs.
-        }
-
-        loginContext.setAuthenticationEngineURL(authenticationManagerPath);
-        loginContext.setProfileHandlerURL(HttpHelper.getRequestUriWithoutContext(request));
-        return loginContext;
-    }
-
-    /**
      * Creates an authentication request context from the current environmental information.
      * 
      * @param loginContext current login context
@@ -292,32 +275,31 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
             requestContext.setUserSession(getUserSession(in));
             requestContext.setRelayState(loginContext.getSpTarget());
 
-            requestContext.setMessageInTransport(in);
+            requestContext.setInboundMessageTransport(in);
             requestContext.setInboundSAMLProtocol(ShibbolethConstants.SHIB_SSO_PROFILE_URI);
 
             MetadataProvider metadataProvider = getMetadataProvider();
             requestContext.setMetadataProvider(metadataProvider);
 
             String relyingPartyId = loginContext.getRelyingPartyId();
-            requestContext.setRelyingPartyEntityId(relyingPartyId);
+            requestContext.setPeerEntityId(relyingPartyId);
             EntityDescriptor relyingPartyMetadata = metadataProvider.getEntityDescriptor(relyingPartyId);
             requestContext.setPeerEntityMetadata(relyingPartyMetadata);
             requestContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
-            requestContext.setPeerEntityRoleMetadata(relyingPartyMetadata
-                    .getSPSSODescriptor(SAMLConstants.SAML11P_NS));
+            requestContext.setPeerEntityRoleMetadata(relyingPartyMetadata.getSPSSODescriptor(SAMLConstants.SAML11P_NS));
             RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(relyingPartyId);
             requestContext.setRelyingPartyConfiguration(rpConfig);
             requestContext.setPeerEntityEndpoint(selectEndpoint(requestContext));
 
             String assertingPartyId = rpConfig.getProviderId();
-            requestContext.setAssertingPartyEntityId(assertingPartyId);
+            requestContext.setLocalEntityId(assertingPartyId);
             EntityDescriptor assertingPartyMetadata = metadataProvider.getEntityDescriptor(assertingPartyId);
             requestContext.setLocalEntityMetadata(assertingPartyMetadata);
             requestContext.setLocalEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME);
             requestContext.setLocalEntityRoleMetadata(assertingPartyMetadata
                     .getIDPSSODescriptor(SAMLConstants.SAML20P_NS));
 
-            requestContext.setMessageOutTransport(out);
+            requestContext.setOutboundMessageTransport(out);
             requestContext.setOutboundSAMLProtocol(SAMLConstants.SAML20P_NS);
             ShibbolethSSOConfiguration profileConfig = (ShibbolethSSOConfiguration) rpConfig
                     .getProfileConfiguration(SSOConfiguration.PROFILE_ID);
@@ -346,22 +328,15 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
     protected Endpoint selectEndpoint(ShibbolethSSORequestContext requestContext) {
         ShibbolethSSOLoginContext loginContext = requestContext.getLoginContext();
 
-        if (loginContext.getSpAssertionConsumerService() != null) {
-            SAMLObjectBuilder<AssertionConsumerService> acsBuilder = (SAMLObjectBuilder<AssertionConsumerService>) getBuilderFactory()
-                    .getBuilder(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
-            AssertionConsumerService acsEndpoint = acsBuilder.buildObject();
-            acsEndpoint.setBinding(getMessageEncoder().getBindingURI());
-            acsEndpoint.setLocation(loginContext.getSpAssertionConsumerService());
-            return acsEndpoint;
-        }
-
-        BasicEndpointSelector endpointSelector = new BasicEndpointSelector();
+        ShibbolethSSOEndpointSelector endpointSelector = new ShibbolethSSOEndpointSelector();
+        endpointSelector.setSpAssertionConsumerService(loginContext.getSpAssertionConsumerService());
         endpointSelector.setEndpointType(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
         endpointSelector.setMetadataProvider(getMetadataProvider());
         endpointSelector.setRelyingParty(requestContext.getPeerEntityMetadata());
         endpointSelector.setRelyingPartyRole(requestContext.getPeerEntityRoleMetadata());
         endpointSelector.setSamlRequest(requestContext.getInboundSAMLMessage());
-        endpointSelector.getSupportedIssuerBindings().addAll(supportedOutgoingBindings);
+        endpointSelector.getSupportedIssuerBindings().addAll(getSupportedOutboundBindings());
+
         return endpointSelector.selectEndpoint();
     }
 
@@ -400,38 +375,23 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
     protected SubjectLocality buildSubjectLocality(ShibbolethSSORequestContext requestContext) {
         SubjectLocality subjectLocality = subjectLocalityBuilder.buildObject();
 
-        HTTPInTransport inTransport = (HTTPInTransport) requestContext.getMessageInTransport();
+        HTTPInTransport inTransport = (HTTPInTransport) requestContext.getInboundMessageTransport();
         subjectLocality.setIPAddress(inTransport.getPeerAddress());
         subjectLocality.setDNSAddress(inTransport.getPeerDomainName());
 
         return subjectLocality;
     }
 
-    /**
-     * Encodes the request's SAML response and writes it to the servlet response.
-     * 
-     * @param requestContext current request context
-     * 
-     * @throws ProfileException thrown if no message encoder is registered for this profiles binding
-     */
-    protected void encodeResponse(ShibbolethSSORequestContext requestContext) throws ProfileException {
-        if (log.isDebugEnabled()) {
-            log.debug("Encoding response to SAML request " + requestContext.getInboundSAMLMessageId()
-                    + " from relying party " + requestContext.getRelyingPartyEntityId());
-        }
-
-        try {
-            getMessageEncoder().encode(requestContext);
-        } catch (MessageEncodingException e) {
-            throw new ProfileException("Unable to encode response to relying party: "
-                    + requestContext.getRelyingPartyEntityId(), e);
-        }
-    }
-
     /** Represents the internal state of a Shibboleth SSO Request while it's being processed by the IdP. */
-    protected class ShibbolethSSORequestContext extends
+    public class ShibbolethSSORequestContext extends
             BaseSAML1ProfileRequestContext<Request, Response, ShibbolethSSOConfiguration> {
 
+        /** Time since the epoch. */
+        private long time;
+
+        /** SP-provide assertion consumer service URL. */
+        private String spAssertionConsumerService;
+
         /** Current login context. */
         private ShibbolethSSOLoginContext loginContext;
 
@@ -452,5 +412,41 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
         public void setLoginContext(ShibbolethSSOLoginContext context) {
             loginContext = context;
         }
+
+        /**
+         * Gets the SP-provided assertion consumer service URL.
+         * 
+         * @return SP-provided assertion consumer service URL
+         */
+        public String getSpAssertionConsumerService() {
+            return spAssertionConsumerService;
+        }
+
+        /**
+         * Sets the SP-provided assertion consumer service URL.
+         * 
+         * @param acs SP-provided assertion consumer service URL
+         */
+        public void setSpAssertionConsumerService(String acs) {
+            spAssertionConsumerService = acs;
+        }
+
+        /**
+         * Sets the time since the epoch.
+         * 
+         * @return time since the epoch
+         */
+        public long getTime() {
+            return time;
+        }
+
+        /**
+         * Sets the time since the epoch.
+         * 
+         * @param time time since the epoch
+         */
+        public void setTime(long time) {
+            this.time = time;
+        }
     }
 }
\ No newline at end of file
index 344f8c3..24e8e9d 100644 (file)
@@ -26,7 +26,6 @@ import org.joda.time.DateTime;
 import org.opensaml.common.SAMLObjectBuilder;
 import org.opensaml.common.SAMLVersion;
 import org.opensaml.common.impl.SAMLObjectContentReference;
-import org.opensaml.log.Level;
 import org.opensaml.saml2.core.Assertion;
 import org.opensaml.saml2.core.AttributeQuery;
 import org.opensaml.saml2.core.AttributeStatement;
@@ -67,7 +66,6 @@ import edu.internet2.middleware.shibboleth.common.attribute.encoding.AttributeEn
 import edu.internet2.middleware.shibboleth.common.attribute.encoding.AttributeEncodingException;
 import edu.internet2.middleware.shibboleth.common.attribute.encoding.SAML2NameIDAttributeEncoder;
 import edu.internet2.middleware.shibboleth.common.attribute.provider.SAML2AttributeAuthority;
-import edu.internet2.middleware.shibboleth.common.log.AuditLogEntry;
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml2.AbstractSAML2ProfileConfiguration;
 import edu.internet2.middleware.shibboleth.idp.profile.AbstractSAMLProfileHandler;
@@ -244,7 +242,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
     protected Issuer buildEntityIssuer(BaseSAML2ProfileRequestContext<?, ?, ?> requestContext) {
         Issuer issuer = issuerBuilder.buildObject();
         issuer.setFormat(Issuer.ENTITY);
-        issuer.setValue(requestContext.getAssertingPartyEntityId());
+        issuer.setValue(requestContext.getLocalEntityId());
 
         return issuer;
     }
@@ -328,18 +326,18 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
             if (log.isDebugEnabled()) {
                 log.debug("Resolving attributes for principal " + requestContext.getPrincipalName()
                         + " of SAML request " + requestContext.getInboundSAMLMessageId() + " from relying party "
-                        + requestContext.getRelyingPartyEntityId());
+                        + requestContext.getPeerEntityId());
             }
             Map<String, BaseAttribute> principalAttributes = attributeAuthority.getAttributes(requestContext);
 
             requestContext.setAttributes(principalAttributes);
         } catch (AttributeRequestException e) {
             log.error("Error resolving attributes for SAML request " + requestContext.getInboundSAMLMessageId()
-                    + " from relying party " + requestContext.getRelyingPartyEntityId(), e);
+                    + " from relying party " + requestContext.getPeerEntityId(), e);
             requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER_URI, null, "Error resolving attributes"));
             throw new ProfileException("Error resolving attributes for SAML request "
                     + requestContext.getInboundSAMLMessageId() + " from relying party "
-                    + requestContext.getRelyingPartyEntityId(), e);
+                    + requestContext.getPeerEntityId(), e);
         }
     }
 
@@ -357,7 +355,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
         if (log.isDebugEnabled()) {
             log.debug("Creating attribute statement in response to SAML request "
                     + requestContext.getInboundSAMLMessageId() + " from relying party "
-                    + requestContext.getRelyingPartyEntityId());
+                    + requestContext.getPeerEntityId());
         }
         AbstractSAML2ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
         SAML2AttributeAuthority attributeAuthority = profileConfiguration.getAttributeAuthority();
@@ -388,19 +386,19 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
         AbstractSAML2ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
         if (profileConfiguration == null) {
             log.error("Unable to resolve principal, no SAML 2 profile configuration for relying party "
-                    + requestContext.getRelyingPartyEntityId());
+                    + requestContext.getPeerEntityId());
             requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER_URI, StatusCode.REQUEST_DENIED_URI,
                     "Error resolving principal"));
             throw new ProfileException(
                     "Unable to resolve principal, no SAML 2 profile configuration for relying party "
-                            + requestContext.getRelyingPartyEntityId());
+                            + requestContext.getPeerEntityId());
         }
         SAML2AttributeAuthority attributeAuthority = profileConfiguration.getAttributeAuthority();
 
         if (log.isDebugEnabled()) {
             log.debug("Resolving principal name for subject of SAML request "
                     + requestContext.getInboundSAMLMessageId() + " from relying party "
-                    + requestContext.getRelyingPartyEntityId());
+                    + requestContext.getPeerEntityId());
         }
 
         try {
@@ -408,12 +406,12 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
             requestContext.setPrincipalName(principal);
         } catch (AttributeRequestException e) {
             log.error("Error resolving attributes for SAML request " + requestContext.getInboundSAMLMessageId()
-                    + " from relying party " + requestContext.getRelyingPartyEntityId(), e);
+                    + " from relying party " + requestContext.getPeerEntityId(), e);
             requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER_URI, StatusCode.UNKNOWN_PRINCIPAL_URI,
                     "Error resolving principal"));
             throw new ProfileException("Error resolving attributes for SAML request "
                     + requestContext.getInboundSAMLMessageId() + " from relying party "
-                    + requestContext.getRelyingPartyEntityId(), e);
+                    + requestContext.getPeerEntityId(), e);
         }
     }
 
@@ -430,7 +428,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
     protected void signAssertion(BaseSAML2ProfileRequestContext<?, ?, ?> requestContext, Assertion assertion)
             throws ProfileException {
         if (log.isDebugEnabled()) {
-            log.debug("Determining if SAML assertion to relying party " + requestContext.getRelyingPartyEntityId()
+            log.debug("Determining if SAML assertion to relying party " + requestContext.getPeerEntityId()
                     + " should be signed");
         }
 
@@ -443,7 +441,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
             if (ssoDescriptor.getWantAssertionsSigned() != null) {
                 signAssertion = ssoDescriptor.getWantAssertionsSigned().booleanValue();
                 if (log.isDebugEnabled()) {
-                    log.debug("Entity metadata for relying party " + requestContext.getRelyingPartyEntityId()
+                    log.debug("Entity metadata for relying party " + requestContext.getPeerEntityId()
                             + " indicates to sign assertions: " + signAssertion);
                 }
             }
@@ -460,7 +458,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
 
         if (log.isDebugEnabled()) {
             log.debug("Determining signing credntial for assertion to relying party "
-                    + requestContext.getRelyingPartyEntityId());
+                    + requestContext.getPeerEntityId());
         }
         Credential signatureCredential = profileConfig.getSigningCredential();
         if (signatureCredential == null) {
@@ -474,7 +472,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
         }
 
         if (log.isDebugEnabled()) {
-            log.debug("Signing assertion to relying party " + requestContext.getRelyingPartyEntityId());
+            log.debug("Signing assertion to relying party " + requestContext.getPeerEntityId());
         }
         SAMLObjectContentReference contentRef = new SAMLObjectContentReference(assertion);
         Signature signature = signatureBuilder.buildObject(Signature.DEFAULT_ELEMENT_NAME);
@@ -535,7 +533,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
         // TODO handle encryption
 
         SubjectConfirmationData confirmationData = subjectConfirmationDataBuilder.buildObject();
-        HTTPInTransport inTransport = (HTTPInTransport) requestContext.getMessageInTransport();
+        HTTPInTransport inTransport = (HTTPInTransport) requestContext.getInboundMessageTransport();
         confirmationData.setAddress(inTransport.getPeerAddress());
         confirmationData.setInResponseTo(requestContext.getInboundSAMLMessageId());
         confirmationData.setNotOnOrAfter(issueInstant.plus(requestContext.getProfileConfiguration()
@@ -578,7 +576,7 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
     protected NameID buildNameId(BaseSAML2ProfileRequestContext<?, ?, ?> requestContext) throws ProfileException {
         if (log.isDebugEnabled()) {
             log.debug("Building assertion NameID for principal/relying party:" + requestContext.getPrincipalName()
-                    + "/" + requestContext.getRelyingPartyEntityId());
+                    + "/" + requestContext.getPeerEntityId());
         }
         Map<String, BaseAttribute> principalAttributes = requestContext.getPrincipalAttributes();
         List<String> supportedNameFormats = getNameFormats(requestContext);
@@ -713,26 +711,4 @@ public abstract class AbstractSAML2ProfileHandler extends AbstractSAMLProfileHan
 
         return samlResponse;
     }
-
-    /**
-     * Writes an aduit log entry indicating the successful response to the attribute request.
-     * 
-     * @param context current request context
-     */
-    protected void writeAuditLogEntry(BaseSAML2ProfileRequestContext<?, ?, ?> context) {
-        AuditLogEntry auditLogEntry = new AuditLogEntry();
-        auditLogEntry.setMessageProfile(getProfileId());
-        auditLogEntry.setPrincipalAuthenticationMethod(context.getPrincipalAuthenticationMethod());
-        auditLogEntry.setPrincipalName(context.getPrincipalName());
-        auditLogEntry.setAssertingPartyId(context.getAssertingPartyEntityId());
-        auditLogEntry.setRelyingPartyId(context.getRelyingPartyEntityId());
-        auditLogEntry.setRequestBinding(getMessageDecoder().getBindingURI());
-        auditLogEntry.setRequestId(context.getInboundSAMLMessageId());
-        auditLogEntry.setResponseBinding(getMessageEncoder().getBindingURI());
-        auditLogEntry.setResponseId(context.getOutboundSAMLMessageId());
-        if (context.getReleasedAttributes() != null) {
-            auditLogEntry.getReleasedAttributes().addAll(context.getReleasedAttributes());
-        }
-        getAduitLog().log(Level.CRITICAL, auditLogEntry);
-    }
 }
\ No newline at end of file
index 08455ee..a7f2199 100644 (file)
@@ -19,6 +19,7 @@ package edu.internet2.middleware.shibboleth.idp.profile.saml2;
 import java.util.ArrayList;
 
 import org.apache.log4j.Logger;
+import org.opensaml.common.binding.decoding.SAMLMessageDecoder;
 import org.opensaml.common.xml.SAMLConstants;
 import org.opensaml.saml2.core.AttributeQuery;
 import org.opensaml.saml2.core.Response;
@@ -29,7 +30,6 @@ import org.opensaml.saml2.metadata.SPSSODescriptor;
 import org.opensaml.saml2.metadata.provider.MetadataProvider;
 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
 import org.opensaml.ws.message.decoder.MessageDecodingException;
-import org.opensaml.ws.message.encoder.MessageEncodingException;
 import org.opensaml.ws.security.SecurityPolicyException;
 import org.opensaml.ws.transport.http.HTTPInTransport;
 import org.opensaml.ws.transport.http.HTTPOutTransport;
@@ -58,10 +58,10 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
         try {
             if (requestContext.getRelyingPartyConfiguration() == null) {
                 log.error("SAML 2 Attribute Query profile is not configured for relying party "
-                        + requestContext.getRelyingPartyEntityId());
+                        + requestContext.getPeerEntityId());
                 requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER_URI, StatusCode.REQUEST_DENIED_URI,
                         "SAML 2 Attribute Query profile is not configured for relying party "
-                                + requestContext.getRelyingPartyEntityId()));
+                                + requestContext.getPeerEntityId()));
                 samlResponse = buildErrorResponse(requestContext);
             }
 
@@ -69,8 +69,8 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
 
             // Resolve attribute query name id to principal name and place in context
             resolvePrincipal(requestContext);
-
             resolveAttributes(requestContext);
+            requestContext.setReleasedAttributes(requestContext.getPrincipalAttributes().keySet());
 
             // Lookup principal name and attributes, create attribute statement from information
             ArrayList<Statement> statements = new ArrayList<Statement>();
@@ -109,14 +109,16 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
         MetadataProvider metadataProvider = getMetadataProvider();
 
         AttributeQueryContext requestContext = new AttributeQueryContext();
-        requestContext.setMessageInTransport(inTransport);
+        requestContext.setInboundMessageTransport(inTransport);
         requestContext.setInboundSAMLProtocol(SAMLConstants.SAML20P_NS);
-        requestContext.setMessageOutTransport(outTransport);
+        requestContext.setOutboundMessageTransport(outTransport);
         requestContext.setOutboundSAMLProtocol(SAMLConstants.SAML20P_NS);
         requestContext.setMetadataProvider(metadataProvider);
 
         try {
-            getMessageDecoder().decode(requestContext);
+            SAMLMessageDecoder decoder = getMessageDecoders().get(getInboundBinding());
+            requestContext.setMessageDecoder(decoder);
+            decoder.decode(requestContext);
             if (log.isDebugEnabled()) {
                 log.debug("Decoded request");
             }
@@ -137,7 +139,7 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
                 requestContext.setInboundSAMLMessageId(attributeQuery.getID());
                 requestContext.setInboundSAMLMessageIssueInstant(attributeQuery.getIssueInstant());
 
-                String relyingPartyId = requestContext.getRelyingPartyEntityId();
+                String relyingPartyId = requestContext.getPeerEntityId();
                 requestContext.setPeerEntityMetadata(metadataProvider.getEntityDescriptor(relyingPartyId));
                 requestContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
                 requestContext.setPeerEntityRoleMetadata(requestContext.getPeerEntityMetadata().getSPSSODescriptor(
@@ -146,7 +148,7 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
                 requestContext.setRelyingPartyConfiguration(rpConfig);
 
                 String assertingPartyId = requestContext.getRelyingPartyConfiguration().getProviderId();
-                requestContext.setAssertingPartyEntityId(assertingPartyId);
+                requestContext.setLocalEntityId(assertingPartyId);
                 requestContext.setLocalEntityMetadata(metadataProvider.getEntityDescriptor(assertingPartyId));
                 requestContext.setLocalEntityRole(AttributeAuthorityDescriptor.DEFAULT_ELEMENT_NAME);
                 requestContext.setLocalEntityRoleMetadata(requestContext.getLocalEntityMetadata()
@@ -170,27 +172,6 @@ public class AttributeQueryProfileHandler extends AbstractSAML2ProfileHandler {
         }
     }
 
-    /**
-     * Encodes the request's SAML response and writes it to the servlet response.
-     * 
-     * @param requestContext current request context
-     * 
-     * @throws ProfileException thrown if no message encoder is registered for this profiles binding
-     */
-    protected void encodeResponse(AttributeQueryContext requestContext) throws ProfileException {
-        if (log.isDebugEnabled()) {
-            log.debug("Encoding response to SAML request " + requestContext.getInboundSAMLMessageId()
-                    + " from relying party " + requestContext.getRelyingPartyEntityId());
-        }
-
-        try {
-            getMessageEncoder().encode(requestContext);
-        } catch (MessageEncodingException e) {
-            throw new ProfileException("Unable to encode response to relying party: "
-                    + requestContext.getRelyingPartyEntityId(), e);
-        }
-    }
-
     /** Basic data structure used to accumulate information as a request is being processed. */
     protected class AttributeQueryContext extends
             BaseSAML2ProfileRequestContext<AttributeQuery, Response, AttributeQueryConfiguration> {
index 734063a..af2de05 100644 (file)
@@ -27,6 +27,7 @@ import javax.servlet.http.HttpSession;
 
 import org.apache.log4j.Logger;
 import org.opensaml.common.SAMLObjectBuilder;
+import org.opensaml.common.binding.decoding.SAMLMessageDecoder;
 import org.opensaml.common.xml.SAMLConstants;
 import org.opensaml.saml2.binding.AuthnResponseEndpointSelector;
 import org.opensaml.saml2.core.AuthnContext;
@@ -47,7 +48,6 @@ import org.opensaml.saml2.metadata.SPSSODescriptor;
 import org.opensaml.saml2.metadata.provider.MetadataProvider;
 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
 import org.opensaml.ws.message.decoder.MessageDecodingException;
-import org.opensaml.ws.message.encoder.MessageEncodingException;
 import org.opensaml.ws.security.SecurityPolicyException;
 import org.opensaml.ws.transport.http.HTTPInTransport;
 import org.opensaml.ws.transport.http.HTTPOutTransport;
@@ -162,7 +162,7 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
         try {
             SSORequestContext requestContext = decodeRequest(inTransport, outTransport);
 
-            String relyingPartyId = requestContext.getRelyingPartyEntityId();
+            String relyingPartyId = requestContext.getPeerEntityId();
             RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(relyingPartyId);
             if (rpConfig == null) {
                 log.error("No relying party configuration for " + relyingPartyId);
@@ -228,6 +228,7 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
             ArrayList<Statement> statements = new ArrayList<Statement>();
             statements.add(buildAuthnStatement(requestContext));
             if (requestContext.getProfileConfiguration().includeAttributeStatement()) {
+                requestContext.setRequestedAttributes(requestContext.getPrincipalAttributes().keySet());
                 statements.add(buildAttributeStatement(requestContext));
             }
 
@@ -260,12 +261,14 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
         }
 
         SSORequestContext requestContext = new SSORequestContext();
-        requestContext.setMessageInTransport(inTransport);
-        requestContext.setMessageOutTransport(outTransport);
+        requestContext.setInboundMessageTransport(inTransport);
+        requestContext.setOutboundMessageTransport(outTransport);
         requestContext.setMetadataProvider(getMetadataProvider());
 
         try {
-            getMessageDecoder().decode(requestContext);
+            SAMLMessageDecoder decoder = getMessageDecoders().get(getInboundBinding());
+            requestContext.setMessageDecoder(decoder);
+            decoder.decode(requestContext);
             return requestContext;
         } catch (MessageDecodingException e) {
             log.error("Error decoding authentication request message", e);
@@ -298,7 +301,7 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
             requestContext.setUserSession(getUserSession(in));
             requestContext.setRelayState(loginContext.getRelayState());
 
-            requestContext.setMessageInTransport(in);
+            requestContext.setInboundMessageTransport(in);
             requestContext.setInboundSAMLProtocol(SAMLConstants.SAML20P_NS);
             requestContext.setInboundMessage(loginContext.getAuthenticationRequest());
             requestContext.setInboundSAMLMessage(loginContext.getAuthenticationRequest());
@@ -308,25 +311,24 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
             requestContext.setMetadataProvider(metadataProvider);
 
             String relyingPartyId = loginContext.getRelyingPartyId();
-            requestContext.setRelyingPartyEntityId(relyingPartyId);
+            requestContext.setPeerEntityId(relyingPartyId);
             EntityDescriptor relyingPartyMetadata = metadataProvider.getEntityDescriptor(relyingPartyId);
             requestContext.setPeerEntityMetadata(relyingPartyMetadata);
             requestContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
-            requestContext.setPeerEntityRoleMetadata(relyingPartyMetadata
-                    .getSPSSODescriptor(SAMLConstants.SAML20P_NS));
+            requestContext.setPeerEntityRoleMetadata(relyingPartyMetadata.getSPSSODescriptor(SAMLConstants.SAML20P_NS));
             RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(relyingPartyId);
             requestContext.setRelyingPartyConfiguration(rpConfig);
             requestContext.setPeerEntityEndpoint(selectEndpoint(requestContext));
 
             String assertingPartyId = rpConfig.getProviderId();
-            requestContext.setAssertingPartyEntityId(assertingPartyId);
+            requestContext.setLocalEntityId(assertingPartyId);
             EntityDescriptor assertingPartyMetadata = metadataProvider.getEntityDescriptor(assertingPartyId);
             requestContext.setLocalEntityMetadata(assertingPartyMetadata);
             requestContext.setLocalEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME);
             requestContext.setLocalEntityRoleMetadata(assertingPartyMetadata
                     .getIDPSSODescriptor(SAMLConstants.SAML20P_NS));
 
-            requestContext.setMessageOutTransport(out);
+            requestContext.setOutboundMessageTransport(out);
             requestContext.setOutboundSAMLProtocol(SAMLConstants.SAML20P_NS);
             SSOConfiguration profileConfig = (SSOConfiguration) rpConfig
                     .getProfileConfiguration(SSOConfiguration.PROFILE_ID);
@@ -428,7 +430,7 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
      * @return subject locality for the authentication statement
      */
     protected SubjectLocality buildSubjectLocality(SSORequestContext requestContext) {
-        HTTPInTransport transport = (HTTPInTransport) requestContext.getMessageInTransport();
+        HTTPInTransport transport = (HTTPInTransport) requestContext.getInboundMessageTransport();
         SubjectLocality subjectLocality = subjectLocalityBuilder.buildObject();
         subjectLocality.setAddress(transport.getPeerAddress());
         subjectLocality.setDNSName(transport.getPeerDomainName());
@@ -454,27 +456,6 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
         return endpointSelector.selectEndpoint();
     }
 
-    /**
-     * Encodes the request's SAML response and writes it to the servlet response.
-     * 
-     * @param requestContext current request context
-     * 
-     * @throws ProfileException thrown if no message encoder is registered for this profiles binding
-     */
-    protected void encodeResponse(SSORequestContext requestContext) throws ProfileException {
-        if (log.isDebugEnabled()) {
-            log.debug("Encoding response to SAML request " + requestContext.getInboundSAMLMessageId()
-                    + " from relying party " + requestContext.getRelyingPartyEntityId());
-        }
-
-        try {
-            getMessageEncoder().encode(requestContext);
-        } catch (MessageEncodingException e) {
-            throw new ProfileException("Unable to encode response to relying party: "
-                    + requestContext.getRelyingPartyEntityId(), e);
-        }
-    }
-
     /** Represents the internal state of a SAML 2.0 SSO Request while it's being processed by the IdP. */
     protected class SSORequestContext extends BaseSAML2ProfileRequestContext<AuthnRequest, Response, SSOConfiguration> {