From 1360bf5372b5593541feee405a66651bf8dce456 Mon Sep 17 00:00:00 2001 From: lajoie Date: Tue, 19 Feb 2008 08:25:35 +0000 Subject: [PATCH 1/1] Add explicit PreviousSession support Cleanup some authn engine code git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@2629 ab3bd59b-922f-494d-bb5f-6f0a3c29deca --- .../schema/shibboleth-2.0-idp-profile-handler.xsd | 29 +++ resources/conf/handler.xml | 8 + .../shibboleth/idp/authn/AuthenticationEngine.java | 188 +++++++++++--------- .../provider/PreviousSessionLoginHandler.java | 135 ++++++++++++++ .../profile/ProfileHandlerNamespaceHandler.java | 12 +- .../authn/AbstractLoginHandlerFactoryBean.java | 2 +- ...ousSessionLoginHandlerBeanDefinitionParser.java | 54 ++++++ .../PreviousSessionLoginHandlerFactoryBean.java | 103 +++++++++++ 8 files changed, 438 insertions(+), 93 deletions(-) create mode 100644 src/edu/internet2/middleware/shibboleth/idp/authn/provider/PreviousSessionLoginHandler.java create mode 100644 src/edu/internet2/middleware/shibboleth/idp/config/profile/authn/PreviousSessionLoginHandlerBeanDefinitionParser.java create mode 100644 src/edu/internet2/middleware/shibboleth/idp/config/profile/authn/PreviousSessionLoginHandlerFactoryBean.java diff --git a/resources/classpath/schema/shibboleth-2.0-idp-profile-handler.xsd b/resources/classpath/schema/shibboleth-2.0-idp-profile-handler.xsd index f7c0502..c1e0335 100644 --- a/resources/classpath/schema/shibboleth-2.0-idp-profile-handler.xsd +++ b/resources/classpath/schema/shibboleth-2.0-idp-profile-handler.xsd @@ -217,6 +217,35 @@ + + + + + + + + Optional servlet path to which the browser may be redirected. + + + + + + + Whether this login handler should report its authentication method as PreviousSession + or the authentication method requested by the peer. + + + + + + + Whether this login handler, when redirecting to a servlet, support passives authentication. + + + + + + diff --git a/resources/conf/handler.xml b/resources/conf/handler.xml index 43858cc..e95d972 100644 --- a/resources/conf/handler.xml +++ b/resources/conf/handler.xml @@ -73,5 +73,13 @@ jaasConfigurationLocation="file://$IDP_HOME$/conf/login.config"> urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport + + + + urn:oasis:names:tc:SAML:2.0:ac:classes:PreviousSession + diff --git a/src/edu/internet2/middleware/shibboleth/idp/authn/AuthenticationEngine.java b/src/edu/internet2/middleware/shibboleth/idp/authn/AuthenticationEngine.java index 9763b1e..b289189 100644 --- a/src/edu/internet2/middleware/shibboleth/idp/authn/AuthenticationEngine.java +++ b/src/edu/internet2/middleware/shibboleth/idp/authn/AuthenticationEngine.java @@ -18,7 +18,6 @@ package edu.internet2.middleware.shibboleth.idp.authn; import java.io.IOException; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -41,6 +40,7 @@ import org.slf4j.LoggerFactory; import edu.internet2.middleware.shibboleth.common.session.SessionManager; import edu.internet2.middleware.shibboleth.common.util.HttpHelper; +import edu.internet2.middleware.shibboleth.idp.authn.provider.PreviousSessionLoginHandler; import edu.internet2.middleware.shibboleth.idp.profile.IdPProfileHandlerManager; import edu.internet2.middleware.shibboleth.idp.session.AuthenticationMethodInformation; import edu.internet2.middleware.shibboleth.idp.session.ServiceInformation; @@ -165,7 +165,7 @@ public class AuthenticationEngine extends HttpServlet { if (!loginContext.getAuthenticationAttempted()) { startUserAuthentication(loginContext, httpRequest, httpResponse); } else { - completeAuthenticationWithoutActiveMethod(loginContext, httpRequest, httpResponse); + completeAuthentication(loginContext, httpRequest, httpResponse); } } @@ -182,40 +182,28 @@ public class AuthenticationEngine extends HttpServlet { HttpServletResponse httpResponse) { LOG.debug("Beginning user authentication process"); try { + Session idpSession = (Session) httpRequest.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE); Map possibleLoginHandlers = determinePossibleLoginHandlers(loginContext); - ArrayList activeAuthnMethods = new ArrayList(); - - Session userSession = (Session) httpRequest.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE); - if (userSession != null) { - activeAuthnMethods.addAll(userSession.getAuthenticationMethods().values()); - } + // Filter out possible candidate login handlers by forced and passive authentication requirements if (loginContext.isForceAuthRequired()) { - LOG.debug("Forced authentication is required, filtering possible login handlers accordingly"); - filterByForceAuthentication(loginContext, activeAuthnMethods, possibleLoginHandlers); - } else { - LOG.debug("Forced authentication not required, trying existing authentication methods"); - for (AuthenticationMethodInformation activeAuthnMethod : activeAuthnMethods) { - if (possibleLoginHandlers.containsKey(activeAuthnMethod.getAuthenticationMethod())) { - completeAuthenticationWithActiveMethod(loginContext, activeAuthnMethod, httpRequest, - httpResponse); - return; - } - } - LOG.debug("No existing authentication method meets service provides requirements"); + filterByForceAuthentication(idpSession, loginContext, possibleLoginHandlers); } if (loginContext.isPassiveAuthRequired()) { - LOG.debug("Passive authentication is required, filtering poassibl login handlers accordingly."); filterByPassiveAuthentication(loginContext, possibleLoginHandlers); } - // Since we made it this far, just pick the first remaining login handler from the list - Entry chosenLoginHandler = possibleLoginHandlers.entrySet().iterator().next(); - LOG.debug("Authenticating user with login handler of type {}", chosenLoginHandler.getValue().getClass() - .getName()); - authenticateUser(chosenLoginHandler.getKey(), chosenLoginHandler.getValue(), loginContext, httpRequest, - httpResponse); + // If the user already has a session and its usage is acceptable than use it + // otherwise just use the first candidate login handler + if (idpSession != null + && possibleLoginHandlers.containsKey(PreviousSessionLoginHandler.PREVIOUS_SESSION_AUTHN_METHOD)) { + authenticateUserWithPreviousSession(loginContext, possibleLoginHandlers, httpRequest, httpResponse); + } else { + Entry chosenLoginHandler = possibleLoginHandlers.entrySet().iterator().next(); + authenticateUser(chosenLoginHandler.getKey(), chosenLoginHandler.getValue(), loginContext, httpRequest, + httpResponse); + } } catch (AuthenticationException e) { loginContext.setAuthenticationFailure(e); returnToProfileHandler(loginContext, httpRequest, httpResponse); @@ -243,7 +231,8 @@ public class AuthenticationEngine extends HttpServlet { Entry supportedLoginHandler; while (supportedLoginHandlerItr.hasNext()) { supportedLoginHandler = supportedLoginHandlerItr.next(); - if (!loginContext.getRequestedAuthenticationMethods().contains(supportedLoginHandler.getKey())) { + if (supportedLoginHandler.getKey().equals(PreviousSessionLoginHandler.PREVIOUS_SESSION_AUTHN_METHOD) + || !loginContext.getRequestedAuthenticationMethods().contains(supportedLoginHandler.getKey())) { supportedLoginHandlerItr.remove(); continue; } @@ -261,22 +250,27 @@ public class AuthenticationEngine extends HttpServlet { /** * Filters out any login handler based on the requirement for forced authentication. * - * During forced authentication any handler that has not previously been used to authenticate the the user or any + * During forced authentication any handler that has not previously been used to authenticate the user or any * handlers that have been and support force re-authentication may be used. Filter out any of the other ones. * + * @param idpSession user's current IdP session * @param loginContext current login context - * @param activeAuthnMethods currently active authentication methods, never null * @param loginHandlers login handlers to filter * * @throws ForceAuthenticationException thrown if no handlers remain after filtering */ - protected void filterByForceAuthentication(LoginContext loginContext, - Collection activeAuthnMethods, Map loginHandlers) - throws ForceAuthenticationException { + protected void filterByForceAuthentication(Session idpSession, LoginContext loginContext, + Map loginHandlers) throws ForceAuthenticationException { + LOG.debug("Forced authentication is required, filtering possible login handlers accordingly"); + + ArrayList activeMethods = new ArrayList(); + if (idpSession != null) { + activeMethods.addAll(idpSession.getAuthenticationMethods().values()); + } LoginHandler loginHandler; - for (AuthenticationMethodInformation activeAuthnMethod : activeAuthnMethods) { - loginHandler = loginHandlers.get(activeAuthnMethod.getAuthenticationMethod()); + for (AuthenticationMethodInformation activeMethod : activeMethods) { + loginHandler = loginHandlers.get(activeMethod.getAuthenticationMethod()); if (loginHandler != null && !loginHandler.supportsForceAuthentication()) { for (String handlerSupportedMethods : loginHandler.getSupportedAuthenticationMethods()) { loginHandlers.remove(handlerSupportedMethods); @@ -301,6 +295,8 @@ public class AuthenticationEngine extends HttpServlet { */ protected void filterByPassiveAuthentication(LoginContext loginContext, Map loginHandlers) throws PassiveAuthenticationException { + LOG.debug("Passive authentication is required, filtering poassible login handlers accordingly."); + LoginHandler loginHandler; Iterator> authnMethodItr = loginHandlers.entrySet().iterator(); while (authnMethodItr.hasNext()) { @@ -317,56 +313,69 @@ public class AuthenticationEngine extends HttpServlet { } /** - * Authenticates the user with the given authentication method provided by the given login handler. + * Completes the authentication request using an existing, active, authentication method for the current user. * - * @param authnMethod the authentication method that will be used to authenticate the user - * @param logingHandler login handler that will authenticate user * @param loginContext current login context + * @param possibleLoginHandlers login handlers that meet the peers authentication requirements * @param httpRequest current HTTP request * @param httpResponse current HTTP response */ - protected void authenticateUser(String authnMethod, LoginHandler logingHandler, LoginContext loginContext, - HttpServletRequest httpRequest, HttpServletResponse httpResponse) { + protected void authenticateUserWithPreviousSession(LoginContext loginContext, + Map possibleLoginHandlers, HttpServletRequest httpRequest, + HttpServletResponse httpResponse) { + LOG.debug("Authenticating user by way of existing session."); + + Session idpSession = (Session) httpRequest.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE); + PreviousSessionLoginHandler loginHandler = (PreviousSessionLoginHandler) handlerManager.getLoginHandlers().get( + PreviousSessionLoginHandler.PREVIOUS_SESSION_AUTHN_METHOD); + + AuthenticationMethodInformation authenticationMethod = null; + for (String possibleAuthnMethod : possibleLoginHandlers.keySet()) { + authenticationMethod = idpSession.getAuthenticationMethods().get(possibleAuthnMethod); + if (authenticationMethod != null) { + break; + } + } + + if (loginHandler.reportPreviousSessionAuthnMethod()) { + loginContext.setAuthenticationDuration(loginHandler.getAuthenticationDuration()); + loginContext.setAuthenticationInstant(new DateTime()); + loginContext.setAuthenticationMethod(PreviousSessionLoginHandler.PREVIOUS_SESSION_AUTHN_METHOD); + } else { + loginContext.setAuthenticationDuration(authenticationMethod.getAuthenticationDuration()); + loginContext.setAuthenticationInstant(authenticationMethod.getAuthenticationInstant()); + loginContext.setAuthenticationMethod(authenticationMethod.getAuthenticationMethod()); + } + loginContext.setPrincipalName(idpSession.getPrincipalName()); - loginContext.setAuthenticationAttempted(); - loginContext.setAuthenticationDuration(logingHandler.getAuthenticationDuration()); - loginContext.setAuthenticationMethod(authnMethod); - loginContext.setAuthenticationEngineURL(HttpHelper.getRequestUriWithoutContext(httpRequest)); httpRequest.getSession().setAttribute(LoginContext.LOGIN_CONTEXT_KEY, loginContext); - logingHandler.login(httpRequest, httpResponse); + loginHandler.login(httpRequest, httpResponse); } /** - * Completes the authentication request using an existing, active, authentication method for the current user. + * Authenticates the user with the given authentication method provided by the given login handler. * + * @param authnMethod the authentication method that will be used to authenticate the user + * @param loginHandler login handler that will authenticate user * @param loginContext current login context - * @param authenticationMethod authentication method to use to complete the request * @param httpRequest current HTTP request * @param httpResponse current HTTP response */ - protected void completeAuthenticationWithActiveMethod(LoginContext loginContext, - AuthenticationMethodInformation authenticationMethod, HttpServletRequest httpRequest, - HttpServletResponse httpResponse) { - Session shibSession = (Session) httpRequest.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE); - - loginContext.setAuthenticationDuration(authenticationMethod.getAuthenticationDuration()); - loginContext.setAuthenticationInstant(authenticationMethod.getAuthenticationInstant()); - loginContext.setAuthenticationMethod(authenticationMethod.getAuthenticationMethod()); - loginContext.setPrincipalAuthenticated(true); - loginContext.setPrincipalName(shibSession.getPrincipalName()); - - ServiceInformation serviceInfo = new ServiceInformationImpl(loginContext.getRelyingPartyId(), new DateTime(), - authenticationMethod); - shibSession.getServicesInformation().put(serviceInfo.getEntityID(), serviceInfo); + protected void authenticateUser(String authnMethod, LoginHandler loginHandler, LoginContext loginContext, + HttpServletRequest httpRequest, HttpServletResponse httpResponse) { + LOG.debug("Authenticating user with login handler of type {}", loginHandler.getClass().getName()); - LOG.debug("Treating user {} as authenticated via existing method {}", loginContext.getPrincipalName(), - loginContext.getAuthenticationMethod()); - returnToProfileHandler(loginContext, httpRequest, httpResponse); + loginContext.setAuthenticationAttempted(); + loginContext.setAuthenticationInstant(new DateTime()); + loginContext.setAuthenticationDuration(loginHandler.getAuthenticationDuration()); + loginContext.setAuthenticationMethod(authnMethod); + loginContext.setAuthenticationEngineURL(HttpHelper.getRequestUriWithoutContext(httpRequest)); + httpRequest.getSession().setAttribute(LoginContext.LOGIN_CONTEXT_KEY, loginContext); + loginHandler.login(httpRequest, httpResponse); } /** - * Completes the authentication process when and already active authentication mechanism wasn't used, that is, when - * the user was really authenticated. + * Completes the authentication process. * * The principal name set by the authentication handler is retrieved and pushed in to the login context, a * Shibboleth session is created if needed, information indicating that the user has logged into the service is @@ -376,25 +385,28 @@ public class AuthenticationEngine extends HttpServlet { * @param httpRequest current HTTP request * @param httpResponse current HTTP response */ - protected void completeAuthenticationWithoutActiveMethod(LoginContext loginContext, HttpServletRequest httpRequest, + protected void completeAuthentication(LoginContext loginContext, HttpServletRequest httpRequest, HttpServletResponse httpResponse) { - String principalName = DatatypeHelper.safeTrimOrNullString((String) httpRequest - .getAttribute(LoginHandler.PRINCIPAL_NAME_KEY)); + // We check if the principal name was already set in the login context + // if not attempt to pull it from where login handlers are supposed to provide it + String principalName = loginContext.getPrincipalName(); if (principalName == null) { - loginContext.setPrincipalAuthenticated(false); - loginContext.setAuthenticationFailure(new AuthenticationException( - "No principal name returned from authentication handler.")); - LOG.error("No principal name returned from authentication method: " - + loginContext.getAuthenticationMethod()); - returnToProfileHandler(loginContext, httpRequest, httpResponse); - return; + DatatypeHelper.safeTrimOrNullString((String) httpRequest.getAttribute(LoginHandler.PRINCIPAL_NAME_KEY)); + if (principalName != null) { + loginContext.setPrincipalName(principalName); + }else{ + loginContext.setPrincipalAuthenticated(false); + loginContext.setAuthenticationFailure(new AuthenticationException( + "No principal name returned from authentication handler.")); + LOG.error("No principal name returned from authentication method: " + + loginContext.getAuthenticationMethod()); + returnToProfileHandler(loginContext, httpRequest, httpResponse); + return; + } } - loginContext.setPrincipalAuthenticated(true); - loginContext.setPrincipalName(principalName); - loginContext.setAuthenticationInstant(new DateTime()); - + // We allow a login handler to override the authentication method in the event that it supports multiple methods String actualAuthnMethod = DatatypeHelper.safeTrimOrNullString((String) httpRequest .getAttribute(LoginHandler.AUTHENTICATION_METHOD_KEY)); @@ -418,12 +430,12 @@ public class AuthenticationEngine extends HttpServlet { */ protected void updateUserSession(LoginContext loginContext, HttpServletRequest httpRequest, HttpServletResponse httpResponse) { - Session shibSession = (Session) httpRequest.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE); - if (shibSession == null) { + Session idpSession = (Session) httpRequest.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE); + if (idpSession == null) { LOG.debug("Creating shibboleth session for principal {}", loginContext.getPrincipalName()); - shibSession = (Session) sessionManager.createSession(loginContext.getPrincipalName()); - loginContext.setSessionID(shibSession.getSessionID()); - addSessionCookie(httpRequest, httpResponse, shibSession); + idpSession = (Session) sessionManager.createSession(loginContext.getPrincipalName()); + loginContext.setSessionID(idpSession.getSessionID()); + addSessionCookie(httpRequest, httpResponse, idpSession); } LOG.debug("Recording authentication and service information in Shibboleth session for principal: {}", @@ -435,13 +447,13 @@ public class AuthenticationEngine extends HttpServlet { } AuthenticationMethodInformation authnMethodInfo = new AuthenticationMethodInformationImpl(subject, authnMethod, - new DateTime(), loginContext.getAuthenticationDuration()); + loginContext.getAuthenticationInstant(), loginContext.getAuthenticationDuration()); - shibSession.getAuthenticationMethods().put(authnMethodInfo.getAuthenticationMethod(), authnMethodInfo); + idpSession.getAuthenticationMethods().put(authnMethodInfo.getAuthenticationMethod(), authnMethodInfo); ServiceInformation serviceInfo = new ServiceInformationImpl(loginContext.getRelyingPartyId(), new DateTime(), authnMethodInfo); - shibSession.getServicesInformation().put(serviceInfo.getEntityID(), serviceInfo); + idpSession.getServicesInformation().put(serviceInfo.getEntityID(), serviceInfo); } /** diff --git a/src/edu/internet2/middleware/shibboleth/idp/authn/provider/PreviousSessionLoginHandler.java b/src/edu/internet2/middleware/shibboleth/idp/authn/provider/PreviousSessionLoginHandler.java new file mode 100644 index 0000000..d0b695c --- /dev/null +++ b/src/edu/internet2/middleware/shibboleth/idp/authn/provider/PreviousSessionLoginHandler.java @@ -0,0 +1,135 @@ +/* + * Copyright 2008 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.provider; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.opensaml.util.URLBuilder; +import org.opensaml.xml.util.DatatypeHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import edu.internet2.middleware.shibboleth.idp.authn.AuthenticationEngine; + +/** + * Login handler that is called when user is logged in under a previously existing session. + * + * This login handler can optionally redirect the browser to a given URL. This provides a mechanism for extensions to + * hook into the authentication process on every request. If this option is used and the servlet to which the browser is + * redirected does not take visible control of the request be sure to indicate passive authentication support by means + * of {@link PreviousSessionLoginHandler#setSupportsPassive(boolean)}. + * + * When the servlet has completed it's work it MUST call + * {@link AuthenticationEngine#returnToAuthenticationEngine(HttpServletRequest, HttpServletResponse)} in order to + * transfer control back to the authentication engine. + */ +public class PreviousSessionLoginHandler extends AbstractLoginHandler { + + /** PreviousSession authentication method URI. */ + public static final String PREVIOUS_SESSION_AUTHN_METHOD = "urn:oasis:names:tc:SAML:2.0:ac:classes:PreviousSession"; + + /** Class logger. */ + private final Logger log = LoggerFactory.getLogger(PreviousSessionLoginHandler.class); + + /** The path of the servlet to which the user agent may be redirected. */ + private String servletPath; + + /** Whether to report the authentication method as PreviousSession. */ + private boolean reportPreviousSessionAuthnMethod; + + /** Constructor. */ + public PreviousSessionLoginHandler() { + super(); + servletPath = null; + } + + /** + * Get the path of the servlet to which the user agent may be redirected. + * + * @return path of the servlet to which the user agent may be redirected + */ + public String getServletPath() { + return servletPath; + } + + /** + * Set the path of the servlet to which the user agent may be redirected. + * + * @param path path of the servlet to which the user agent may be redirected + */ + public void setServletPath(String path) { + servletPath = DatatypeHelper.safeTrimOrNullString(path); + } + + /** + * Gets whether to use PreviousSession as the users authentication method. + * + * @return whether to use PreviousSession as the users authentication method + */ + public boolean reportPreviousSessionAuthnMethod() { + return reportPreviousSessionAuthnMethod; + } + + /** + * Sets whether to use PreviousSession as the users authentication method. + * + * @param report whether to use PreviousSession as the users authentication method + */ + public void setReportPreviousSessionAuthnMethod(boolean report) { + reportPreviousSessionAuthnMethod = report; + } + + /** {@inheritDoc} */ + public boolean supportsPassive() { + if (servletPath == null) { + return true; + } + + return super.supportsPassive(); + } + + /** {@inheritDoc} */ + public void login(HttpServletRequest httpRequest, HttpServletResponse httpResponse) { + if (servletPath == null) { + AuthenticationEngine.returnToAuthenticationEngine(httpRequest, httpResponse); + } else { + try { + StringBuilder pathBuilder = new StringBuilder(); + pathBuilder.append(httpRequest.getContextPath()); + if (!servletPath.startsWith("/")) { + pathBuilder.append("/"); + } + pathBuilder.append(servletPath); + + URLBuilder urlBuilder = new URLBuilder(); + urlBuilder.setScheme(httpRequest.getScheme()); + urlBuilder.setHost(httpRequest.getLocalName()); + urlBuilder.setPort(httpRequest.getLocalPort()); + urlBuilder.setPath(pathBuilder.toString()); + + log.debug("Redirecting to {}", urlBuilder.buildURL()); + httpResponse.sendRedirect(urlBuilder.buildURL()); + return; + } catch (IOException ex) { + log.error("Unable to redirect to previous session authentication servlet.", ex); + } + } + } +} \ No newline at end of file diff --git a/src/edu/internet2/middleware/shibboleth/idp/config/profile/ProfileHandlerNamespaceHandler.java b/src/edu/internet2/middleware/shibboleth/idp/config/profile/ProfileHandlerNamespaceHandler.java index 7249c82..a650933 100644 --- a/src/edu/internet2/middleware/shibboleth/idp/config/profile/ProfileHandlerNamespaceHandler.java +++ b/src/edu/internet2/middleware/shibboleth/idp/config/profile/ProfileHandlerNamespaceHandler.java @@ -21,6 +21,7 @@ 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; +import edu.internet2.middleware.shibboleth.idp.config.profile.authn.PreviousSessionLoginHandlerBeanDefinitionParser; import edu.internet2.middleware.shibboleth.idp.config.profile.authn.RemoteUserLoginHandlerBeanDefinitionParser; import edu.internet2.middleware.shibboleth.idp.config.profile.authn.UsernamePasswordLoginHandlerBeanDefinitionParser; import edu.internet2.middleware.shibboleth.idp.config.profile.saml1.SAML1ArtifactResolutionProfileHanderBeanDefinitionParser; @@ -45,7 +46,7 @@ public class ProfileHandlerNamespaceHandler extends BaseSpringNamespaceHandler { registerBeanDefinitionParser(ProfileHandlerGroupBeanDefinitionParser.SCHEMA_TYPE, new ProfileHandlerGroupBeanDefinitionParser()); - + registerBeanDefinitionParser(StatusHandlerBeanDefinitionParser.SCHEMA_TYPE, new StatusHandlerBeanDefinitionParser()); @@ -60,19 +61,22 @@ public class ProfileHandlerNamespaceHandler extends BaseSpringNamespaceHandler { registerBeanDefinitionParser(SAML1AttributeQueryProfileHandlerBeanDefinitionParser.SCHEMA_TYPE, new SAML1AttributeQueryProfileHandlerBeanDefinitionParser()); - + registerBeanDefinitionParser(SAML1ArtifactResolutionProfileHanderBeanDefinitionParser.SCHEMA_TYPE, new SAML1ArtifactResolutionProfileHanderBeanDefinitionParser()); registerBeanDefinitionParser(SAML2SSOProfileHandlerBeanDefinitionParser.SCHEMA_TYPE, new SAML2SSOProfileHandlerBeanDefinitionParser()); - + registerBeanDefinitionParser(SAML2AttributeQueryProfileHandlerBeanDefinitionParser.SCHEMA_TYPE, new SAML2AttributeQueryProfileHandlerBeanDefinitionParser()); - + registerBeanDefinitionParser(SAML2ArtifactResolutionProfileHandlerBeanDefinitionParser.SCHEMA_TYPE, new SAML2ArtifactResolutionProfileHandlerBeanDefinitionParser()); + registerBeanDefinitionParser(PreviousSessionLoginHandlerBeanDefinitionParser.SCHEMA_TYPE, + new PreviousSessionLoginHandlerBeanDefinitionParser()); + registerBeanDefinitionParser(RemoteUserLoginHandlerBeanDefinitionParser.SCHEMA_TYPE, new RemoteUserLoginHandlerBeanDefinitionParser()); diff --git a/src/edu/internet2/middleware/shibboleth/idp/config/profile/authn/AbstractLoginHandlerFactoryBean.java b/src/edu/internet2/middleware/shibboleth/idp/config/profile/authn/AbstractLoginHandlerFactoryBean.java index 57e7477..d04bb4c 100644 --- a/src/edu/internet2/middleware/shibboleth/idp/config/profile/authn/AbstractLoginHandlerFactoryBean.java +++ b/src/edu/internet2/middleware/shibboleth/idp/config/profile/authn/AbstractLoginHandlerFactoryBean.java @@ -70,7 +70,7 @@ public abstract class AbstractLoginHandlerFactoryBean extends AbstractFactoryBea } /** - * Populates the authenication duration and methods of the handler. + * Populates the authentication duration and methods of the handler. * * @param handler the authentication handler to populate */ diff --git a/src/edu/internet2/middleware/shibboleth/idp/config/profile/authn/PreviousSessionLoginHandlerBeanDefinitionParser.java b/src/edu/internet2/middleware/shibboleth/idp/config/profile/authn/PreviousSessionLoginHandlerBeanDefinitionParser.java new file mode 100644 index 0000000..6b89bfc --- /dev/null +++ b/src/edu/internet2/middleware/shibboleth/idp/config/profile/authn/PreviousSessionLoginHandlerBeanDefinitionParser.java @@ -0,0 +1,54 @@ +/* + * Copyright 2008 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.authn; + +import javax.xml.namespace.QName; + +import org.opensaml.xml.util.DatatypeHelper; +import org.opensaml.xml.util.XMLHelper; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.w3c.dom.Element; + +import edu.internet2.middleware.shibboleth.idp.config.profile.ProfileHandlerNamespaceHandler; + +/** + * Spring bean definition parser for previous session authentication handlers. + */ +public class PreviousSessionLoginHandlerBeanDefinitionParser extends AbstractLoginHandlerBeanDefinitionParser { + + /** Schema type. */ + public static final QName SCHEMA_TYPE = new QName(ProfileHandlerNamespaceHandler.NAMESPACE, "PreviousSession"); + + /** {@inheritDoc} */ + protected Class getBeanClass(Element arg0) { + return PreviousSessionLoginHandlerFactoryBean.class; + } + + /** {@inheritDoc} */ + protected void doParse(Element config, BeanDefinitionBuilder builder) { + super.doParse(config, builder); + + builder.addPropertyValue("servletPath", DatatypeHelper.safeTrimOrNullString(config.getAttributeNS(null, + "servletPath"))); + + builder.addPropertyValue("supportsPassiveAuth", XMLHelper.getAttributeValueAsBoolean(config.getAttributeNodeNS( + null, "supportsPassiveAuthentication"))); + + builder.addPropertyValue("reportPreviousSessionAuthnMethod", XMLHelper.getAttributeValueAsBoolean(config + .getAttributeNodeNS(null, "reportPreviousSessionAuthnMethod"))); + } +} \ No newline at end of file diff --git a/src/edu/internet2/middleware/shibboleth/idp/config/profile/authn/PreviousSessionLoginHandlerFactoryBean.java b/src/edu/internet2/middleware/shibboleth/idp/config/profile/authn/PreviousSessionLoginHandlerFactoryBean.java new file mode 100644 index 0000000..e3f3e79 --- /dev/null +++ b/src/edu/internet2/middleware/shibboleth/idp/config/profile/authn/PreviousSessionLoginHandlerFactoryBean.java @@ -0,0 +1,103 @@ +/* + * Copyright 2008 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.authn; + +import edu.internet2.middleware.shibboleth.idp.authn.provider.PreviousSessionLoginHandler; + +/** + * Spring factory for {@link PreviousSessionLoginHandler}. + */ +public class PreviousSessionLoginHandlerFactoryBean extends AbstractLoginHandlerFactoryBean { + + /** Path to protected servlet. */ + private String servletPath; + + /** Whether the login handler supports passive authentication. */ + private boolean supportPassiveAuth; + + /** Whether the login handler will report its authentication method as PreviousSession. */ + private boolean reportPreviousSessionAuthnMethod; + + /** {@inheritDoc} */ + public Class getObjectType() { + return PreviousSessionLoginHandler.class; + } + + /** + * Gets the path of the servlet to which the user agent may be redirected. + * + * @return path of the servlet to which the user agent may be redirected + */ + public String getServletPath() { + return servletPath; + } + + /** + * Sets the path of the servlet to which the user agent may be redirected. + * + * @param path path of the servlet to which the user agent may be redirected + */ + public void setServletPath(String path) { + servletPath = path; + } + + /** + * Gets whether the login handler supports passive authentication. + * + * @return whether the login handler supports passive authentication + */ + public boolean supportsPassiveAuth() { + return supportPassiveAuth; + } + + /** + * Sets whether the login handler supports passive authentication. + * + * @param supported whether the login handler supports passive authentication + */ + public void setSupportsPassiveAuth(boolean supported) { + supportPassiveAuth = supported; + } + + /** + * Gets whether the login handler will report its authentication method as PreviousSession. + * + * @return whether the login handler will report its authentication method as PreviousSession + */ + public boolean reportPreviousSessionAuthnMethod() { + return reportPreviousSessionAuthnMethod; + } + + /** + * Sets whether the login handler will report its authentication method as PreviousSession. + * + * @param report whether the login handler will report its authentication method as PreviousSession + */ + public void setReportPreviousSessionAuthnMethod(boolean report) { + reportPreviousSessionAuthnMethod = report; + } + + /** {@inheritDoc} */ + protected Object createInstance() throws Exception { + PreviousSessionLoginHandler handler = new PreviousSessionLoginHandler(); + handler.setServletPath(getServletPath()); + handler.setSupportsPassive(supportsPassiveAuth()); + handler.setReportPreviousSessionAuthnMethod(reportPreviousSessionAuthnMethod()); + populateHandler(handler); + return handler; + } +} \ No newline at end of file -- 1.7.10.4