Use protocol support constant instead of literal.
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / idp / provider / SSOHandler.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.idp.provider;
18
19 import java.text.ParseException;
20 import java.text.SimpleDateFormat;
21 import java.util.Date;
22 import java.util.Iterator;
23
24 import javax.servlet.http.HttpServletRequest;
25
26 import org.apache.log4j.Logger;
27 import org.opensaml.SAMLException;
28 import org.opensaml.SAMLNameIdentifier;
29 import org.w3c.dom.Element;
30
31 import edu.internet2.middleware.shibboleth.common.LocalPrincipal;
32 import edu.internet2.middleware.shibboleth.common.NameIdentifierMapping;
33 import edu.internet2.middleware.shibboleth.common.NameIdentifierMappingException;
34 import edu.internet2.middleware.shibboleth.common.NameMapper;
35 import edu.internet2.middleware.shibboleth.common.RelyingParty;
36 import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationException;
37 import edu.internet2.middleware.shibboleth.idp.IdPProtocolHandler;
38 import edu.internet2.middleware.shibboleth.idp.InvalidClientDataException;
39 import edu.internet2.middleware.shibboleth.metadata.EntityDescriptor;
40 import edu.internet2.middleware.shibboleth.metadata.SPSSODescriptor;
41
42 /**
43  * @author Walter Hoehn
44  */
45 public abstract class SSOHandler extends BaseHandler implements IdPProtocolHandler {
46
47         private static Logger log = Logger.getLogger(BaseHandler.class.getName());
48
49         /**
50          * Required DOM-based constructor.
51          */
52         public SSOHandler(Element config) throws ShibbolethConfigurationException {
53
54                 super(config);
55
56         }
57
58         public static void validateEngineData(HttpServletRequest req) throws InvalidClientDataException {
59
60                 if ((req.getRemoteAddr() == null) || (req.getRemoteAddr().equals(""))) { throw new InvalidClientDataException(
61                                 "Unable to obtain client address."); }
62         }
63
64         protected Date getAuthNTime(HttpServletRequest request) throws SAMLException {
65
66                 // Determine, if possible, when the authentication actually happened
67                 String suppliedAuthNInstant = request.getHeader("SAMLAuthenticationInstant");
68                 if (suppliedAuthNInstant != null && !suppliedAuthNInstant.equals("")) {
69                         try {
70                                 return new SimpleDateFormat().parse(suppliedAuthNInstant);
71                         } catch (ParseException e) {
72                                 log.error("An error was encountered while receiving authentication "
73                                                 + "instant from authentication mechanism: " + e);
74                                 throw new SAMLException(SAMLException.RESPONDER, "General error processing request.");
75                         }
76                 } else {
77                         return new Date(System.currentTimeMillis());
78                 }
79         }
80
81         /**
82          * Constructs a SAML Name Identifier of a given principal that is most appropriate to the relying party.
83          * 
84          * @param mapper
85          *            name mapping facility
86          * @param principal
87          *            the principal represented by the name identifier
88          * @param relyingParty
89          *            the party that will consume the name identifier
90          * @param descriptor
91          *            metadata descriptor for the party that will consume the name identifier
92          * @return the SAML Name identifier
93          * @throws NameIdentifierMappingException
94          *             if a name identifier could not be created
95          */
96         protected SAMLNameIdentifier getNameIdentifier(NameMapper mapper, LocalPrincipal principal,
97                         RelyingParty relyingParty, EntityDescriptor descriptor) throws NameIdentifierMappingException {
98
99                 String[] availableMappings = relyingParty.getNameMapperIds();
100
101                 // If we have preferred Name Identifier formats from the metadata, see if the we can find one that is configured
102                 // for this relying party
103                 SPSSODescriptor role;
104                 if (descriptor != null
105                                 && (role = descriptor.getSPSSODescriptor(org.opensaml.XML.SAML11_PROTOCOL_ENUM)) != null) {
106                         Iterator spPreferredFormats = role.getNameIDFormats();
107                         while (spPreferredFormats.hasNext()) {
108
109                                 String preferredFormat = (String) spPreferredFormats.next();
110                                 for (int i = 0; availableMappings != null && i < availableMappings.length; i++) {
111                                         NameIdentifierMapping mapping = mapper.getNameIdentifierMappingById(availableMappings[i]);
112                                         if (mapping != null && preferredFormat.equals(mapping.getNameIdentifierFormat().toString())) {
113                                                 log.debug("Found a supported name identifier format that "
114                                                                 + "matches the metadata for the relying party: ("
115                                                                 + mapping.getNameIdentifierFormat().toString() + ").");
116                                                 return mapping.getNameIdentifier(principal, relyingParty, relyingParty.getIdentityProvider());
117                                         }
118                                 }
119                         }
120                 }
121
122                 // If we didn't find any matches, then just use the default for the relying party
123                 String defaultNameMapping = null;
124                 if (availableMappings != null && availableMappings.length > 0) {
125                         defaultNameMapping = availableMappings[0];
126                 }
127                 SAMLNameIdentifier nameId = mapper.getNameIdentifier(defaultNameMapping, principal, relyingParty, relyingParty
128                                 .getIdentityProvider());
129                 log.debug("Using the default name identifier format for this relying party: (" + nameId.getFormat());
130                 return nameId;
131         }
132 }