ebe2d94ff9528606090172a2e28320a60149b109
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / idp / profile / saml2 / AuthenticationRequestBrowserPost.java
1 /*
2  * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package edu.internet2.middleware.shibboleth.idp.profile.saml2;
18
19 import javax.servlet.ServletRequest;
20 import javax.servlet.ServletResponse;
21 import javax.servlet.http.HttpServletRequest;
22 import javax.servlet.http.HttpServletResponse;
23 import javax.servlet.http.HttpSession;
24 import javax.servlet.ServletException;
25
26 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
27 import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
28 import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
29 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration;
30 import edu.internet2.middleware.shibboleth.common.relyingparty.saml2.SSOConfiguration;
31
32 import org.apache.log4j.Logger;
33 import org.opensaml.common.SAMLObject;
34 import org.opensaml.common.binding.BindingException;
35 import org.opensaml.common.binding.MessageDecoder;
36 import org.opensaml.saml2.core.AuthnRequest;
37 import org.opensaml.saml2.core.Issuer;
38 import org.opensaml.saml2.core.Response;
39 import org.opensaml.saml2.binding.HTTPPostDecoder;
40 import org.opensaml.saml2.metadata.SPSSODescriptor;
41
42 /**
43  * Browser POST binding for SAML 2 AuthenticationRequest.
44  */
45 public class AuthenticationRequestBrowserPost extends AbstractAuthenticationRequest {
46     
47     /** Class logger. */
48     private static final Logger log = Logger.getLogger(AuthenticationRequestBrowserPost.class);
49     
50     /** Constructor. */
51     public AuthenticationRequestBrowserPost() {
52         super();
53     }
54     
55     /** {@inheritDoc} */
56     public void processRequest(final ProfileRequest<ServletRequest> request,
57             final ProfileResponse<ServletResponse> response)
58             throws ProfileException {
59         
60         // Only http servlets are supported for now.
61         if (!(request.getRawRequest() instanceof HttpServletRequest)) {
62             log.error("Received a non-HTTP request");
63             throw new ServletException("Received a non-HTTP request");
64         }
65         
66         HttpServletRequest httpReq = (HttpServletRequest) request.getRawRequest();
67         HttpServletResponse httpResp = (HttpServletResponse) response.getRawResponse();
68         HttpSession httpSession = httpReq.getSession();
69         
70         AuthnRequest authnRequest;
71         Issuer issuer;
72         RelyingPartyConfiguration relyingParty;
73         SSOConfiguration ssoConfig;
74         SPSSODescriptor spDescriptor;
75         
76         // If the user hasn't been authenticated, validate the AuthnRequest
77         // and redirect to AuthenticationManager to authenticate the user.
78         if (!hasUserAuthenticated(httpSession)) {
79             
80             try {
81                 MessageDecoder<HttpServletRequest> decoder = new HTTPPostDecoder();
82                 decoder.setMetadataProvider(getRelyingPartyConfigurationManager().getMetadataProvider());
83                 // decoder.setSecurityPolicy(??);
84                 // decoder.setTrustEngine(??);
85                 decoder.setRequest(httpReq);
86                 decoder.decode();
87                 SAMLObject samlObject = decoder.getSAMLMessage();
88                 if (!(samlObject instanceof AuthnRequest)) {
89                     log.error("SAML 2 AuthnRequest: Received message is not a SAML 2 Authentication Request");
90                     throw new ProfileException("SAML 2 AuthnRequest: Received message is not a SAML 2 Authentication Request");
91                 }
92                 
93                 authnRequest = (AuthnRequest) samlObject;
94                 issuer = (Issuer) decoder.getSecurityPolicy().getIssuer();
95                 
96                 if (!findMetadataForSSORequest(issuer, relyingParty, ssoConfig, spDescriptor)) {
97                     throw new ProfileException(
98                             "SAML 2 AuthnRequest: Unable to locate metadata for issuer: "
99                             + issuer.getSPProvidedID());
100                 }
101                 
102                 verifyAuthnRequest(authnRequest, issuer, relyingParty, httpSession);
103                 storeRequestData(httpSession, authnRequest, issuer, relyingParty, ssoConfig, spDescriptor);
104                 authenticateUser(authnRequest, httpSession, httpReq, httpResp);
105                 
106             } catch (BindingException ex) {
107                 log.error("SAML 2 Authentication Request: Unable to decode SAML 2 Authentication Request", ex);
108                 throw new ProfileException(
109                         "SAML 2 Authentication Request: Unable to decode SAML 2 Authentication Request", ex);
110             } catch (AuthenticationRequestException ex) {
111                 // XXX: todo: generate and send the error, with a REQUEST_URI
112                 // failure.
113             }
114         }
115         
116         // The user has already been authenticated,
117         // so generate an AuthenticationStatement.
118         retrieveRequestData(httpSession, authnRequest, issuer, relyingParty, ssoConfig, spDescriptor);
119         Response samlResponse = evaluateRequest(authnRequest, issuer, httpSession, relyingParty, ssoConfig, spDescriptor);
120         encodeResponse(response, samlResponse, relyingParty, ssoConfig, spDescriptor);
121     }
122     
123     protected void encodeResponse(final ProfileResponse response,
124             final Response samlResponse,
125             final RelyingPartyConfiguration relyingParty,
126             final SSOConfiguration ssoConfig, final SPSSODescriptor spDescriptor) {
127         // xxx: todo
128     }
129 }