Removed println.
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / idp / provider / E_AuthSSOHandler.java
index eb1ef68..6fea7d7 100644 (file)
@@ -77,10 +77,9 @@ public class E_AuthSSOHandler extends SSOHandler implements IdPProtocolHandler {
 
        private static Logger log = Logger.getLogger(E_AuthSSOHandler.class.getName());
        private String eAuthPortal = "http://eauth.firstgov.gov/service/select";
+       private String eAuthError = "http://eauth.firstgov.gov/service/error";
        private String csid;
 
-       // TODO profile-specific error handling
-
        /**
         * Required DOM-based constructor.
         */
@@ -92,10 +91,16 @@ public class E_AuthSSOHandler extends SSOHandler implements IdPProtocolHandler {
                        log.error("(csid) attribute is required for the " + getHandlerName() + "protocol handler.");
                        throw new ShibbolethConfigurationException("Unable to initialize protocol handler.");
                }
+
                String portal = config.getAttribute("eAuthPortal");
                if (portal != null && !portal.equals("")) {
                        eAuthPortal = portal;
                }
+
+               String error = config.getAttribute("eAuthError");
+               if (error != null && !error.equals("")) {
+                       eAuthError = portal;
+               }
        }
 
        /*
@@ -115,7 +120,7 @@ public class E_AuthSSOHandler extends SSOHandler implements IdPProtocolHandler {
                        SAMLRequest samlRequest, IdPProtocolSupport support) throws SAMLException, IOException, ServletException {
 
                // Sanity check
-               if (request != null) {
+               if (samlRequest != null) {
                        log.error("Protocol Handler received a SAML Request, but is unable to handle it.");
                        throw new SAMLException(SAMLException.RESPONDER, "General error processing request.");
                }
@@ -166,27 +171,31 @@ public class E_AuthSSOHandler extends SSOHandler implements IdPProtocolHandler {
 
                if (relyingParty == null || relyingParty.isLegacyProvider()) {
                        log.error("Unable to identify appropriate relying party configuration.");
-                       throw new SAMLException(SAMLException.RESPONDER, "General error processing request.");
+                       eAuthError(response, 30, remoteProviderId, csid);
+                       return null;
                }
 
                // Lookup the provider in the metadata
                EntityDescriptor entity = support.lookup(relyingParty.getProviderId());
                if (entity == null) {
                        log.error("No metadata found for EAuth provider.");
-                       throw new SAMLException(SAMLException.RESPONDER, "General error processing request.");
+                       eAuthError(response, 30, remoteProviderId, csid);
+                       return null;
                }
                SPSSODescriptor role = entity.getSPSSODescriptor("urn:oasis:names:tc:SAML:1.1:protocol");
                if (role == null) {
                        log.error("Inappropriate metadata for EAuth provider.");
-                       throw new SAMLException(SAMLException.RESPONDER, "General error processing request.");
+                       eAuthError(response, 30, remoteProviderId, csid);
+                       return null;
                }
 
                // The EAuth profile requires metadata, since the assertion consumer is not supplied as a request parameter
                // Pull the consumer URL from the metadata
-               Iterator endpoints = role.getAttributeConsumingServices();
-               if (!endpoints.hasNext()) {
+               Iterator endpoints = role.getAssertionConsumerServiceManager().getEndpoints();
+               if (endpoints == null || !endpoints.hasNext()) {
                        log.error("Inappropriate metadata for provider: no roles specified.");
-                       throw new SAMLException(SAMLException.RESPONDER, "General error processing request.");
+                       eAuthError(response, 30, remoteProviderId, csid);
+                       return null;
                }
                String consumerURL = ((Endpoint) endpoints.next()).getLocation();
                log.debug("Assertion Consumer URL provider: " + consumerURL);
@@ -194,12 +203,13 @@ public class E_AuthSSOHandler extends SSOHandler implements IdPProtocolHandler {
                // Create SAML Name Identifier & Subject
                SAMLNameIdentifier nameId;
                try {
-                       nameId = support.getNameMapper().getNameIdentifierName(
-                                       "urn:oasis:names:tc:SAML:1.0:assertion#X509SubjectName", principal, relyingParty,
-                                       relyingParty.getIdentityProvider());
+                       // TODO verify that the nameId is the right format here and error if not
+                       nameId = support.getNameMapper().getNameIdentifierName(relyingParty.getHSNameFormatId(), principal,
+                                       relyingParty, relyingParty.getIdentityProvider());
                } catch (NameIdentifierMappingException e) {
                        log.error("Error converting principal to SAML Name Identifier: " + e);
-                       throw new SAMLException(SAMLException.RESPONDER, "General error processing request.");
+                       eAuthError(response, 60, remoteProviderId, csid);
+                       return null;
                }
 
                String[] confirmationMethods = {SAMLSubject.CONF_ARTIFACT};
@@ -236,7 +246,8 @@ public class E_AuthSSOHandler extends SSOHandler implements IdPProtocolHandler {
                        attributes = Arrays.asList(support.getReleaseAttributes(principal, relyingParty.getProviderId(), null));
                } catch (AAException e1) {
                        log.error("Error resolving attributes: " + e1);
-                       throw new SAMLException(SAMLException.RESPONDER, "General error processing request.");
+                       eAuthError(response, 90, remoteProviderId, csid);
+                       return null;
                }
                log.info("Found " + attributes.size() + " attribute(s) for " + principal.getName());
 
@@ -244,12 +255,18 @@ public class E_AuthSSOHandler extends SSOHandler implements IdPProtocolHandler {
                if (attributes == null || attributes.size() < 1) {
                        log.error("Attribute resolver did not return any attributes. "
                                        + " The E-Authentication profile's minimum attribute requirements were not met.");
-                       throw new SAMLException(SAMLException.RESPONDER, "General error processing request.");
+                       eAuthError(response, 60, remoteProviderId, csid);
+                       return null;
 
                        // OK, we got attributes back, package them as required for eAuth and combine them with the authN data in an
                        // assertion
                } else {
-                       repackageForEauth(attributes);
+                       try {
+                               attributes = repackageForEauth(attributes);
+                       } catch (SAMLException e) {
+                               eAuthError(response, 90, remoteProviderId, csid);
+                               return null;
+                       }
 
                        // Put all attributes into an assertion
                        try {
@@ -266,12 +283,19 @@ public class E_AuthSSOHandler extends SSOHandler implements IdPProtocolHandler {
                                }
 
                                // Redirect to agency application
-                               respondWithArtifact(response, support, consumerURL, principal, assertion, nameId, role, relyingParty);
-                               return null;
+                               try {
+                                       respondWithArtifact(response, support, consumerURL, principal, assertion, nameId, role,
+                                                       relyingParty);
+                                       return null;
+                               } catch (SAMLException e) {
+                                       eAuthError(response, 90, remoteProviderId, csid);
+                                       return null;
+                               }
 
                        } catch (CloneNotSupportedException e) {
                                log.error("An error was encountered while generating assertion: " + e);
-                               throw new SAMLException(SAMLException.RESPONDER, "General error processing request.");
+                               eAuthError(response, 90, remoteProviderId, csid);
+                               return null;
                        }
                }
        }
@@ -302,7 +326,7 @@ public class E_AuthSSOHandler extends SSOHandler implements IdPProtocolHandler {
                // Construct the artifact query parameter
                while (iterator.hasNext()) {
                        Artifact artifact = (Artifact) iterator.next();
-                       artifactBuffer.append("(" + artifact + ")");
+                       artifactBuffer.append("(" + artifact.encode() + ")");
                        destination.append("&SAMLart=");
                        destination.append(URLEncoder.encode(artifact.encode(), "UTF-8"));
                }
@@ -311,16 +335,17 @@ public class E_AuthSSOHandler extends SSOHandler implements IdPProtocolHandler {
                response.sendRedirect(destination.toString()); // Redirect to the artifact receiver
                support.getTransactionLog().info(
                                "Assertion artifact(s) (" + artifactBuffer.toString() + ") issued to E-Authentication provider ("
-                                               + relyingParty.getIdentityProvider().getProviderId() + ") on behalf of principal ("
+                                               + relyingParty.getProviderId() + ") on behalf of principal ("
                                                + principal.getName() + "). Name Identifier: (" + nameId.getName()
                                                + "). Name Identifier Format: (" + nameId.getFormat() + ").");
 
        }
 
-       private void repackageForEauth(List attributes) throws SAMLException {
+       private List repackageForEauth(List attributes) throws SAMLException {
 
+               ArrayList  writeable = new ArrayList(attributes); 
                // Bail if we didn't get a commonName, because it is required by the profile
-               SAMLAttribute commonName = getAttribute("commonName", attributes);
+               SAMLAttribute commonName = getAttribute("commonName", writeable);
                if (commonName == null) {
                        log.error("The attribute resolver did not return a (commonName) attribute, "
                                        + " which is required for the E-Authentication profile.");
@@ -330,11 +355,12 @@ public class E_AuthSSOHandler extends SSOHandler implements IdPProtocolHandler {
                        commonName.setNamespace("http://eauthentication.gsa.gov/federated/attribute");
                        // TODO Maybe the resolver should set this
                }
-               attributes.add(new SAMLAttribute("csid", "http://eauthentication.gsa.gov/federated/attribute", null, 0, Arrays
+               writeable.add(new SAMLAttribute("csid", "http://eauthentication.gsa.gov/federated/attribute", null, 0, Arrays
                                .asList(new String[]{csid})));
                // TODO pull from authN system? or make configurable
-               attributes.add(new SAMLAttribute("assuranceLevel", "http://eauthentication.gsa.gov/federated/attribute", null,
+               writeable.add(new SAMLAttribute("assuranceLevel", "http://eauthentication.gsa.gov/federated/attribute", null,
                                0, Arrays.asList(new String[]{"2"})));
+               return writeable;
        }
 
        private SAMLAttribute getAttribute(String name, List attributes) {
@@ -346,4 +372,10 @@ public class E_AuthSSOHandler extends SSOHandler implements IdPProtocolHandler {
                }
                return null;
        }
+
+       private void eAuthError(HttpServletResponse response, int code, String aaid, String csid) throws IOException {
+
+               log.info("Redirecting to E-Authentication error page.");
+               response.sendRedirect(eAuthError + "?aaid=" + aaid + "&csid=" + csid + "&errcode=" + code);
+       }
 }
\ No newline at end of file