SAML 2 SSO unit test and bug fixes
authorlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Fri, 7 Sep 2007 22:25:12 +0000 (22:25 +0000)
committerlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Fri, 7 Sep 2007 22:25:12 +0000 (22:25 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@2375 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

src/edu/internet2/middleware/shibboleth/idp/profile/saml1/ShibbolethSSOProfileHandler.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/SSOProfileHandler.java
test/edu/internet2/middleware/shibboleth/idp/system/conf1/SAML2SSOTestCase.java

index 4657631..b62f768 100644 (file)
@@ -53,6 +53,7 @@ import org.opensaml.xml.util.DatatypeHelper;
 
 import edu.internet2.middleware.shibboleth.common.ShibbolethConstants;
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
+import edu.internet2.middleware.shibboleth.common.relyingparty.ProfileConfiguration;
 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration;
 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml1.ShibbolethSSOConfiguration;
 import edu.internet2.middleware.shibboleth.common.util.HttpHelper;
@@ -143,7 +144,7 @@ public class ShibbolethSSOProfileHandler extends AbstractSAML1ProfileHandler {
         ShibbolethSSOLoginContext loginContext = requestContext.getLoginContext();
 
         RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(loginContext.getRelyingPartyId());
-        ShibbolethSSOConfiguration ssoConfig = (ShibbolethSSOConfiguration) rpConfig.getProfileConfigurations().get(ShibbolethSSOConfiguration.PROFILE_ID);
+        ProfileConfiguration ssoConfig = rpConfig.getProfileConfiguration(ShibbolethSSOConfiguration.PROFILE_ID);
         if (ssoConfig == 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 "
index 794aa5a..9bb6858 100644 (file)
@@ -56,6 +56,7 @@ import org.opensaml.xml.io.MarshallingException;
 import org.opensaml.xml.io.UnmarshallingException;
 
 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
+import edu.internet2.middleware.shibboleth.common.relyingparty.ProfileConfiguration;
 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration;
 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml2.SSOConfiguration;
 import edu.internet2.middleware.shibboleth.common.util.HttpHelper;
@@ -148,9 +149,11 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
 
             String relyingPartyId = requestContext.getInboundMessageIssuer();
             RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(relyingPartyId);
-            if (rpConfig == null) {
-                log.error("No relying party configuration for " + relyingPartyId);
-                throw new ProfileException("No relying party configuration for " + relyingPartyId);
+            ProfileConfiguration ssoConfig = rpConfig.getProfileConfiguration(SSOConfiguration.PROFILE_ID);
+            if (ssoConfig == null) {
+                log.error("SAML 2 SSO profile is not configured for relying party " + requestContext.getInboundMessageIssuer());
+                throw new ProfileException("SAML 2 SSO profile is not configured for relying party "
+                        + requestContext.getInboundMessageIssuer());
             }
 
             Saml2LoginContext loginContext = new Saml2LoginContext(relyingPartyId, requestContext.getRelayState(),
@@ -284,6 +287,8 @@ public class SSOProfileHandler extends AbstractSAML2ProfileHandler {
         SSORequestContext requestContext = new SSORequestContext();
 
         try {
+            requestContext.setMessageDecoder(getMessageDecoders().get(getInboundBinding()));
+            
             requestContext.setLoginContext(loginContext);
             requestContext.setPrincipalName(loginContext.getPrincipalName());
             requestContext.setPrincipalAuthenticationMethod(loginContext.getAuthenticationMethod());
index a067b55..b4c985c 100644 (file)
@@ -44,15 +44,9 @@ import edu.internet2.middleware.shibboleth.idp.authn.Saml2LoginContext;
  */
 public class SAML2SSOTestCase extends BaseConf1TestCase {
 
-    /** Tests a request where the Issuer can not be authenticated. */
-    public void testUnathenticatedIssuer() throws Exception {
-        AuthnRequest authnRequest = buildAuthnRequest("urn:example.org:unitTest:sp1");
-        String authnRequestString = getSamlRequestString(authnRequest);
-
-        MockHttpServletRequest servletRequest = new MockHttpServletRequest();
-        servletRequest.setPathInfo("/saml2/POST/SSO");
-        servletRequest.setParameter("SAMLRequest", Base64.encodeBytes(authnRequestString.getBytes()));
-
+    /** Tests initial leg of the SSO request where request is decoded and sent to the authentication engine. */
+    public void testFirstAuthenticationLeg() throws Exception {
+        MockHttpServletRequest servletRequest = buildServletRequest("urn:example.org:sp1");
         MockHttpServletResponse servletResponse = new MockHttpServletResponse();
 
         ProfileHandlerManager handlerManager = (ProfileHandlerManager) getApplicationContext().getBean(
@@ -63,25 +57,32 @@ public class SAML2SSOTestCase extends BaseConf1TestCase {
         // Process request
         HTTPInTransport profileRequest = new HttpServletRequestAdapter(servletRequest);
         HTTPOutTransport profileResponse = new HttpServletResponseAdapter(servletResponse);
+        handler.processRequest(profileRequest, profileResponse);
 
-        try {
-            handler.processRequest(profileRequest, profileResponse);
-            fail();
-        } catch (ProfileException e) {
-            // expected
-        }
-    }
-
-    public void testAuthenicatedIssuer() throws Exception {
-        AuthnRequest authnRequest = buildAuthnRequest("urn:example.org:unitTestFed:sp2");
-        String authnRequestString = getSamlRequestString(authnRequest);
+        HttpSession session = servletRequest.getSession();
+        Saml2LoginContext loginContext = (Saml2LoginContext) session
+                .getAttribute(Saml2LoginContext.LOGIN_CONTEXT_KEY);
 
-        MockHttpServletRequest servletRequest = new MockHttpServletRequest();
-        servletRequest.setPathInfo("/saml2/POST/SSO");
-        servletRequest.setParameter("SAMLRequest", Base64.encodeBytes(authnRequestString.getBytes()));
+        assertNotNull(loginContext);
+        assertEquals(false, loginContext.getAuthenticationAttempted());
+        assertEquals(false, loginContext.getForceAuth());
+        assertEquals(false, loginContext.getPassiveAuth());
+        assertEquals("/AuthnEngine", loginContext.getAuthenticationEngineURL());
+        assertEquals("/saml2/POST/SSO", loginContext.getProfileHandlerURL());
+        assertEquals("urn:example.org:sp1", loginContext.getRelyingPartyId());
+        assertEquals(1, loginContext.getRequestedAuthenticationMethods().size());
+
+        assertEquals("/AuthnEngine", servletResponse.getForwardedUrl());
+    }
 
+    /** Tests second leg of the SSO request where request returns to SSO handler and AuthN statement is generated. */
+    public void testSecondAuthenticationLeg() throws Exception {
+        MockHttpServletRequest servletRequest = buildServletRequest("urn:example.org:sp1");
         MockHttpServletResponse servletResponse = new MockHttpServletResponse();
 
+        HttpSession httpSession = servletRequest.getSession(true);
+        httpSession.setAttribute(Saml2LoginContext.LOGIN_CONTEXT_KEY, buildLoginContext("urn:example.org:sp1"));
+
         ProfileHandlerManager handlerManager = (ProfileHandlerManager) getApplicationContext().getBean(
                 "shibboleth.HandlerManager");
         ProfileHandler handler = handlerManager.getProfileHandler(servletRequest);
@@ -92,26 +93,15 @@ public class SAML2SSOTestCase extends BaseConf1TestCase {
         HTTPOutTransport profileResponse = new HttpServletResponseAdapter(servletResponse);
         handler.processRequest(profileRequest, profileResponse);
 
-        HttpSession session = servletRequest.getSession();
-        Saml2LoginContext loginContext = (Saml2LoginContext) session.getAttribute(Saml2LoginContext.LOGIN_CONTEXT_KEY);
-        assertNotNull(loginContext);
+        String response = servletResponse.getContentAsString();
+        assertTrue(response.contains("action=\"https://example.org/mySP\" method=\"post\""));
+        assertTrue(response.contains("SAMLResponse"));
     }
 
-    public void testSecondLeg() throws Exception {
-        AuthnRequest authnRequest = buildAuthnRequest("urn:example.org:unitTestFed:sp2");
-
-        Saml2LoginContext loginContext = new Saml2LoginContext("urn:example.org:unitTestFed:sp2", null, authnRequest);
-        loginContext.setAuthenticationInstant(new DateTime());
-        loginContext.setAuthenticationMethod("urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified");
-        loginContext.setPrincipalAuthenticated(true);
-        loginContext.setPrincipalName("testUser");
-
-        MockHttpServletRequest servletRequest = new MockHttpServletRequest();
-        servletRequest.setPathInfo("/saml2/POST/SSO");
-
-        HttpSession session = servletRequest.getSession();
-        session.setAttribute(Saml2LoginContext.LOGIN_CONTEXT_KEY, loginContext);
-
+    /** Tests that the handler correctly fails out if the SSO profile is not configured. */
+    public void testAuthenticationWithoutConfiguredSSO() throws Exception{
+        MockHttpServletRequest servletRequest = buildServletRequest("urn:example.org:BogusSP");
+        
         MockHttpServletResponse servletResponse = new MockHttpServletResponse();
 
         ProfileHandlerManager handlerManager = (ProfileHandlerManager) getApplicationContext().getBean(
@@ -122,16 +112,42 @@ public class SAML2SSOTestCase extends BaseConf1TestCase {
         // Process request
         HTTPInTransport profileRequest = new HttpServletRequestAdapter(servletRequest);
         HTTPOutTransport profileResponse = new HttpServletResponseAdapter(servletResponse);
-        handler.processRequest(profileRequest, profileResponse);
+        try {
+            handler.processRequest(profileRequest, profileResponse);
+            fail("Request processing expected to due to lack of configured SAML 2 SSO profile");
+        } catch (ProfileException e) {
+
+        }
+    }
+
+    protected MockHttpServletRequest buildServletRequest(String relyingPartyId) throws Exception{
+        AuthnRequest authnRequest = buildAuthnRequest(relyingPartyId);
+        String authnRequestString = getSamlRequestString(authnRequest);
+        
+        MockHttpServletRequest servletRequest = new MockHttpServletRequest();
+        servletRequest.setPathInfo("/saml2/POST/SSO");
+        servletRequest.setParameter("SAMLRequest", Base64.encodeBytes(authnRequestString.getBytes()));
 
-        System.out.println(servletResponse.getContentAsString());
+        return servletRequest;
     }
 
-    protected AuthnRequest buildAuthnRequest(String requester) {
+    protected Saml2LoginContext buildLoginContext(String relyingPartyId) throws Exception{
+        AuthnRequest request = buildAuthnRequest(relyingPartyId);
+        Saml2LoginContext loginContext = new Saml2LoginContext(relyingPartyId, null, request);
+        loginContext.setAuthenticationInstant(new DateTime());
+        loginContext.setAuthenticationMethod("urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified");
+        loginContext.setPrincipalAuthenticated(true);
+        loginContext.setPrincipalName("testUser");
+        loginContext.setRelyingParty(relyingPartyId);
+
+        return loginContext;
+    }
+    
+    protected AuthnRequest buildAuthnRequest(String relyingPartyId) {
         SAMLObjectBuilder<Issuer> issuerBuilder = (SAMLObjectBuilder<Issuer>) builderFactory
                 .getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
         Issuer issuer = issuerBuilder.buildObject();
-        issuer.setValue(requester);
+        issuer.setValue(relyingPartyId);
 
         SAMLObjectBuilder<AuthnRequest> authnRequestBuilder = (SAMLObjectBuilder<AuthnRequest>) builderFactory
                 .getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);