Login Handler Extensions
This information is meant to be used in conjunction with the Creating Custom IdP Extensions - General Overview guide.
Classes, Schema Types, and Schema Files
- Interface to implement:
edu.internet2.middleware.shibboleth.idp.authn.LoginHandler
- Bean Definition Parser to extend:
edu.internet2.middleware.shibboleth.idp.config.profile.authn.AbstractLoginHandlerBeanDefinitionParser
- Bean Factory to extend:
edu.internet2.middleware.shibboleth.idp.config.profile.authn.AbstractLoginHandlerFactoryBean
- Location of schema file to import:
/schema/shibboleth-2.0-idp-profile-handler.xsd
- Namespace containing schema type to extend:
urn:mace:shibboleth:2.0:idp:profile-handler
- Complex type to extend:
LoginHandlerType
Example Extension
Extension Class File
package foo.shibboleth.idp.authn.provider; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.opensaml.util.URLBuilder; import edu.internet2.middleware.shibboleth.idp.authn.provider.AbstractLoginHandler; public class MyloginHandler extends AbstractLoginHandler { /** Class logger. */ private final Logger log = LoggerFactory.getLogger(MyloginHandler.class); /** The URL of the servlet used to perform authentication. */ private String authenticationServletURL; /** * Constructor. * * @param servletURL URL to the authentication servlet */ public MyloginHandler(String servletURL) { super(); setSupportsPassive(false); setSupportsForceAuthentication(true); authenticationServletURL = servletURL; } public void login(final HttpServletRequest httpRequest, final HttpServletResponse httpResponse) { // forward control to the servlet try { StringBuilder pathBuilder = new StringBuilder(); pathBuilder.append(httpRequest.getContextPath()); if(!authenticationServletURL.startsWith("/")){ pathBuilder.append("/"); } pathBuilder.append(authenticationServletURL); URLBuilder urlBuilder = new URLBuilder(); urlBuilder.setScheme(httpRequest.getScheme()); urlBuilder.setHost(httpRequest.getServerName()); urlBuilder.setPort(httpRequest.getServerPort()); urlBuilder.setPath(pathBuilder.toString()); log.debug("Redirecting to {}", urlBuilder.buildURL()); httpResponse.sendRedirect(urlBuilder.buildURL()); return; } catch (IOException ex) { log.error("Unable to redirect to authentication servlet.", ex); } } }
Extension Schema
<?xml version="1.0" encoding="UTF-8"?> <schema targetNamespace="http://example.org/shibboleth/authn" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:ph="urn:mace:shibboleth:2.0:idp:profile-handler" elementFormDefault="qualified"> <import namespace="urn:mace:shibboleth:2.0:idp:profile-handler" schemaLocation="classpath:/schema/shibboleth-2.0-idp-profile-handler.xsd" /> <complexType name="Mylogin"> <complexContent> <extension base="ph:LoginHandlerType"> <attribute name="authenticationServletURL" type="string" default="/Authn/UserPassword"/> </extension> </complexContent> </complexType> </schema>
Bean Definition Parser
package foo.shibboleth.udo.config.profile.authn import javax.xml.namespace.QName; import org.opensaml.xml.util.DatatypeHelper; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Element; import foo.shibboleth.idp.config.profile.ProfileHandlerMyNamespaceHandler;import edu.internet2.middleware.shibboleth.idp.config.profile.authn.AbstractLoginHandlerBeanDefinitionParser; public class MyHandlerBeanDefinitionParser extends AbstractLoginHandlerBeanDefinitionParser { /** Schema type. */ public static final QName SCHEMA_TYPE = new QName(ProfileHandlerMyNamespaceHandler.NAMESPACE, "Mylogin"); /** Class logger. */ private final Logger log = LoggerFactory.getLogger(MyHandlerBeanDefinitionParser.class); /** {@inheritDoc} */ protected Class getBeanClass(Element element) { return MyHandlerFactoryBean.class; } /** {@inheritDoc} */ protected void doParse(Element config, BeanDefinitionBuilder builder) { super.doParse(config, builder); builder.addPropertyValue("authenticationServletURL", DatatypeHelper.safeTrim(config.getAttributeNS(null,"authenticationServletURL"))); } }
Bean Factory
package foo.shibboleth.idp.config.profile.authn; import foo.shibboleth.idp.authn.provider.MyloginHandler; import edu.internet2.middleware.shibboleth.idp.config.profile.authn.AbstractLoginHandlerFactoryBean; /** * Factory bean for {@link MyloginHandler}s. */ public class MyHandlerFactoryBean extends AbstractLoginHandlerFactoryBean{ // URL to authenticatio servlet private String authenticationServletURL; /** * Gets the URL to authentication servlet. * @return URL to authentication servlet */ public String getAuthenticationServletURL(){ return authenticationServletURL; } /** * Set URL to authentication servlet * @param url URL to authentication servlet */ public void setAuthenticationServletURL(String url){ authenticationServletURL = url; } @Override protected Object createInstance() throws Exception { MyloginHandler handler = new MyloginHandler(authenticationServletURL); populateHandler(handler); return handler; } @Override public Class getObjectType() { return MyloginHandler.class; } }
Namespace Handler
package foo.shibboleth.idp.config.profile; import edu.internet2.middleware.shibboleth.common.config.BaseSpringNamespaceHandler; import foo.shibboleth.idp.config.profile.authn.MyHandlerBeanDefinitionParser; public class ProfileHandlerMyNamespaceHandler extends BaseSpringNamespaceHandler { /** Namespace URI. */ public static final String NAMESPACE = "http://example.org/shibboleth/authn"; public void init(){ super.init(); registerBeanDefinitionParser(MyHandlerBeanDefinitionParser.SCHEMA_TYPE, new MyHandlerBeanDefinitionParser()); } }
spring.schemas File
http\://example.org/shibboleth/authn = schema/mylogin-profile-handler.xsd
spring.handlers File
http\://example.org/shibboleth/authn = foo.shibboleth.idp.config.profile.ProfileHandlerMyNamespaceHandler