urn\:mace\:shibboleth\:2.0\:idp\:services = edu.internet2.middleware.shibboleth.idp.config.service.IdPServicesNamespaceHandler
-urn\:mace\:shibboleth\:2.0\:idp\:profiles = edu.internet2.middleware.shibboleth.idp.config.profile.IdPProfileHandlerNamespaceHandler
\ No newline at end of file
+urn\:mace\:shibboleth\:2.0\:idp\:profile = edu.internet2.middleware.shibboleth.idp.config.profile.ProfileHandlerNamespaceHandler
\ No newline at end of file
urn\:mace\:shibboleth\:2.0\:idp\:services = schema/shibboleth-2.0-idp-service.xsd
-urn\:mace\:shibboleth\:2.0\:idp\:profiles = schema/shibboleth-2.0-idp-profile.xsd
\ No newline at end of file
+urn\:mace\:shibboleth\:2.0\:idp\:profile = schema/shibboleth-2.0-idp-profile.xsd
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="urn:mace:shibboleth:2.0:idp:profiles" xmlns="http://www.w3.org/2001/XMLSchema"
- xmlns:ph="urn:mace:shibboleth:2.0:profile-handler" xmlns:idpph="urn:mace:shibboleth:2.0:idp:profiles"
+<xsd:schema targetNamespace="urn:mace:shibboleth:2.0:idp:profile" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns="urn:mace:shibboleth:2.0:idp:profile" xmlns:service="urn:mace:shibboleth:2.0:services"
elementFormDefault="qualified">
- <import namespace="urn:mace:shibboleth:2.0:profile-handler"
- schemaLocation="classpath:/schema/shibboleth-2.0-profile-handler.xsd" />
+ <xsd:include schemaLocation="classpath:/schema/shibboleth-2.0-profile-handler.xsd" />
- <annotation>
- <documentation>
+ <xsd:import namespace="urn:mace:shibboleth:2.0:services"
+ schemaLocation="classpath:/schema/shibboleth-2.0-services.xsd" />
+
+ <xsd:annotation>
+ <xsd:documentation>
This schema specifies the configuration options for Shibboleth IdP profile handlers.
- </documentation>
- </annotation>
-
- <complexType name="Status">
- <annotation>
- <documentation>Basic handler that returns a general status of the IdP.</documentation>
- </annotation>
- <complexContent>
- <extension base="ph:RequestURIMappedProfileHandlerType" />
- </complexContent>
- </complexType>
-
- <complexType name="SAML2SSO">
- <annotation>
- <documentation>Configuration type for SAML 2 Attribute Query profile handlers.</documentation>
- </annotation>
- <complexContent>
- <extension base="idpph:SAML2ProfileHandler">
- <attribute name="authenticationManagerPath" type="string" default="/AuthnManager">
- <annotation>
- <documentation>
- The context relative path to the authentication manager used by this profile handler. This should
- match the URL pattern given in the web.xml
- </documentation>
- </annotation>
- </attribute>
- <attribute name="decodingBinding" type="anyURI" default=" urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
- <annotation>
- <documentation>
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType name="IdPProfileHandlerManager">
+ <xsd:annotation>
+ <xsd:documentation>Definition for the basic Shibboleth profile handler manager service.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexContent>
+ <xsd:extension base="service:ReloadableServiceType" />
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="ProfileHandlerGroup">
+ <xsd:annotation>
+ <xsd:documentation>Root of a profile handler configuration file.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="ErrorHandler" type="ErrorHandlerType">
+
+ </xsd:element>
+ <xsd:element name="ProfileHandler" type="RequestHandlerType" minOccurs="0"
+ maxOccurs="unbounded">
+
+ </xsd:element>
+ <xsd:element name="AuthenticationHandler" type="AuthenticationHandlerType" minOccurs="0"
+ maxOccurs="unbounded">
+
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="Status">
+ <xsd:annotation>
+ <xsd:documentation>Basic handler that returns a general status of the IdP.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexContent>
+ <xsd:extension base="RequestURIMappedProfileHandlerType" />
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="SAML2SSO">
+ <xsd:annotation>
+ <xsd:documentation>Configuration type for SAML 2 Attribute Query profile handlers.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexContent>
+ <xsd:extension base="SAML2ProfileHandler">
+ <xsd:attribute name="authenticationManagerPath" type="xsd:string" default="/AuthnManager">
+ <xsd:annotation>
+ <xsd:documentation>
+ The context relative path to the authentication manager used by this profile handler. This
+ should match the URL pattern given in the web.xml
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="decodingBinding" type="xsd:anyURI"
+ default="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
+ <xsd:annotation>
+ <xsd:documentation>
The URI of the binding used when decoding requests from relying parties.
- </documentation>
- </annotation>
- </attribute>
- <attribute name="encodingBinding" type="anyURI" default=" urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
- <annotation>
- <documentation>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="encodingBinding" type="xsd:anyURI"
+ default="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
+ <xsd:annotation>
+ <xsd:documentation>
The URI of the binding used when encoding responses to relying parties.
- </documentation>
- </annotation>
- </attribute>
- </extension>
- </complexContent>
- </complexType>
-
- <complexType name="SAML2AttributeQuery">
- <annotation>
- <documentation>Configuration type for SAML 2 Attribute Query profile handlers.</documentation>
- </annotation>
- <complexContent>
- <extension base="idpph:SAML2ProfileHandler" />
- </complexContent>
- </complexType>
-
- <complexType name="SAML2ProfileHandler" abstract="true">
- <annotation>
- <documentation>Base type for SAML 2 profile handlers.</documentation>
- </annotation>
- <complexContent>
- <extension base="idpph:SAMLProfileHandler" />
- </complexContent>
- </complexType>
-
- <complexType name="SAML1AttributeQuery">
- <annotation>
- <documentation>Configuration type for SAML 1 Attribute Query profile handlers.</documentation>
- </annotation>
- <complexContent>
- <extension base="idpph:SAML1ProfileHandler" />
- </complexContent>
- </complexType>
-
- <complexType name="SAML1ProfileHandler" abstract="true">
- <annotation>
- <documentation>Base type for SAML 1 profile handlers.</documentation>
- </annotation>
- <complexContent>
- <extension base="idpph:SAMLProfileHandler" />
- </complexContent>
- </complexType>
-
- <complexType name="SAMLProfileHandler" abstract="true">
- <annotation>
- <documentation>Base type for Shibboleth IdP SAML profile handlers.</documentation>
- </annotation>
- <complexContent>
- <extension base="idpph:IdPProfileHandlerType">
- <attribute name="messageDecoderFactoryId" type="string" default="shibboleth.MessageDecoderFactory">
- <annotation>
- <documentation>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="securityPolicyFactoryId" type="xsd:string"
+ default="shibboleth.SAML2SSOMessageSecurityPolicyFactory">
+ <xsd:annotation>
+ <xsd:documentation>
+ The component ID of the security policy factory to use with the profile handler.
+
+ This setting should not be changed from its default unless the deployer fully understands
+ the inter-relationship between IdP components.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="SAML2AttributeQuery">
+ <xsd:annotation>
+ <xsd:documentation>Configuration type for SAML 2 Attribute Query profile handlers.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexContent>
+ <xsd:extension base="SAML2ProfileHandler">
+ <xsd:attribute name="securityPolicyFactoryId" type="xsd:string"
+ default="shibboleth.SAML2AttributeQueryMessageSecurityPolicyFactory">
+ <xsd:annotation>
+ <xsd:documentation>
+ The component ID of the security policy factory to use with the profile handler.
+
+ This setting should not be changed from its default unless the deployer fully understands
+ the inter-relationship between IdP components.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="SAML2ProfileHandler" abstract="true">
+ <xsd:annotation>
+ <xsd:documentation>Base type for SAML 2 profile handlers.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexContent>
+ <xsd:extension base="SAMLProfileHandler" />
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="SAML1AttributeQuery">
+ <xsd:annotation>
+ <xsd:documentation>Configuration type for SAML 1 Attribute Query profile handlers.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexContent>
+ <xsd:extension base="SAML1ProfileHandler" />
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="SAML1ProfileHandler" abstract="true">
+ <xsd:annotation>
+ <xsd:documentation>Base type for SAML 1 profile handlers.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexContent>
+ <xsd:extension base="SAMLProfileHandler" />
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="SAMLProfileHandler" abstract="true">
+ <xsd:annotation>
+ <xsd:documentation>Base type for Shibboleth IdP SAML profile handlers.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexContent>
+ <xsd:extension base="IdPProfileHandlerType">
+ <xsd:attribute name="messageDecoderFactoryId" type="xsd:string"
+ default="shibboleth.MessageDecoderFactory">
+ <xsd:annotation>
+ <xsd:documentation>
The component ID of the message decoder to use with the profile handler.
This setting should not be changed from its default unless the deployer fully understands
the inter-relationship between IdP components.
- </documentation>
- </annotation>
- </attribute>
- <attribute name="messageEncoderFactoryId" type="string" default="shibboleth.MessageEncoderFactory">
- <annotation>
- <documentation>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="messageEncoderFactoryId" type="xsd:string"
+ default="shibboleth.MessageEncoderFactory">
+ <xsd:annotation>
+ <xsd:documentation>
The component ID of the message encoder to use with the profile handler.
This setting should not be changed from its default unless the deployer fully understands
the inter-relationship between IdP components.
- </documentation>
- </annotation>
- </attribute>
- <attribute name="idGeneratorId" type="string" default="shibboleth.IdGenerator">
- <annotation>
- <documentation>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="idGeneratorId" type="xsd:string" default="shibboleth.IdGenerator">
+ <xsd:annotation>
+ <xsd:documentation>
The component ID of a generator used to generated things like response and assertion IDs.
This setting should not be changed from its default unless the deployer fully understands
the inter-relationship between IdP components.
- </documentation>
- </annotation>
- </attribute>
- </extension>
- </complexContent>
- </complexType>
-
- <complexType name="IdPProfileHandlerType" abstract="true">
- <annotation>
- <documentation>Base type for Shibboleth IdP profile handlers.</documentation>
- </annotation>
- <complexContent>
- <extension base="ph:ShibbolethProfileHandlerType" />
- </complexContent>
- </complexType>
-
-</schema>
\ No newline at end of file
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="IdPProfileHandlerType" abstract="true">
+ <xsd:annotation>
+ <xsd:documentation>Base type for IdP profile handlers.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexContent>
+ <xsd:extension base="ShibbolethProfileHandlerType" />
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="AuthenticationHandlerType" abstract="true">
+
+ </xsd:complexType>
+
+</xsd:schema>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
-<ProfileHandlerGroup xmlns="urn:mace:shibboleth:2.0:profile-handler"
- xmlns:idpProfile="urn:mace:shibboleth:2.0:idp:profiles"
+<ProfileHandlerGroup xmlns="urn:mace:shibboleth:2.0:idp:profile"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="urn:mace:shibboleth:2.0:profile-handler classpath:/schema/shibboleth-2.0-profile-handler.xsd
- urn:mace:shibboleth:2.0:idp:profiles classpath:/schema/shibboleth-2.0-idp-profile.xsd">
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:idp:profile classpath:/schema/shibboleth-2.0-idp-profile.xsd">
<ErrorHandler xsi:type="JSPErrorHandler" jspPagePath="/error.jsp" />
import org.opensaml.xml.util.DatatypeHelper;
import org.opensaml.xml.util.Pair;
-import edu.internet2.middleware.shibboleth.common.profile.ProfileHandlerManager;
import edu.internet2.middleware.shibboleth.common.session.SessionManager;
+import edu.internet2.middleware.shibboleth.idp.profile.IdPProfileHandlerManager;
import edu.internet2.middleware.shibboleth.idp.session.AuthenticationMethodInformation;
import edu.internet2.middleware.shibboleth.idp.session.ServiceInformation;
import edu.internet2.middleware.shibboleth.idp.session.Session;
*/
public class AuthenticationEngine extends HttpServlet {
+ /** Serial version UID. */
+ private static final long serialVersionUID = 8494202791991613148L;
+
/** Class logger. */
private static final Logger LOG = Logger.getLogger(AuthenticationEngine.class);
*
* @return manager used to retrieve handlers for requests
*/
- public ProfileHandlerManager getProfileHandlerManager() {
- return (ProfileHandlerManager) getServletContext().getAttribute("handlerManager");
+ public IdPProfileHandlerManager getProfileHandlerManager() {
+ return (IdPProfileHandlerManager) getServletContext().getAttribute("handlerManager");
}
/**
}
/**
- * Gets the authentication handler manager used by this engine.
- *
- * @return authentication handler manager used by this engine
- */
- public AuthenticationHandlerManager getAuthenticationHandlerManager() {
- return (AuthenticationHandlerManager) getServletContext().getAttribute("authenticationHandlerManager");
- }
-
- /**
* Returns control back to the authentication engine.
*
* @param httpRequest current http request
if (LOG.isDebugEnabled()) {
LOG.debug("Selecting appropriate authentication method for request.");
}
- Pair<String, AuthenticationHandler> handler = getAuthenticationHandlerManager().getAuthenticationHandler(
+ Pair<String, AuthenticationHandler> handler = getProfileHandlerManager().getAuthenticationHandler(
loginContext);
if (handler == null) {
package edu.internet2.middleware.shibboleth.idp.authn;
+import java.util.List;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public static final String AUTHENTICATION_ERROR_KEY = "authnError";
/**
+ * Gets the list of authentication methods this handler supports.
+ *
+ * @return authentication methods this handler supports
+ */
+ public List<String> getSupportedAuthenticationMethods();
+
+ /**
* Gets the length of time, in milliseconds, after which a user authenticated by this handler should be
* re-authenticated.
*
+++ /dev/null
-/*
- * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.idp.authn;
-
-import java.util.Map;
-
-import org.opensaml.xml.util.Pair;
-
-/**
- * Manager for registering and retrieving authentication handlers.
- */
-public interface AuthenticationHandlerManager {
-
- /**
- * Gets the registered authentication handlers.
- *
- * @return registered authentication handlers
- */
- public Map<String, AuthenticationHandler> getAuthenticationHandlers();
-
- /**
- * Gets the authentication handler appropriate for the given loging context. The mechanism used to determine the
- * "appropriate" handler is implementation specific.
- *
- * @param loginContext current login context
- *
- * @return authentication method URI and handler appropriate for given login context
- */
- public Pair<String, AuthenticationHandler> getAuthenticationHandler(LoginContext loginContext);
-}
\ No newline at end of file
package edu.internet2.middleware.shibboleth.idp.authn.provider;
-import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.log4j.Logger;
-
import edu.internet2.middleware.shibboleth.idp.authn.AuthenticationHandler;
-import edu.internet2.middleware.shibboleth.idp.authn.LoginContext;
/**
* Base class for authentication handlers.
*/
public abstract class AbstractAuthenticationHandler implements AuthenticationHandler {
-
- /** Class logger. */
- private final Logger log = Logger.getLogger(AbstractAuthenticationHandler.class);
+
+ /** Authentication methods this handler supports. */
+ private ArrayList<String> supportedAuthenticationMethods;
/** Length of time, in milliseconds, after which a user should be re-authenticated. */
private long authenticationDuration;
/** Whether this handler supports passive authentication. */
private boolean supportsPassive;
+
+ /** Constructor. */
+ protected AbstractAuthenticationHandler(){
+ supportedAuthenticationMethods = new ArrayList<String>();
+ }
+
+ /** {@inheritDoc} */
+ public List<String> getSupportedAuthenticationMethods() {
+ return supportedAuthenticationMethods;
+ }
/** {@inheritDoc} */
public long getAuthenticationDuration() {
--- /dev/null
+/*
+ * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.internet2.middleware.shibboleth.idp.config.profile;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+
+import edu.internet2.middleware.shibboleth.common.config.service.AbstractReloadableServiceBeanDefinitionParser;
+import edu.internet2.middleware.shibboleth.idp.profile.IdPProfileHandlerManager;
+
+/**
+ * Spring bean definition parser for {@link IdPProfileHandlerManager}s.
+ */
+public class IdPProfileHandlerManagerBeanDefinitionParser extends AbstractReloadableServiceBeanDefinitionParser {
+
+ /** Schema type. */
+ public static final QName SCHEMA_TYPE = new QName(ProfileHandlerNamespaceHandler.NAMESPACE, "IdPProfileHandlerManager");
+
+ /** {@inheritDoc} */
+ protected Class getBeanClass(Element arg0) {
+ return IdPProfileHandlerManager.class;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.internet2.middleware.shibboleth.idp.config.profile;
+
+import java.util.List;
+
+import edu.internet2.middleware.shibboleth.common.profile.AbstractErrorHandler;
+import edu.internet2.middleware.shibboleth.common.profile.ProfileHandler;
+import edu.internet2.middleware.shibboleth.idp.authn.AuthenticationHandler;
+
+/**
+ * Container for a single profile handler group configuration.
+ */
+public class ProfileHandlerGroup {
+
+ /** Error handler for the group. */
+ private AbstractErrorHandler errorHandler;
+
+ /** List of profile handlers for the group. */
+ private List<ProfileHandler> profileHandlers;
+
+ /** List of authentication handlers for the group. */
+ private List<AuthenticationHandler> authenticationHandlers;
+
+ /**
+ * Gets the error handler for the group.
+ *
+ * @return error handler for the group
+ */
+ public AbstractErrorHandler getErrorHandler() {
+ return errorHandler;
+ }
+
+ /**
+ * Sets the error handler for the group.
+ *
+ * @param handler error handler for the group
+ */
+ public void setErrorHandler(AbstractErrorHandler handler) {
+ errorHandler = handler;
+ }
+
+ /**
+ * Gets the profile handlers for the group.
+ *
+ * @return profile handlers for the group
+ */
+ public List<ProfileHandler> getProfileHandlers() {
+ return profileHandlers;
+ }
+
+ /**
+ * Sets the profile handlers for the group.
+ *
+ * @param handlers profile handlers for the group
+ */
+ public void setProfileHandlers(List<ProfileHandler> handlers) {
+ profileHandlers = handlers;
+ }
+
+ /**
+ * Gets the authentication handlers for the group.
+ *
+ * @return authentication handlers for the group
+ */
+ public List<AuthenticationHandler> getAuthenticationHandlers() {
+ return authenticationHandlers;
+ }
+
+ /**
+ * Sets the authentication handlers for the group.
+ *
+ * @param handlers authentication handlers for the group
+ */
+ public void setAuthenticationHandlers(List<AuthenticationHandler> handlers) {
+ authenticationHandlers = handlers;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.internet2.middleware.shibboleth.idp.config.profile;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.opensaml.xml.util.XMLHelper;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+import edu.internet2.middleware.shibboleth.common.config.SpringConfigurationUtils;
+
+/**
+ * Spring bean definition parser for profile handler root element.
+ */
+public class ProfileHandlerGroupBeanDefinitionParser extends AbstractBeanDefinitionParser {
+
+ /** Schema type name. */
+ public static final QName SCHEMA_TYPE = new QName(ProfileHandlerNamespaceHandler.NAMESPACE, "ProfileHandlerGroup");
+
+ /** {@inheritDoc} */
+ protected AbstractBeanDefinition parseInternal(Element config, ParserContext context) {
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ProfileHandlerGroup.class);
+
+ Map<QName, List<Element>> configChildren = XMLHelper.getChildElements(config);
+ List<Element> children;
+
+ children = configChildren.get(new QName(ProfileHandlerNamespaceHandler.NAMESPACE, "ErrorHandler"));
+ builder.addPropertyValue("errorHandler", SpringConfigurationUtils.parseCustomElement(children.get(0), context));
+
+ children = configChildren.get(new QName(ProfileHandlerNamespaceHandler.NAMESPACE, "ProfileHandler"));
+ builder.addPropertyValue("profileHandlers", SpringConfigurationUtils.parseCustomElements(children, context));
+
+ children = configChildren.get(new QName(ProfileHandlerNamespaceHandler.NAMESPACE, "AuthenticationHandler"));
+ builder.addPropertyValue("authenticationHandlers", SpringConfigurationUtils.parseCustomElements(children,
+ context));
+
+ return builder.getBeanDefinition();
+ }
+
+ /** {@inheritDoc} */
+ protected boolean shouldGenerateId() {
+ return true;
+ }
+}
\ No newline at end of file
package edu.internet2.middleware.shibboleth.idp.config.profile;
+import javax.xml.namespace.QName;
+
import edu.internet2.middleware.shibboleth.common.config.BaseSpringNamespaceHandler;
+import edu.internet2.middleware.shibboleth.common.config.profile.JSPErrorHandlerBeanDefinitionParser;
+import edu.internet2.middleware.shibboleth.common.config.profile.VelocityErrorHandlerBeanDefinitionParser;
/**
- * Spring namespace handler for IdP profile handlers.
+ * Spring namespace handler for profile handler configurations.
*/
-public class IdPProfileHandlerNamespaceHandler extends BaseSpringNamespaceHandler {
+public class ProfileHandlerNamespaceHandler extends BaseSpringNamespaceHandler {
- /** IdP profile handler namespace URI. */
- public static final String NAMESPACE = "urn:mace:shibboleth:2.0:idp:profiles";
+ /** Namespace URI. */
+ public static final String NAMESPACE = "urn:mace:shibboleth:2.0:idp:profile";
/** {@inheritDoc} */
public void init() {
+ registerBeanDefinitionParser(IdPProfileHandlerManagerBeanDefinitionParser.SCHEMA_TYPE,
+ new IdPProfileHandlerManagerBeanDefinitionParser());
+
+ registerBeanDefinitionParser(ProfileHandlerGroupBeanDefinitionParser.SCHEMA_TYPE,
+ new ProfileHandlerGroupBeanDefinitionParser());
+
+ registerBeanDefinitionParser(new QName(NAMESPACE, JSPErrorHandlerBeanDefinitionParser.ELEMENT_NAME),
+ new JSPErrorHandlerBeanDefinitionParser());
+
+ registerBeanDefinitionParser(new QName(NAMESPACE, VelocityErrorHandlerBeanDefinitionParser.ELEMENT_NAME),
+ new VelocityErrorHandlerBeanDefinitionParser());
+
registerBeanDefinitionParser(StatusHandlerBeanDefinitionParser.SCHEMA_TYPE,
new StatusHandlerBeanDefinitionParser());
import javax.xml.namespace.QName;
+import org.opensaml.xml.util.DatatypeHelper;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.w3c.dom.Element;
import edu.internet2.middleware.shibboleth.idp.profile.saml2.AttributeQueryProfileHandler;
AbstractSAML2ProfileHandlerBeanDefinitionParser {
/** Schema type. */
- public static final QName SCHEMA_TYPE = new QName(IdPProfileHandlerNamespaceHandler.NAMESPACE,
+ public static final QName SCHEMA_TYPE = new QName(ProfileHandlerNamespaceHandler.NAMESPACE,
"SAML2AttributeQuery");
/** {@inheritDoc} */
protected Class getBeanClass(Element arg0) {
return AttributeQueryProfileHandler.class;
}
+
+ /** {@inheritDoc} */
+ protected void doParse(Element config, BeanDefinitionBuilder builder) {
+ super.doParse(config, builder);
+
+ builder.addPropertyReference("securityPolicyFactory", DatatypeHelper.safeTrimOrNullString(config
+ .getAttributeNS(null, "securityPolicyFactoryId")));
+ }
}
\ No newline at end of file
public class SAML2SSOProfileHandlerBeanDefinitionParser extends AbstractSAML2ProfileHandlerBeanDefinitionParser {
/** Schema type. */
- public static final QName SCHEMA_TYPE = new QName(IdPProfileHandlerNamespaceHandler.NAMESPACE, "SAML2SSO");
+ public static final QName SCHEMA_TYPE = new QName(ProfileHandlerNamespaceHandler.NAMESPACE, "SAML2SSO");
/** {@inheritDoc} */
protected Class getBeanClass(Element arg0) {
builder.addConstructorArg(DatatypeHelper.safeTrimOrNullString(config.getAttributeNS(null, "decodingBinding")));
builder.addConstructorArg(DatatypeHelper.safeTrimOrNullString(config.getAttributeNS(null, "encodingBinding")));
+
+ builder.addPropertyReference("securityPolicyFactory", DatatypeHelper.safeTrimOrNullString(config
+ .getAttributeNS(null, "securityPolicyFactoryId")));
}
}
\ No newline at end of file
* Spring bean definition parser for {@link StatusProfileHandler}s.
*/
public class StatusHandlerBeanDefinitionParser extends AbstractRequestURIMappedProfileHandlerBeanDefinitionParser {
-
+
/** Schema type. */
- public static final QName SCHEMA_TYPE = new QName(IdPProfileHandlerNamespaceHandler.NAMESPACE, "Status");
+ public static final QName SCHEMA_TYPE = new QName(ProfileHandlerNamespaceHandler.NAMESPACE, "Status");
/** {@inheritDoc} */
protected Class getBeanClass(Element arg0) {
--- /dev/null
+/*
+ * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.internet2.middleware.shibboleth.idp.profile;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+import java.util.concurrent.locks.Lock;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.log4j.Logger;
+import org.opensaml.util.resource.Resource;
+import org.opensaml.util.resource.ResourceException;
+import org.opensaml.xml.util.Pair;
+import org.springframework.context.ApplicationContext;
+
+import edu.internet2.middleware.shibboleth.common.config.BaseReloadableService;
+import edu.internet2.middleware.shibboleth.common.profile.AbstractErrorHandler;
+import edu.internet2.middleware.shibboleth.common.profile.ProfileHandler;
+import edu.internet2.middleware.shibboleth.common.profile.ProfileHandlerManager;
+import edu.internet2.middleware.shibboleth.common.profile.provider.AbstractRequestURIMappedProfileHandler;
+import edu.internet2.middleware.shibboleth.idp.authn.AuthenticationHandler;
+import edu.internet2.middleware.shibboleth.idp.authn.LoginContext;
+
+/**
+ * Implementation of a {@link ProfileHandlerManager} that maps the request path, without the servlet context, to a
+ * profile handler and adds support for authentication handlers.
+ */
+public class IdPProfileHandlerManager extends BaseReloadableService implements ProfileHandlerManager {
+
+ /** URI of the default authentication method. */
+ public static final String DEFAULT_AUTHEN_METHOD_URI = "urn:mace:shibboleth:2.0:idp:authentication:method:default";
+
+ /** Class logger. */
+ private final Logger log = Logger.getLogger(IdPProfileHandlerManager.class);
+
+ /** Handler used for errors. */
+ private AbstractErrorHandler errorHandler;
+
+ /** Map of request paths to profile handlers. */
+ private Map<String, AbstractRequestURIMappedProfileHandler> profileHandlers;
+
+ /** Map of authentication methods to authentication handlers. */
+ private Map<String, AuthenticationHandler> authenticationHandlers;
+
+ /**
+ * Constructor. Configuration resources are not monitored for changes.
+ *
+ * @param configurations configuration resources for this service
+ */
+ public IdPProfileHandlerManager(List<Resource> configurations) {
+ super(configurations);
+ profileHandlers = new HashMap<String, AbstractRequestURIMappedProfileHandler>();
+ authenticationHandlers = new HashMap<String, AuthenticationHandler>();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param timer timer resource polling tasks are scheduled with
+ * @param configurations configuration resources for this service
+ * @param pollingFrequency the frequency, in milliseconds, to poll the policy resources for changes, must be greater
+ * than zero
+ */
+ public IdPProfileHandlerManager(List<Resource> configurations, Timer timer, long pollingFrequency) {
+ super(timer, configurations, pollingFrequency);
+ profileHandlers = new HashMap<String, AbstractRequestURIMappedProfileHandler>();
+ authenticationHandlers = new HashMap<String, AuthenticationHandler>();
+ }
+
+ /** {@inheritDoc} */
+ public AbstractErrorHandler getErrorHandler() {
+ return errorHandler;
+ }
+
+ /**
+ * Sets the error handler.
+ *
+ * @param handler error handler
+ */
+ public void setErrorHandler(AbstractErrorHandler handler) {
+ if (handler == null) {
+ throw new IllegalArgumentException("Error handler may not be null");
+ }
+ errorHandler = handler;
+ }
+
+ /** {@inheritDoc} */
+ public ProfileHandler getProfileHandler(ServletRequest request) {
+ ProfileHandler handler;
+
+ String requestPath = ((HttpServletRequest) request).getPathInfo();
+ if (log.isDebugEnabled()) {
+ log.debug("Looking up profile handler for request path: " + requestPath);
+ }
+ Lock readLock = getReadWriteLock().readLock();
+ readLock.lock();
+ handler = profileHandlers.get(requestPath);
+ readLock.unlock();
+
+ if (handler != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Located profile handler of the following type for request path " + requestPath + ": "
+ + handler.getClass().getName());
+ }
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("No profile handler registered for request path " + requestPath);
+ }
+ }
+ return handler;
+ }
+
+ /**
+ * Gets the registered profile handlers.
+ *
+ * @return registered profile handlers
+ */
+ public Map<String, AbstractRequestURIMappedProfileHandler> getProfileHandlers() {
+ return profileHandlers;
+ }
+
+ /**
+ * Gets the authentication handler appropriate for the given loging context. The mechanism used to determine the
+ * "appropriate" handler is implementation specific.
+ *
+ * @param loginContext current login context
+ *
+ * @return authentication method URI and handler appropriate for given login context
+ */
+ public Pair<String, AuthenticationHandler> getAuthenticationHandler(LoginContext loginContext) {
+ List<String> requestedMethods = loginContext.getRequestedAuthenticationMethods();
+ if (requestedMethods != null) {
+ AuthenticationHandler candidateHandler;
+ for (String requestedMethod : requestedMethods) {
+ candidateHandler = authenticationHandlers.get(requestedMethod);
+ if (candidateHandler != null) {
+ if (loginContext.getPassiveAuth() && candidateHandler.supportsPassive()) {
+ return new Pair<String, AuthenticationHandler>(requestedMethod, candidateHandler);
+ }
+ }
+ }
+ }
+
+ Pair<String, AuthenticationHandler> authenticationHandler = new Pair<String, AuthenticationHandler>(
+ DEFAULT_AUTHEN_METHOD_URI, authenticationHandlers.get(DEFAULT_AUTHEN_METHOD_URI));
+ return authenticationHandler;
+ }
+
+ /**
+ * Gets the registered authentication handlers.
+ *
+ * @return registered authentication handlers
+ */
+ public Map<String, AuthenticationHandler> getAuthenticationHandlers() {
+ return authenticationHandlers;
+ }
+
+ /** {@inheritDoc} */
+ protected void newContextCreated(ApplicationContext newServiceContext) throws ResourceException {
+ if (log.isDebugEnabled()) {
+ log.debug("Loading new configuration into service");
+ }
+ String[] errorBeanNames = newServiceContext.getBeanNamesForType(AbstractErrorHandler.class);
+ String[] profileBeanNames = newServiceContext.getBeanNamesForType(AbstractRequestURIMappedProfileHandler.class);
+ String[] authnBeanNames = newServiceContext.getBeanNamesForType(AuthenticationHandler.class);
+
+ Lock writeLock = getReadWriteLock().writeLock();
+ writeLock.lock();
+
+ errorHandler = (AbstractErrorHandler) newServiceContext.getBean(errorBeanNames[0]);
+ if (log.isDebugEnabled()) {
+ log.debug("Loaded new error handler of type: " + errorHandler.getClass().getName());
+ }
+
+ profileHandlers.clear();
+ if (log.isDebugEnabled()) {
+ log.debug(profileBeanNames.length + " profile handlers loaded");
+ }
+ AbstractRequestURIMappedProfileHandler profileHandler;
+ for (String profileBeanName : profileBeanNames) {
+ profileHandler = (AbstractRequestURIMappedProfileHandler) newServiceContext.getBean(profileBeanName);
+ for (String requestPath : profileHandler.getRequestPaths()) {
+ profileHandlers.put(requestPath, profileHandler);
+ if (log.isDebugEnabled()) {
+ log.debug("Request path " + requestPath + " mapped to profile handler of type: "
+ + profileHandler.getClass().getName());
+ }
+ }
+ }
+
+ authenticationHandlers.clear();
+ if (log.isDebugEnabled()) {
+ log.debug(authnBeanNames.length + " authentication handlers loaded");
+ }
+ AuthenticationHandler authnHandler;
+ for (String authnBeanName : authnBeanNames) {
+ authnHandler = (AuthenticationHandler) newServiceContext.getBean(authnBeanName);
+ for (String authnMethod : authnHandler.getSupportedAuthenticationMethods()) {
+ authenticationHandlers.put(authnMethod, authnHandler);
+ if (log.isDebugEnabled()) {
+ log.debug("Authentication method " + authnMethod + " mapped to authentication handler of type: "
+ + authnHandler.getClass().getName());
+ }
+ }
+ }
+
+ writeLock.unlock();
+ }
+}
\ No newline at end of file
*/
protected void resolvePrincipal(SAML2ProfileRequestContext requestContext) throws ProfileException {
AbstractSAML2ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
+ if (profileConfiguration == null) {
+ log.error("Unable to resolve principal, no SAML 2 profile configuration for relying party "
+ + requestContext.getRelyingPartyId());
+ requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER_URI, StatusCode.REQUEST_DENIED_URI,
+ "Error resolving principal"));
+ throw new ProfileException(
+ "Unable to resolve principal, no SAML 2 profile configuration for relying party "
+ + requestContext.getRelyingPartyId());
+ }
SAML2AttributeAuthority attributeAuthority = profileConfiguration.getAttributeAuthority();
if (log.isDebugEnabled()) {
SSORequestContext requestContext = new SSORequestContext(request, response);
try {
+ requestContext.setLoginContext(loginContext);
+
String relyingPartyId = loginContext.getRelyingPartyId();
AuthnRequest authnRequest = loginContext.getAuthenticationRequest();
requestContext.setAssertingPartyId(requestContext.getRelyingPartyConfiguration().getProviderId());
requestContext.setAssertingPartyRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME);
+
+ requestContext.setPrincipalName(loginContext.getPrincipalName());
requestContext.setProfileConfiguration((SSOConfiguration) rpConfig
.getProfileConfiguration(SSOConfiguration.PROFILE_ID));
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<ProfileHandlerGroup xmlns="urn:mace:shibboleth:2.0:idp:profile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:2.0:idp:profile classpath:/schema/shibboleth-2.0-idp-profile.xsd">
+
+ <ErrorHandler xsi:type="JSPErrorHandler" jspPagePath="/error.jsp" />
+
+ <ProfileHandler xsi:type="Status">
+ <RequestPath>/shibboleth/IdP/status</RequestPath>
+ </ProfileHandler>
+
+ <ProfileHandler xsi:type="SAML2AttributeQuery"
+ securityPolicyFactoryId="shibboleth.SAML2AttributeQueryMessageSecurityPolicyFactoryNoIssuerAuth">
+ <RequestPath>/IdP/saml2/SOAP/AttributeQueryNoAuth</RequestPath>
+ </ProfileHandler>
+
+ <ProfileHandler xsi:type="SAML2AttributeQuery"
+ securityPolicyFactoryId="shibboleth.SAML2AttributeQueryMessageSecurityPolicyFactoryIssuerAuth">
+ <RequestPath>/IdP/saml2/SOAP/AttributeQuery</RequestPath>
+ </ProfileHandler>
+
+ <ProfileHandler xsi:type="SAML2SSO"
+ securityPolicyFactoryId="shibboleth.SAML2SSOMessageSecurityPolicyFactoryNoIssuerAuth">
+ <RequestPath>/IdP/saml2/SSONoAuth</RequestPath>
+ </ProfileHandler>
+
+ <ProfileHandler xsi:type="SAML2SSO"
+ securityPolicyFactoryId="shibboleth.SAML2SSOMessageSecurityPolicyFactoryIssuerAuth">
+ <RequestPath>/IdP/saml2/SSO</RequestPath>
+ </ProfileHandler>
+
+</ProfileHandlerGroup>
\ No newline at end of file
<property name="namespaceAware" value="true" />
</bean>
+ <bean id="shibboleth.SAML2SSOMessageSecurityPolicyFactoryNoIssuerAuth"
+ parent="shibboleth.SAML2SSOMessageSecurityPolicyFactoryIssuerAuth">
+ <property name="requiredAuthenticatedIssuer" value="false" />
+ </bean>
+
+ <bean id="shibboleth.SAML2SSOMessageSecurityPolicyFactoryIssuerAuth"
+ parent="shibboleth.BaseSAML2SecurityPolicyFactory">
+ <property name="issuerRole">
+ <bean id="shibboleth.SAML2SSORole" class="javax.xml.namespace.QName">
+ <constructor-arg value="urn:oasis:names:tc:SAML:2.0:metadata" />
+ <constructor-arg value="SPSSODescriptor" />
+ </bean>
+ </property>
+ </bean>
+
<bean id="shibboleth.SAML2AttributeQueryMessageSecurityPolicyFactoryNoIssuerAuth"
- class="org.opensaml.common.binding.security.SAMLSecurityPolicyFactory">
+ parent="shibboleth.SAML2AttributeQueryMessageSecurityPolicyFactoryIssuerAuth">
+ <property name="requiredAuthenticatedIssuer" value="false" />
+ </bean>
+
+ <bean id="shibboleth.SAML2AttributeQueryMessageSecurityPolicyFactoryIssuerAuth"
+ parent="shibboleth.BaseSAML2SecurityPolicyFactory">
<property name="issuerRole">
<bean id="shibboleth.SAML2AttributeQueryRole" class="javax.xml.namespace.QName">
<constructor-arg value="urn:oasis:names:tc:SAML:2.0:metadata" />
<constructor-arg value="SPSSODescriptor" />
</bean>
</property>
+ </bean>
+
+ <bean id="shibboleth.BaseSAML2SecurityPolicyFactory" abstract="true" class="org.opensaml.common.binding.security.SAMLSecurityPolicyFactory">
<property name="issuerProtocol" value="urn:oasis:names:tc:SAML:2.0:protocol" />
<property name="policyRuleFactories">
<list>
<ref bean="shibboleth.MessageIssueInstantRuleFactory" />
</list>
</property>
- <property name="requiredAuthenticatedIssuer" value="false" />
- </bean>
-
- <bean id="shibboleth.SAML2AttributeQueryMessageSecurityPolicyFactoryIssuerAuth"
- class="org.opensaml.common.binding.security.SAMLSecurityPolicyFactory"
- parent="shibboleth.SAML2AttributeQueryMessageSecurityPolicyFactoryNoIssuerAuth">
<property name="requiredAuthenticatedIssuer" value="true" />
</bean>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<ProfileHandlerGroup xmlns="urn:mace:shibboleth:2.0:profile-handler"
- xmlns:idpProfile="urn:mace:shibboleth:2.0:idp:profiles" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="urn:mace:shibboleth:2.0:profile-handler classpath:/schema/shibboleth-2.0-profile-handler.xsd
- urn:mace:shibboleth:2.0:idp:profiles classpath:/schema/shibboleth-2.0-idp-profile.xsd">
-
- <ErrorHandler xsi:type="JSPErrorHandler" jspPagePath="/error.jsp" />
-
- <ProfileHandler xsi:type="idpProfile:Status">
- <RequestPath>/shibboleth/IdP/status</RequestPath>
- </ProfileHandler>
-
- <ProfileHandler xsi:type="idpProfile:SAML2AttributeQuery"
- securityPolicyFactoryId="shibboleth.SAML2AttributeQueryMessageSecurityPolicyFactoryNoIssuerAuth">
- <RequestPath>/IdP/saml2/SOAP/AttributeQueryNoAuth</RequestPath>
- </ProfileHandler>
-
- <ProfileHandler xsi:type="idpProfile:SAML2AttributeQuery"
- securityPolicyFactoryId="shibboleth.SAML2AttributeQueryMessageSecurityPolicyFactoryIssuerAuth">
- <RequestPath>/IdP/saml2/SOAP/AttributeQuery</RequestPath>
- </ProfileHandler>
-
- <!--
- <ProfileHandler xsi:type="idpProfile:SAML2SSO">
- <RequestPath>/IdP/saml2/HTTP/SSO</RequestPath>
- </ProfileHandler>
-
- <ProfileHandler xsi:type="idpProfile:SAML2AttributeQuery">
- <RequestPath>/IdP/saml2/SOAP/attribute</RequestPath>
- </ProfileHandler>
- -->
-
-</ProfileHandlerGroup>
\ No newline at end of file
<RelyingParty id="urn:example.org:unitTestFed"
provider="http://example.org/IdP">
- <ProfileConfiguration xsi:type="saml:SAML2AttributesQueryProfile" />
+ <ProfileConfiguration xsi:type="saml:SAML2AttributeQueryProfile" />
+ <ProfileConfiguration xsi:type="saml:SAML2SSOProfile" />
</RelyingParty>
<MetadataProvider id="UnitTestConf1" xsi:type="InlineMetadataProvider" xmlns="urn:mace:shibboleth:2.0:metadata">
<?xml version="1.0" encoding="UTF-8"?>
<IdPConfig xmlns="urn:mace:shibboleth:2.0:idp:services" xmlns:service="urn:mace:shibboleth:2.0:services"
- xmlns:profile="urn:mace:shibboleth:2.0:profile-handler" xmlns:relyingParty="urn:mace:shibboleth:2.0:relying-party"
+ xmlns:profile="urn:mace:shibboleth:2.0:idp:profile" xmlns:relyingParty="urn:mace:shibboleth:2.0:relying-party"
xmlns:resolver="urn:mace:shibboleth:2.0:resolver" xmlns:afp="urn:mace:shibboleth:2.0:afp"
xmlns:resource="urn:mace:shibboleth:2.0:resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:mace:shibboleth:2.0:idp:services classpath:/schema/shibboleth-2.0-idp-service.xsd
urn:mace:shibboleth:2.0:services classpath:/schema/shibboleth-2.0-services.xsd
- urn:mace:shibboleth:2.0:profile-handler classpath:/schema/shibboleth-2.0-profile-handler.xsd
+ urn:mace:shibboleth:2.0:idp:profile classpath:/schema/shibboleth-2.0-idp-profile.xsd
urn:mace:shibboleth:2.0:relying-party classpath:/schema/shibboleth-2.0-relying-party.xsd
urn:mace:shibboleth:2.0:resolver classpath:/schema/shibboleth-2.0-attribute-resolver.xsd
urn:mace:shibboleth:2.0:afp classpath:/schema/shibboleth-2.0-afp.xsd
urn:mace:shibboleth:2.0:resource classpath:/schema/shibboleth-2.0-resource.xsd">
-<!--
- <LoggingConfiguration>$IDP_HOME$/conf/logging.xml</LoggingConfiguration>
--->
-
- <Service id="shibboleth.ProfileHandler"
- xmlns="urn:mace:shibboleth:2.0:services"
- xsi:type="profile:ShibbolethProfileHandlerManager">
- <ConfigurationResource file="/data/conf1/protocol.xml" xsi:type="resource:ClasspathResource" />
- </Service>
-
- <Service id="shibboleth.RelyingPartyConfigurationManager"
- xmlns="urn:mace:shibboleth:2.0:services"
- xsi:type="relyingParty:SAMLMDRelyingPartyConfigurationManager">
- <ConfigurationResource file="/data/conf1/relying-party.xml" xsi:type="resource:ClasspathResource" />
- </Service>
-
<Service id="shibboleth.AttributeResolver"
xmlns="urn:mace:shibboleth:2.0:services"
xsi:type="resolver:ShibbolethAttributeResolver">
<ConfigurationResource file="/data/conf1/attribute-filter.xml" xsi:type="resource:ClasspathResource" />
</Service>
+ <Service id="shibboleth.HandlerManager"
+ xmlns="urn:mace:shibboleth:2.0:services"
+ xsi:type="profile:IdPProfileHandlerManager">
+ <ConfigurationResource file="/data/conf1/handler.xml" xsi:type="resource:ClasspathResource" />
+ </Service>
+
+ <Service id="shibboleth.RelyingPartyConfigurationManager"
+ xmlns="urn:mace:shibboleth:2.0:services"
+ xsi:type="relyingParty:SAMLMDRelyingPartyConfigurationManager">
+ <ConfigurationResource file="/data/conf1/relying-party.xml" xsi:type="resource:ClasspathResource" />
+ </Service>
+
</IdPConfig>
\ No newline at end of file
import org.w3c.dom.Element;
import edu.internet2.middleware.shibboleth.common.profile.ProfileHandler;
+import edu.internet2.middleware.shibboleth.common.profile.ProfileHandlerManager;
import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
-import edu.internet2.middleware.shibboleth.common.profile.provider.ShibbolethProfileHandlerManager;
import edu.internet2.middleware.shibboleth.idp.profile.ShibbolethProfileRequest;
import edu.internet2.middleware.shibboleth.idp.profile.ShibbolethProfileResponse;
MockHttpServletResponse servletResponse = new MockHttpServletResponse();
- ShibbolethProfileHandlerManager handlerManager = (ShibbolethProfileHandlerManager) getApplicationContext()
- .getBean("shibboleth.ProfileHandler");
+ ProfileHandlerManager handlerManager = (ProfileHandlerManager) getApplicationContext().getBean(
+ "shibboleth.HandlerManager");
ProfileHandler handler = handlerManager.getProfileHandler(servletRequest);
assertNotNull(handler);
assertTrue(response.contains(StatusCode.RESPONDER_URI));
assertTrue(response.contains(StatusCode.REQUEST_DENIED_URI));
}
-
+
/** Test a request where the Issuer is authenticated and has not requested any specific attributes. */
public void testAuthenticatedIssuerNoProfileConfiguration() throws Exception {
AttributeQuery query = buildAttributeQuery("urn:example.org:unitTest:sp1");
MockHttpServletResponse servletResponse = new MockHttpServletResponse();
- ShibbolethProfileHandlerManager handlerManager = (ShibbolethProfileHandlerManager) getApplicationContext()
- .getBean("shibboleth.ProfileHandler");
+ ProfileHandlerManager handlerManager = (ProfileHandlerManager) getApplicationContext().getBean(
+ "shibboleth.HandlerManager");
ProfileHandler handler = handlerManager.getProfileHandler(servletRequest);
assertNotNull(handler);
assertTrue(response.contains(StatusCode.RESPONDER_URI));
assertTrue(response.contains(StatusCode.REQUEST_DENIED_URI));
}
-
+
/** Test a request where the Issuer is authenticated and has not requested any specific attributes. */
public void testAuthenticatedIssuerNoRequestAttributes() throws Exception {
AttributeQuery query = buildAttributeQuery("urn:example.org:unitTestFed:sp2");
MockHttpServletResponse servletResponse = new MockHttpServletResponse();
- ShibbolethProfileHandlerManager handlerManager = (ShibbolethProfileHandlerManager) getApplicationContext()
- .getBean("shibboleth.ProfileHandler");
+ ProfileHandlerManager handlerManager = (ProfileHandlerManager) getApplicationContext().getBean(
+ "shibboleth.HandlerManager");
ProfileHandler handler = handlerManager.getProfileHandler(servletRequest);
assertNotNull(handler);
assertTrue(response.contains("Name=\"cn\""));
assertTrue(response.contains("Name=\"uid\""));
}
-
+
/**
* Builds a basic attribute query.
*
--- /dev/null
+/*
+ * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.internet2.middleware.shibboleth.idp.system.conf1;
+
+import java.io.StringWriter;
+
+import javax.servlet.http.HttpSession;
+
+import org.joda.time.DateTime;
+import org.opensaml.common.SAMLObjectBuilder;
+import org.opensaml.common.binding.encoding.MessageEncoder;
+import org.opensaml.common.binding.encoding.MessageEncoderFactory;
+import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;
+import org.opensaml.saml2.core.AttributeQuery;
+import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.xml.io.Marshaller;
+import org.opensaml.xml.io.MarshallingException;
+import org.opensaml.xml.util.Base64;
+import org.opensaml.xml.util.XMLHelper;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.w3c.dom.Element;
+
+import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
+import edu.internet2.middleware.shibboleth.common.profile.ProfileHandler;
+import edu.internet2.middleware.shibboleth.common.profile.ProfileHandlerManager;
+import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
+import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
+import edu.internet2.middleware.shibboleth.idp.authn.Saml2LoginContext;
+import edu.internet2.middleware.shibboleth.idp.profile.IdPProfileHandlerManager;
+import edu.internet2.middleware.shibboleth.idp.profile.ShibbolethProfileRequest;
+import edu.internet2.middleware.shibboleth.idp.profile.ShibbolethProfileResponse;
+
+/**
+ *
+ */
+public class SAML2SSOTestCase extends BaseConf1TestCase {
+
+ /** Tests a request where the Issuer can not be authenticated. */
+ public void testUnathenticatedIssuer() throws Exception {
+ AuthnRequest authnRequest = buildAuthnRequest("urn:example.org:unitTest:sp1");
+ String authnRequestString = getSamlRequestString(authnRequest);
+
+ MockHttpServletRequest servletRequest = new MockHttpServletRequest();
+ servletRequest.setPathInfo("/IdP/saml2/SSONoAuth");
+ servletRequest.setParameter(HTTPPostDecoder.REQUEST_PARAM, Base64.encodeBytes(authnRequestString.getBytes()));
+
+ MockHttpServletResponse servletResponse = new MockHttpServletResponse();
+
+ ProfileHandlerManager handlerManager = (ProfileHandlerManager) getApplicationContext().getBean(
+ "shibboleth.HandlerManager");
+ ProfileHandler handler = handlerManager.getProfileHandler(servletRequest);
+ assertNotNull(handler);
+
+ // Process request
+ ProfileRequest profileRequest = new ShibbolethProfileRequest(servletRequest);
+ ProfileResponse profileResponse = new ShibbolethProfileResponse(servletResponse);
+
+ try {
+ handler.processRequest(profileRequest, profileResponse);
+ fail();
+ } catch (ProfileException e) {
+ // expected
+ }
+ }
+
+ public void testAuthenicatedIssuer() throws Exception {
+ AuthnRequest authnRequest = buildAuthnRequest("urn:example.org:unitTestFed:sp2");
+ String authnRequestString = getSamlRequestString(authnRequest);
+
+ MockHttpServletRequest servletRequest = new MockHttpServletRequest();
+ servletRequest.setPathInfo("/IdP/saml2/SSONoAuth");
+ servletRequest.setParameter(HTTPPostDecoder.REQUEST_PARAM, Base64.encodeBytes(authnRequestString.getBytes()));
+
+ MockHttpServletResponse servletResponse = new MockHttpServletResponse();
+
+ ProfileHandlerManager handlerManager = (ProfileHandlerManager) getApplicationContext().getBean(
+ "shibboleth.HandlerManager");
+ ProfileHandler handler = handlerManager.getProfileHandler(servletRequest);
+ assertNotNull(handler);
+
+ // Process request
+ ProfileRequest profileRequest = new ShibbolethProfileRequest(servletRequest);
+ ProfileResponse profileResponse = new ShibbolethProfileResponse(servletResponse);
+ handler.processRequest(profileRequest, profileResponse);
+
+ HttpSession session = servletRequest.getSession();
+ Saml2LoginContext loginContext = (Saml2LoginContext) session.getAttribute(Saml2LoginContext.LOGIN_CONTEXT_KEY);
+ assertNotNull(loginContext);
+ }
+
+ public void testSecondLeg() throws Exception {
+ AuthnRequest authnRequest = buildAuthnRequest("urn:example.org:unitTestFed:sp2");
+
+ Saml2LoginContext loginContext = new Saml2LoginContext("urn:example.org:unitTestFed:sp2", authnRequest);
+ loginContext.setAuthenticationInstant(new DateTime());
+ loginContext.setAuthenticationMethod(IdPProfileHandlerManager.DEFAULT_AUTHEN_METHOD_URI);
+ loginContext.setPrincipalAuthenticated(true);
+ loginContext.setPrincipalName("testUser");
+
+ MockHttpServletRequest servletRequest = new MockHttpServletRequest();
+ servletRequest.setPathInfo("/IdP/saml2/SSONoAuth");
+
+ HttpSession session = servletRequest.getSession();
+ session.setAttribute(Saml2LoginContext.LOGIN_CONTEXT_KEY, loginContext);
+
+ MockHttpServletResponse servletResponse = new MockHttpServletResponse();
+
+ ProfileHandlerManager handlerManager = (ProfileHandlerManager) getApplicationContext().getBean(
+ "shibboleth.HandlerManager");
+ ProfileHandler handler = handlerManager.getProfileHandler(servletRequest);
+ assertNotNull(handler);
+
+ // Process request
+ ProfileRequest profileRequest = new ShibbolethProfileRequest(servletRequest);
+ ProfileResponse profileResponse = new ShibbolethProfileResponse(servletResponse);
+ handler.processRequest(profileRequest, profileResponse);
+
+ }
+
+ protected AuthnRequest buildAuthnRequest(String requester) {
+ SAMLObjectBuilder<Issuer> issuerBuilder = (SAMLObjectBuilder<Issuer>) builderFactory
+ .getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
+ Issuer issuer = issuerBuilder.buildObject();
+ issuer.setValue(requester);
+
+ SAMLObjectBuilder<AuthnRequest> authnRequestBuilder = (SAMLObjectBuilder<AuthnRequest>) builderFactory
+ .getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
+ AuthnRequest request = authnRequestBuilder.buildObject();
+ request.setID("1");
+ request.setIssueInstant(new DateTime());
+ request.setIssuer(issuer);
+
+ return request;
+ }
+
+ protected String getSamlRequestString(AuthnRequest request) throws MarshallingException {
+ Marshaller marshaller = marshallerFactory.getMarshaller(request);
+ Element requestElem = marshaller.marshall(request);
+ String requestString = XMLHelper.nodeToString(requestElem);
+ return Base64.encodeBytes(requestString.getBytes());
+ }
+}
\ No newline at end of file