package edu.internet2.middleware.shibboleth.idp.provider;
+import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import javax.security.auth.x500.X500Principal;
import javax.servlet.http.HttpServletRequest;
+import org.apache.log4j.Logger;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.KeyInfo;
+
+import edu.internet2.middleware.shibboleth.common.ShibBrowserProfile;
import edu.internet2.middleware.shibboleth.idp.IdPProtocolHandler;
+import edu.internet2.middleware.shibboleth.metadata.EntityDescriptor;
+import edu.internet2.middleware.shibboleth.metadata.KeyDescriptor;
+import edu.internet2.middleware.shibboleth.metadata.SPSSODescriptor;
/**
* @author Walter Hoehn
*/
public abstract class BaseServiceHandler implements IdPProtocolHandler {
+ private static Logger log = Logger.getLogger(BaseServiceHandler.class.getName());
+
protected static X509Certificate getCredentialFromProvider(HttpServletRequest req) {
X509Certificate[] certArray = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
return null;
}
+ protected static boolean isValidCredential(EntityDescriptor provider, X509Certificate certificate) {
+
+ SPSSODescriptor sp = provider.getSPSSODescriptor(org.opensaml.XML.SAML11_PROTOCOL_ENUM);
+ if (sp == null) {
+ log.info("Inappropriate metadata for provider.");
+ return false;
+ }
+ // TODO figure out what to do about this role business here
+ Iterator descriptors = sp.getKeyDescriptors();
+ while (descriptors.hasNext()) {
+ KeyInfo keyInfo = ((KeyDescriptor) descriptors.next()).getKeyInfo();
+ for (int l = 0; keyInfo.lengthKeyName() > l; l++) {
+ try {
+
+ // First, try to match DN against metadata
+ try {
+ if (certificate.getSubjectX500Principal().getName(X500Principal.RFC2253).equals(
+ new X500Principal(keyInfo.itemKeyName(l).getKeyName()).getName(X500Principal.RFC2253))) {
+ log.debug("Matched against DN.");
+ return true;
+ }
+ } catch (IllegalArgumentException iae) {
+ // squelch this runtime exception, since
+ // this might be a valid case
+ }
+
+ // If that doesn't work, we try matching against
+ // some Subject Alt Names
+ try {
+ Collection altNames = certificate.getSubjectAlternativeNames();
+ if (altNames != null) {
+ for (Iterator nameIterator = altNames.iterator(); nameIterator.hasNext();) {
+ List altName = (List) nameIterator.next();
+ if (altName.get(0).equals(new Integer(2)) || altName.get(0).equals(new Integer(6))) { // 2 is
+ // DNS,
+ // 6 is
+ // URI
+ if (altName.get(1).equals(keyInfo.itemKeyName(l).getKeyName())) {
+ log.debug("Matched against SubjectAltName.");
+ return true;
+ }
+ }
+ }
+ }
+ } catch (CertificateParsingException e1) {
+ log
+ .error("Encountered an problem trying to extract Subject Alternate Name from supplied certificate: "
+ + e1);
+ }
+
+ // If that doesn't work, try to match using
+ // SSL-style hostname matching
+
+ //TODO stop relying on this class
+ if (ShibBrowserProfile.getHostNameFromDN(certificate.getSubjectX500Principal()).equals(
+ keyInfo.itemKeyName(l).getKeyName())) {
+ log.debug("Matched against hostname.");
+ return true;
+ }
+
+ } catch (XMLSecurityException e) {
+ log.error("Encountered an error reading federation metadata: " + e);
+ }
+ }
+ }
+ log.info("Supplied credential not found in metadata.");
+ return false;
+ }
+
protected class InvalidProviderCredentialException extends Exception {
public InvalidProviderCredentialException(String message) {
super(message);
}
}
-}
+}
\ No newline at end of file
package edu.internet2.middleware.shibboleth.idp.provider;
import java.io.IOException;
-import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Iterator;
-import java.util.List;
import javax.security.auth.x500.X500Principal;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
-import org.apache.xml.security.exceptions.XMLSecurityException;
-import org.apache.xml.security.keys.KeyInfo;
import org.opensaml.SAMLAssertion;
import org.opensaml.SAMLException;
import org.opensaml.SAMLRequest;
import edu.internet2.middleware.shibboleth.artifact.ArtifactMapper;
import edu.internet2.middleware.shibboleth.artifact.ArtifactMapping;
import edu.internet2.middleware.shibboleth.artifact.provider.MemoryArtifactMapper;
-import edu.internet2.middleware.shibboleth.common.ShibBrowserProfile;
import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationException;
import edu.internet2.middleware.shibboleth.idp.IdPProtocolHandler;
import edu.internet2.middleware.shibboleth.idp.IdPProtocolSupport;
import edu.internet2.middleware.shibboleth.idp.InvalidClientDataException;
import edu.internet2.middleware.shibboleth.metadata.EntityDescriptor;
-import edu.internet2.middleware.shibboleth.metadata.KeyDescriptor;
-import edu.internet2.middleware.shibboleth.metadata.SPSSODescriptor;
/**
* @author Walter Hoehn
public class SAMLv1_1ArtifactQueryHandler extends BaseServiceHandler implements IdPProtocolHandler {
// TODO figure out how to refactor this
- private ArtifactMapper artifactMapper;
+ private ArtifactMapper artifactMapper;
- private static Logger log = Logger.getLogger(SAMLv1_1ArtifactQueryHandler.class.getName());
+ private static Logger log = Logger.getLogger(SAMLv1_1ArtifactQueryHandler.class.getName());
SAMLv1_1ArtifactQueryHandler() throws ShibbolethConfigurationException {
}
/*
- * (non-Javadoc)
- *
* @see edu.internet2.middleware.shibboleth.idp.ProtocolHandler#processRequest(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse, edu.internet2.middleware.shibboleth.idp.ProtocolSupport)
*/
SAMLRequest samlRequest, IdPProtocolSupport support) throws SAMLException, InvalidClientDataException,
IOException, ServletException {
- // TODO make this jsut test for artifacts... or something
- /*
- * Iterator artifacts = samlRequest.getArtifacts(); if (artifacts.hasNext()) { artifacts = null; // get rid of
- * the iterator log.info("Recieved a request to dereference an assertion artifact."); }
- */
+ log.info("Recieved a request to dereference an assertion artifact.");
// TODO how about signatures on artifact dereferencing
// Pull credential from request
return samlResponse;
}
- private static boolean isValidCredential(EntityDescriptor provider, X509Certificate certificate) {
-
- SPSSODescriptor sp = provider.getSPSSODescriptor(org.opensaml.XML.SAML11_PROTOCOL_ENUM);
- if (sp == null) {
- log.info("Inappropriate metadata for provider.");
- return false;
- }
- // TODO figure out what to do about this role business here
- Iterator descriptors = sp.getKeyDescriptors();
- while (descriptors.hasNext()) {
- KeyInfo keyInfo = ((KeyDescriptor) descriptors.next()).getKeyInfo();
- for (int l = 0; keyInfo.lengthKeyName() > l; l++) {
- try {
-
- // First, try to match DN against metadata
- try {
- if (certificate.getSubjectX500Principal().getName(X500Principal.RFC2253).equals(
- new X500Principal(keyInfo.itemKeyName(l).getKeyName()).getName(X500Principal.RFC2253))) {
- log.debug("Matched against DN.");
- return true;
- }
- } catch (IllegalArgumentException iae) {
- // squelch this runtime exception, since
- // this might be a valid case
- }
-
- // If that doesn't work, we try matching against
- // some Subject Alt Names
- try {
- Collection altNames = certificate.getSubjectAlternativeNames();
- if (altNames != null) {
- for (Iterator nameIterator = altNames.iterator(); nameIterator.hasNext();) {
- List altName = (List) nameIterator.next();
- if (altName.get(0).equals(new Integer(2)) || altName.get(0).equals(new Integer(6))) { // 2 is
- // DNS,
- // 6 is
- // URI
- if (altName.get(1).equals(keyInfo.itemKeyName(l).getKeyName())) {
- log.debug("Matched against SubjectAltName.");
- return true;
- }
- }
- }
- }
- } catch (CertificateParsingException e1) {
- log
- .error("Encountered an problem trying to extract Subject Alternate Name from supplied certificate: "
- + e1);
- }
-
- // If that doesn't work, try to match using
- // SSL-style hostname matching
- if (ShibBrowserProfile.getHostNameFromDN(certificate.getSubjectX500Principal()).equals(
- keyInfo.itemKeyName(l).getKeyName())) {
- log.debug("Matched against hostname.");
- return true;
- }
-
- } catch (XMLSecurityException e) {
- log.error("Encountered an error reading federation metadata: " + e);
- }
- }
- }
- log.info("Supplied credential not found in metadata.");
- return false;
- }
-
}
\ No newline at end of file
import org.opensaml.SAMLSubject;
import sun.misc.BASE64Decoder;
+import edu.internet2.middleware.shibboleth.aa.AAException;
+import edu.internet2.middleware.shibboleth.common.InvalidNameIdentifierException;
+import edu.internet2.middleware.shibboleth.common.NameIdentifierMappingException;
import edu.internet2.middleware.shibboleth.common.RelyingParty;
import edu.internet2.middleware.shibboleth.common.ShibBrowserProfile;
import edu.internet2.middleware.shibboleth.idp.IdPProtocolHandler;
*/
public class SAMLv1_AttributeQueryHandler extends BaseServiceHandler implements IdPProtocolHandler {
- private static Logger log = Logger.getLogger(SAMLv1_AttributeQueryHandler.class.getName());
+ private static Logger log = Logger.getLogger(SAMLv1_AttributeQueryHandler.class.getName());
/*
* @see edu.internet2.middleware.shibboleth.idp.ProtocolHandler#getHandlerName()
return "SAML v1.1 Attribute Query";
}
- private String getEffectiveName(HttpServletRequest req, RelyingParty relyingParty)
+ private String getEffectiveName(HttpServletRequest req, RelyingParty relyingParty, IdPProtocolSupport support)
throws InvalidProviderCredentialException {
- // X500Principal credentialName = getCredentialName(req);
X509Certificate credential = getCredentialFromProvider(req);
if (credential == null || credential.getSubjectX500Principal().getName(X500Principal.RFC2253).equals("")) {
} else {
// See if we have metadata for this provider
- EntityDescriptor provider = protocolSupport.lookup(relyingParty.getProviderId());
+ EntityDescriptor provider = support.lookup(relyingParty.getProviderId());
if (provider == null) {
log.info("No metadata found for provider: (" + relyingParty.getProviderId() + ").");
log.info("Treating remote provider as unauthenticated.");
relyingParty = support.getServiceProviderMapper().getRelyingParty(attributeQuery.getResource());
try {
- effectiveName = getEffectiveName(request, relyingParty);
+ effectiveName = getEffectiveName(request, relyingParty, support);
} catch (InvalidProviderCredentialException ipc) {
- sendSAMLFailureResponse(response, samlRequest, new SAMLException(SAMLException.RESPONDER,
- "Invalid credentials for request."));
+ //TODO no, throw an exception
+ //sendSAMLFailureResponse(response, samlRequest, new SAMLException(SAMLException.RESPONDER,
+ // "Invalid credentials for request."));
return null;
}
}
}
// Map Subject to local principal
- Principal principal = support.getNameMapper().getPrincipal(attributeQuery.getSubject().getName(), relyingParty,
- relyingParty.getIdentityProvider());
- log.info("Request is for principal (" + principal.getName() + ").");
-
- SAMLAttribute[] attrs;
- Iterator requestedAttrsIterator = attributeQuery.getDesignators();
- if (requestedAttrsIterator.hasNext()) {
- log.info("Request designates specific attributes, resolving this set.");
- ArrayList requestedAttrs = new ArrayList();
- while (requestedAttrsIterator.hasNext()) {
- SAMLAttributeDesignator attribute = (SAMLAttributeDesignator) requestedAttrsIterator.next();
- try {
- log.debug("Designated attribute: (" + attribute.getName() + ")");
- requestedAttrs.add(new URI(attribute.getName()));
- } catch (URISyntaxException use) {
- log.error("Request designated an attribute name that does not conform to the required URI syntax ("
- + attribute.getName() + "). Ignoring this attribute");
+ Principal principal;
+ try {
+ principal = support.getNameMapper().getPrincipal(attributeQuery.getSubject().getName(), relyingParty,
+ relyingParty.getIdentityProvider());
+
+ log.info("Request is for principal (" + principal.getName() + ").");
+
+ SAMLAttribute[] attrs;
+ Iterator requestedAttrsIterator = attributeQuery.getDesignators();
+ if (requestedAttrsIterator.hasNext()) {
+ log.info("Request designates specific attributes, resolving this set.");
+ ArrayList requestedAttrs = new ArrayList();
+ while (requestedAttrsIterator.hasNext()) {
+ SAMLAttributeDesignator attribute = (SAMLAttributeDesignator) requestedAttrsIterator.next();
+ try {
+ log.debug("Designated attribute: (" + attribute.getName() + ")");
+ requestedAttrs.add(new URI(attribute.getName()));
+ } catch (URISyntaxException use) {
+ log
+ .error("Request designated an attribute name that does not conform to the required URI syntax ("
+ + attribute.getName() + "). Ignoring this attribute");
+ }
}
- }
-
- attrs = support.getReleaseAttributes(principal, effectiveName, null, (URI[]) requestedAttrs
- .toArray(new URI[0]));
- } else {
- log.info("Request does not designate specific attributes, resolving all available.");
- attrs = support.getReleaseAttributes(principal, effectiveName, null);
- }
-
- log.info("Found " + attrs.length + " attribute(s) for " + principal.getName());
- sendSAMLResponse(response, attrs, samlRequest, relyingParty, null);
- log.info("Successfully responded about " + principal.getName());
- if (effectiveName == null) {
- if (fromLegacyProvider(request)) {
- support.getTransactionLog().info(
- "Attribute assertion issued to anonymous legacy provider at (" + request.getRemoteAddr()
- + ") on behalf of principal (" + principal.getName() + ").");
- } else {
- support.getTransactionLog().info(
- "Attribute assertion issued to anonymous provider at (" + request.getRemoteAddr()
- + ") on behalf of principal (" + principal.getName() + ").");
- }
- } else {
- if (fromLegacyProvider(request)) {
- support.getTransactionLog().info(
- "Attribute assertion issued to legacy provider (" + effectiveName
- + ") on behalf of principal (" + principal.getName() + ").");
+ attrs = support.getReleaseAttributes(principal, effectiveName, null, (URI[]) requestedAttrs
+ .toArray(new URI[0]));
} else {
- support.getTransactionLog().info(
- "Attribute assertion issued to provider (" + effectiveName + ") on behalf of principal ("
- + principal.getName() + ").");
+ log.info("Request does not designate specific attributes, resolving all available.");
+ attrs = support.getReleaseAttributes(principal, effectiveName, null);
}
- }
-
- // TODO not NULL!!!
- return null;
-
- /*
- * throw new SAMLException(SAMLException.REQUESTER, "Identity Provider unable to respond to this SAML Request
- * type."); } catch (InvalidNameIdentifierException invalidNameE) { log.info("Could not associate the request
- * subject with a principal: " + invalidNameE); try { // TODO once again, ifgure out passThruErrors if (false) { //
- * if (relyingParty.passThruErrors()) { sendSAMLFailureResponse(response, samlRequest, new
- * SAMLException(Arrays.asList(invalidNameE .getSAMLErrorCodes()), "The supplied Subject was unrecognized.",
- * invalidNameE)); } else { sendSAMLFailureResponse(response, samlRequest, new
- * SAMLException(Arrays.asList(invalidNameE .getSAMLErrorCodes()), "The supplied Subject was unrecognized.")); }
- * return; } catch (Exception ee) { log.fatal("Could not construct a SAML error response: " + ee); throw new
- * ServletException("Identity Provider response failure."); }
- */
-
- }
- // TODO this should be renamed, since it is now only one type of response
- // that we can send
- public void sendSAMLResponse(HttpServletResponse resp, SAMLAttribute[] attrs, SAMLRequest samlRequest,
- RelyingParty relyingParty, SAMLException exception) throws IOException {
+ log.info("Found " + attrs.length + " attribute(s) for " + principal.getName());
- SAMLException ourSE = null;
- SAMLResponse samlResponse = null;
+ SAMLResponse samlResponse = null;
- try {
if (attrs == null || attrs.length == 0) {
// No attribute found
- samlResponse = new SAMLResponse(samlRequest.getId(), null, null, exception);
+ samlResponse = new SAMLResponse(samlRequest.getId(), null, null, null);
} else {
- SAMLAttributeQuery attributeQuery = (SAMLAttributeQuery) samlRequest.getQuery();
+ // SAMLAttributeQuery attributeQuery = (SAMLAttributeQuery) samlRequest.getQuery();
+ //TODO catch clonenotsupportedexception
+ //TODO no, put the use inside this blcok so we don't have to init
// Reference requested subject
- SAMLSubject rSubject = (SAMLSubject) attributeQuery.getSubject().clone();
-
- // Set appropriate audience
+ SAMLSubject rSubject = null;
+ try {
+ rSubject = (SAMLSubject) attributeQuery.getSubject().clone();
+ } catch (CloneNotSupportedException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
ArrayList audiences = new ArrayList();
if (relyingParty.getProviderId() != null) {
audiences.add(relyingParty.getProviderId());
SAMLAssertion sAssertion = new SAMLAssertion(relyingParty.getIdentityProvider().getProviderId(), now,
then, Collections.singleton(condition), null, Collections.singleton(statement));
- samlResponse = new SAMLResponse(samlRequest.getId(), null, Collections.singleton(sAssertion), exception);
- ProtocolSupport.addSignatures(samlResponse, relyingParty, protocolSupport.lookup(relyingParty
+ samlResponse = new SAMLResponse(samlRequest.getId(), null, Collections.singleton(sAssertion), null);
+ IdPProtocolSupport.addSignatures(samlResponse, relyingParty, support.lookup(relyingParty
.getProviderId()), false);
}
- } catch (SAMLException se) {
- ourSE = se;
- } catch (CloneNotSupportedException ex) {
- ourSE = new SAMLException(SAMLException.RESPONDER, ex);
-
- } finally {
if (log.isDebugEnabled()) { // This takes some processing, so only do it if we need to
try {
}
}
- try {
- binding.respond(resp, samlResponse, ourSE);
- } catch (SAMLException e) {
- log.error("Caught exception while responding to requester: " + e.getMessage());
- resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error while responding.");
+ log.info("Successfully responded about " + principal.getName());
+
+ if (effectiveName == null) {
+ if (fromLegacyProvider(request)) {
+ support.getTransactionLog().info(
+ "Attribute assertion issued to anonymous legacy provider at (" + request.getRemoteAddr()
+ + ") on behalf of principal (" + principal.getName() + ").");
+ } else {
+ support.getTransactionLog().info(
+ "Attribute assertion issued to anonymous provider at (" + request.getRemoteAddr()
+ + ") on behalf of principal (" + principal.getName() + ").");
+ }
+ } else {
+ if (fromLegacyProvider(request)) {
+ support.getTransactionLog().info(
+ "Attribute assertion issued to legacy provider (" + effectiveName
+ + ") on behalf of principal (" + principal.getName() + ").");
+ } else {
+ support.getTransactionLog().info(
+ "Attribute assertion issued to provider (" + effectiveName + ") on behalf of principal ("
+ + principal.getName() + ").");
+ }
}
+ } catch (InvalidNameIdentifierException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (NameIdentifierMappingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (AAException e) {
+ //TODO get rid of AAException, I think
+ // TODO Auto-generated catch block
+ e.printStackTrace();
}
+
+ // TODO not NULL!!!
+ return null;
+
+ /*
+ * throw new SAMLException(SAMLException.REQUESTER, "Identity Provider unable to respond to this SAML Request
+ * type."); } catch (InvalidNameIdentifierException invalidNameE) { log.info("Could not associate the request
+ * subject with a principal: " + invalidNameE); try { // TODO once again, ifgure out passThruErrors if (false) { //
+ * if (relyingParty.passThruErrors()) { sendSAMLFailureResponse(response, samlRequest, new
+ * SAMLException(Arrays.asList(invalidNameE .getSAMLErrorCodes()), "The supplied Subject was unrecognized.",
+ * invalidNameE)); } else { sendSAMLFailureResponse(response, samlRequest, new
+ * SAMLException(Arrays.asList(invalidNameE .getSAMLErrorCodes()), "The supplied Subject was unrecognized.")); }
+ * return; } catch (Exception ee) { log.fatal("Could not construct a SAML error response: " + ee); throw new
+ * ServletException("Identity Provider response failure."); }
+ */
+
}
private static boolean fromLegacyProvider(HttpServletRequest request) {
return true;
}
-}
+}
\ No newline at end of file