2 * Copyright [2007] [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.idp.profile.saml2;
19 import javax.servlet.ServletRequest;
20 import javax.servlet.ServletResponse;
21 import javax.servlet.http.HttpServletRequest;
22 import javax.servlet.http.HttpServletResponse;
24 import org.apache.log4j.Logger;
25 import org.opensaml.common.binding.BindingException;
26 import org.opensaml.saml2.binding.HTTPSOAP11Decoder;
27 import org.opensaml.saml2.binding.HTTPSOAP11Encoder;
28 import org.opensaml.saml2.core.AttributeStatement;
29 import org.opensaml.saml2.core.Response;
30 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
31 import org.opensaml.xml.encryption.EncryptionException;
33 import edu.internet2.middleware.shibboleth.common.attribute.AttributeRequestException;
34 import edu.internet2.middleware.shibboleth.common.attribute.provider.ShibbolethAttributeRequestContext;
35 import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolver;
36 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
37 import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
38 import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
39 import edu.internet2.middleware.shibboleth.idp.session.ServiceInformation;
42 * SAML 2.0 SOAP Attribute Query profile handler.
44 public class HTTPSOAPAttributeQuery extends AbstractAttributeQuery {
47 private static Logger log = Logger.getLogger(HTTPSOAPAttributeQuery.class);
50 * This creates a new http soap attribute query.
52 * @param ar <code>AttributeResolver</code>
54 public HTTPSOAPAttributeQuery(AttributeResolver<ShibbolethAttributeRequestContext> ar) {
59 public void processRequest(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response)
60 throws ProfileException {
61 if (log.isDebugEnabled()) {
62 log.debug("begin processRequest");
65 // check that request/response is of proper type
66 if (!(request.getRawRequest() instanceof HttpServletRequest)) {
67 throw new ProfileException(HTTPSOAPAttributeQuery.class.getName() + " can only process requests of type "
68 + HttpServletRequest.class.getName());
69 } else if (!(response.getRawResponse() instanceof HttpServletResponse)) {
70 throw new ProfileException(HTTPSOAPAttributeQuery.class.getName() + " can only process responses of type "
71 + HttpServletResponse.class.getName());
75 HTTPSOAP11Decoder decoder = new HTTPSOAP11Decoder();
76 decoder.setMetadataProvider(getMetadataProvider());
77 // TODO decoder.setSecurityPolicy(policy);
78 // TODO decoder.setTrustEngine(newEngine);
80 // get message from the decoder
81 org.opensaml.saml2.core.AttributeQuery message = null;
83 decoder.setRequest((HttpServletRequest) request.getRawRequest());
85 if (log.isDebugEnabled()) {
86 log.debug("decoded http servlet request");
88 message = (org.opensaml.saml2.core.AttributeQuery) decoder.getSAMLMessage();
89 } catch (BindingException e) {
90 log.error("Error decoding attribute query message", e);
91 throw new ProfileException("Error decoding attribute query message");
94 // get the provider id from the message issuer
95 String providerId = message.getIssuer().getSPProvidedID();
97 // TODO get user data from the session, need sessionId
98 // ?? getSessionManager().getSession(null).getServicesInformation().get(0);
99 ServiceInformation serviceInformation = null;
100 String principalName = serviceInformation.getSubjectNameID().getSPProvidedID();
101 String authenticationMethod = serviceInformation.getAuthenticationMethod().getAuthenticationMethod();
103 // create attribute request for the attribute authority
104 ShibbolethAttributeRequestContext requestContext = null;
106 requestContext = new ShibbolethAttributeRequestContext(getMetadataProvider(),
107 getRelyingPartyConfiguration(providerId));
108 requestContext.setPrincipalName(principalName);
109 requestContext.setPrincipalAuthenticationMethod(authenticationMethod);
110 requestContext.setRequest(request.getRawRequest());
111 } catch (MetadataProviderException e) {
112 log.error("Error creating ShibbolethAttributeRequestContext", e);
113 throw new ProfileException("Error retrieving metadata", e);
116 // resolve attributes with the attribute authority
117 AttributeStatement statement = null;
119 statement = getAttributeAuthority().performAttributeQuery(requestContext);
120 } catch (AttributeRequestException e) {
121 log.error("Error resolving attributes", e);
122 throw new ProfileException("Error resolving attributes", e);
125 // construct attribute response
126 Response samlResponse = null;
128 ProfileResponseContext profileResponse = new ProfileResponseContext(request, message);
129 profileResponse.setIssuer(decoder.getSecurityPolicy().getIssuer().toString());
130 profileResponse.setDestination(request.getRawRequest().getRemoteHost());
131 profileResponse.setAttributeStatement(statement);
132 samlResponse = buildResponse(profileResponse);
133 } catch (EncryptionException e) {
134 log.error("Error encrypting SAML response", e);
135 throw new ProfileException("Error encrypting SAML response", e);
137 if (log.isDebugEnabled()) {
138 log.debug("built saml2 response: " + samlResponse);
143 HTTPSOAP11Encoder encoder = new HTTPSOAP11Encoder();
144 encoder.setMetadataProvider(getMetadataProvider());
145 encoder.setRelyingParty(getRelyingPartyConfiguration(providerId).getRelyingPartyId());
146 encoder.setResponse((HttpServletResponse) response.getRawResponse());
147 encoder.setSAMLMessage(samlResponse);
149 } catch (BindingException e) {
150 log.error("Error encoding attribute query response", e);
151 throw new ProfileException("Error encoding attribute query response", e);