cleanup, add checks to arguments and responses, add log statements
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / common / ShibBrowserProfile.java
1 /*
2  * Copyright [2005] [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.common;
18
19 import java.util.ArrayList;
20
21 import javax.servlet.http.HttpServletRequest;
22
23 import org.apache.log4j.Logger;
24 import org.opensaml.NoSuchProviderException;
25 import org.opensaml.ReplayCache;
26 import org.opensaml.SAMLBrowserProfile;
27 import org.opensaml.SAMLBrowserProfileFactory;
28 import org.opensaml.SAMLException;
29 import org.opensaml.TrustException;
30 import org.opensaml.SAMLBrowserProfile.ArtifactMapper;
31 import org.opensaml.SAMLBrowserProfile.BrowserProfileRequest;
32 import org.opensaml.SAMLBrowserProfile.BrowserProfileResponse;
33
34 import edu.internet2.middleware.shibboleth.metadata.EntityDescriptor;
35 import edu.internet2.middleware.shibboleth.metadata.IDPSSODescriptor;
36 import edu.internet2.middleware.shibboleth.metadata.MetadataException;
37 import edu.internet2.middleware.shibboleth.serviceprovider.ServiceProviderConfig;
38 import edu.internet2.middleware.shibboleth.serviceprovider.ServiceProviderContext;
39 import edu.internet2.middleware.shibboleth.serviceprovider.ServiceProviderConfig.ApplicationInfo;
40
41 /**
42  * Basic Shibboleth POST browser profile implementation with basic support for signing
43  * 
44  * @author Scott Cantor @created April 11, 2002
45  */
46 public class ShibBrowserProfile  {
47
48         private static Logger   log                     = Logger.getLogger(ShibBrowserProfile.class.getName());
49
50     /** Policy URIs to attach or check against */
51     protected ArrayList     policies    = new ArrayList();
52
53     protected SAMLBrowserProfile profile = SAMLBrowserProfileFactory.getInstance(); 
54     private static ServiceProviderContext context = ServiceProviderContext.getInstance();
55     private String applicationId = null;
56     
57     /**
58      * Identify the <Application> from which to get plugins.
59      * 
60      * @param applicationId 
61      */
62     public ShibBrowserProfile(String applicationId) throws NoSuchProviderException {
63         this.applicationId = applicationId;
64     }
65
66
67     /**
68      * @see org.opensaml.SAMLBrowserProfile#receive(java.lang.StringBuffer, javax.servlet.http.HttpServletRequest, java.lang.String, int, org.opensaml.ReplayCache, org.opensaml.SAMLBrowserProfile.ArtifactMapper, int)
69      */
70     public BrowserProfileResponse receive(
71             StringBuffer issuer,
72             HttpServletRequest reqContext,
73             String recipient,
74             ReplayCache replayCache,
75             ArtifactMapper artifactMapper,
76             int minorVersion
77             ) throws SAMLException {
78         
79         String providerId = null;
80         issuer.setLength(0);
81         
82         // Let SAML do all the decoding and parsing
83         BrowserProfileRequest bpRequest = profile.receive(reqContext);
84         BrowserProfileResponse bpr = profile.receive(issuer, bpRequest, recipient, replayCache, artifactMapper, minorVersion);
85         
86         /*
87          * Now find the Metadata for the Entity that send this assertion.
88          * From the C++, look first for issuer, then namequalifier (for 1.1 compat.)
89          */
90         EntityDescriptor entity = null;
91         String asn_issuer = bpr.assertion.getIssuer();
92         String qualifier = bpr.authnStatement.getSubject().getNameIdentifier().getNameQualifier();
93         ServiceProviderConfig config = context.getServiceProviderConfig();
94         ApplicationInfo appinfo = config.getApplication(applicationId);
95         
96         entity = appinfo.lookup(asn_issuer);
97         providerId=asn_issuer;
98         if (entity==null) {
99             providerId=qualifier;
100             entity= appinfo.lookup(qualifier);
101         }
102         if (entity==null) {
103             log.error("assertion issuer not found in metadata(Issuer ="+
104                     issuer+", NameQualifier="+qualifier);
105             throw new MetadataException("ShibBrowserProfile.receive() metadata lookup failed, unable to process assertion");
106         }
107         issuer.append(providerId);
108         
109         IDPSSODescriptor role = entity.getIDPSSODescriptor(
110                 minorVersion==1?
111                     org.opensaml.XML.SAML11_PROTOCOL_ENUM :
112                     org.opensaml.XML.SAML10_PROTOCOL_ENUM
113                 );
114         
115         if (bpr.response.isSigned()) {
116             boolean signatureValid = appinfo.validate(bpr.response,role);
117             if (!signatureValid) {
118                 throw new TrustException("ShibBrowserProfile cannot validate signature on response from SSO");
119             }
120         }
121         if (bpr.assertion.isSigned()) {
122             boolean signatureValid = appinfo.validate(bpr.assertion,role);
123             if (!signatureValid) {
124                 throw new TrustException("ShibBrowserProfile cannot validate signature on assertion from SSO");
125             }
126         }
127         
128         return bpr;
129     }
130 }