2 * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package edu.internet2.middleware.shibboleth.integration;
19 import java.util.Enumeration;
21 import javax.naming.directory.Attributes;
22 import javax.naming.directory.BasicAttribute;
23 import javax.servlet.http.HttpServletRequest;
25 import junit.framework.TestCase;
27 import org.apache.commons.codec.binary.Base64;
28 import org.apache.log4j.Level;
29 import org.opensaml.SAMLException;
31 import edu.internet2.middleware.shibboleth.idp.provider.ShibbolethV1SSOHandler;
32 import edu.internet2.middleware.shibboleth.resource.FilterUtil;
33 import edu.internet2.middleware.shibboleth.resource.FilterSupport.NewSessionData;
34 import edu.internet2.middleware.shibboleth.runner.ShibbolethRunner;
35 import edu.internet2.middleware.shibboleth.serviceprovider.AssertionConsumerServlet;
36 import edu.internet2.middleware.shibboleth.serviceprovider.ServiceProviderContext;
37 import edu.internet2.middleware.shibboleth.serviceprovider.Session;
38 import edu.internet2.middleware.shibboleth.serviceprovider.SessionManager;
41 * A JUnit test case that exercises the IdP, SP, and Filter
42 * @author Howard Gilbert
44 public class IntegrationTest extends TestCase {
46 ShibbolethRunner runner;
47 ShibbolethRunner.IdpTestContext idp;
48 ShibbolethRunner.AuthenticationFilterContext filter;
52 protected void setUp() throws Exception {
55 // Static call to set Log4J appenders and levels
56 ShibbolethRunner.loglevel = Level.DEBUG;
57 ShibbolethRunner.setupLogging();
59 // Create the overall testing framework
60 runner = new ShibbolethRunner();
62 // Initialize the Idp, create the Mockrunner
63 // objects to do SSO, AA, and Artifact calls, and
64 // configure SAML to use the MockHTTPBindingProvider
65 runner.setIdpConfigFileName("/basicIdpHome/idpconfig.xml");
66 idp = runner.getIdp();
68 // Initialize the SP with the default config file.
69 runner.setSpConfigFileName("/basicSpHome/spconfig.xml");
70 runner.initializeSP();
72 // Initialize the Filter and create its separate
73 // Mockrunner simulated context.
74 filter= runner.getFilter();
76 // Make changes to Filter init-param values before setUp.
79 // Create attributes to be returned from the IdP
80 // This could be done in each test, just as long as it
81 // is done before the SSO.
82 Attributes attributes = runner.getAttributesCollection();
83 attributes.put(new BasicAttribute("eduPersonAffiliation", "member"));
84 attributes.put(new BasicAttribute("eduPersonScopedAffiliation", "member"));
85 attributes.put(new BasicAttribute("title", "clown"));
86 attributes.put(new BasicAttribute("givenName", "bozo"));
87 attributes.put(new BasicAttribute("surname", "Clown"));
91 public void testAttributePush() throws SAMLException {
93 // Set the URL suffix that triggers SSO processing
94 idp.setRequestUrls("SSO");
96 // Add the WAYF/RM parameters
97 idp.testModule.addRequestParameter("target", "https://nonsense");
98 idp.testModule.addRequestParameter("shire","https://sp.example.org/Shibboleth.sso/SAML/POST");
99 idp.testModule.addRequestParameter("providerId", "https://sp.example.org/shibboleth");
101 // Add a userid, as if provided by Basic Authentication or a Filter
102 idp.request.setRemoteUser("BozoTClown");
104 // Force Attribute Push
105 ShibbolethV1SSOHandler.pushAttributeDefault=true;
108 idp.testModule.doGet();
111 * Sanity check: The IdP normally ends by transferring control to a
112 * JSP page that generates the FORM. However, we have not set up
113 * Mockrunner to perform the transfer, because the form would just
114 * create parsing work. Rather, the following code extracts the
115 * information from the request attributes that the JSP would have
116 * used as its source.
118 String bin64assertion = (String) idp.request.getAttribute("assertion");
119 String assertion = new String(Base64.decodeBase64(bin64assertion.getBytes()));
120 String handlerURL = (String) idp.request.getAttribute("shire");
121 String targetURL = (String) idp.request.getAttribute("target");
124 // Build the parameter for Session creation
125 NewSessionData data = new NewSessionData();
126 FilterUtil.sessionDataFromRequest(data,idp.request);
127 data.SAMLResponse = bin64assertion; // test logic
128 data.target=targetURL;
129 data.applicationId="default";
130 data.handlerURL=handlerURL;
131 data.providerId="https://sp.example.org/shibboleth";
133 // Create the session, extract pushed Attributes
134 String sessionId = AssertionConsumerServlet.createSessionFromData(data);
136 // Now get what was created in case you want to test it.
137 ServiceProviderContext context = ServiceProviderContext.getInstance();
138 Session session = context.getSessionManager().findSession(sessionId, "default");
140 // Pass the SessionId to the Filter, let it fetch the attributes
141 filter.testModule.addRequestParameter("ShibbolethSessionId", sessionId);
142 filter.setRequestUrls("test.txt");
143 filter.testModule.doFilter();
146 * Sanity Check: doFilter runs just the Filter itself. On
147 * input there was a Request and Response. When done, there
148 * will be a replacement Request object created by the Filter
149 * wrapping the original request and adding features.
152 // Get the Request Wrapper object created by the Filter
153 HttpServletRequest filteredRequest =
154 (HttpServletRequest) filter.testModule.getFilteredRequest();
156 // Now do something that uses Filter supplied logic
157 Enumeration headerNames = filteredRequest.getHeaderNames();
158 while (headerNames.hasMoreElements()) {
159 String name = (String) headerNames.nextElement();
160 String value = (String) filteredRequest.getHeader(name);
161 System.out.println(name+ "-"+value );
167 public void testAttributeQuery() throws SAMLException {
169 // Set the URL suffix that triggers SSO processing
170 idp.setRequestUrls("SSO");
172 // Add the WAYF/RM parameters
173 idp.testModule.addRequestParameter("target", "https://nonsense");
174 idp.testModule.addRequestParameter("shire","https://sp.example.org/Shibboleth.sso/SAML/POST");
175 idp.testModule.addRequestParameter("providerId", "https://sp.example.org/shibboleth");
177 // Add a userid, as if provided by Basic Authentication or a Filter
178 idp.request.setRemoteUser("BozoTClown");
180 // Block Attribute Push
181 ShibbolethV1SSOHandler.pushAttributeDefault=false;
184 idp.testModule.doGet();
186 String bin64assertion = (String) idp.request.getAttribute("assertion");
187 String assertion = new String(Base64.decodeBase64(bin64assertion.getBytes()));
188 String handlerURL = (String) idp.request.getAttribute("shire");
189 String targetURL = (String) idp.request.getAttribute("target");
192 // Build the parameter for Session creation
193 NewSessionData data = new NewSessionData();
194 FilterUtil.sessionDataFromRequest(data,idp.request);
195 data.SAMLResponse = bin64assertion; // test logic
196 data.target=targetURL;
197 data.applicationId="default";
198 data.handlerURL=handlerURL;
199 data.providerId="https://sp.example.org/shibboleth";
201 // Create the Session
202 // Internally an AA Query will fetch the attributes through the
203 // MockHTTPBindingProvider
204 String sessionId = AssertionConsumerServlet.createSessionFromData(data);
207 // Now get what was created in case you want to test it.
208 ServiceProviderContext context = ServiceProviderContext.getInstance();
209 Session session = context.getSessionManager().findSession(sessionId, "default");
210 StringBuffer buffer = SessionManager.dumpAttributes(session);
211 System.out.println(buffer.toString());
213 // Pass the SessionId to the Filter, let it fetch the attributes
214 filter.testModule.addRequestParameter("ShibbolethSessionId", sessionId);
215 filter.setRequestUrls("test.txt"); // need any URL
216 filter.testModule.doFilter();
218 // Get the Request Wrapper object created by the Filter
219 HttpServletRequest filteredRequest = (HttpServletRequest) filter.testModule.getFilteredRequest();
221 // Now do something that uses Filter supplied logic
222 Enumeration headerNames = filteredRequest.getHeaderNames();
223 while (headerNames.hasMoreElements()) {
224 String name = (String) headerNames.nextElement();
225 String value = (String) filteredRequest.getHeader(name);
226 System.out.println(name+ "-"+value );