From 517f94bd97d275d6c64cdcb6015aca31c11559fa Mon Sep 17 00:00:00 2001 From: "Marvin S. Addison" Date: Thu, 1 Aug 2013 14:05:01 -0400 Subject: [PATCH] CASC-174 Provide facility for Servlet 3.0 programmatic JAAS login. Servlet3AuthenticationFilter supersede the JBoss-specific WebAuthenticationFilter for JBoss 7. It should also provide support for programmatic JAAS login for any container that is Servlet 3.0/JEE6 compliant. --- .../jaas/Servlet3AuthenticationFilter.java | 90 +++++++++++++++++++ pom.xml | 4 +- 2 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 cas-client-core/src/main/java/org/jasig/cas/client/jaas/Servlet3AuthenticationFilter.java diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/Servlet3AuthenticationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/jaas/Servlet3AuthenticationFilter.java new file mode 100644 index 0000000..b2dddf8 --- /dev/null +++ b/cas-client-core/src/main/java/org/jasig/cas/client/jaas/Servlet3AuthenticationFilter.java @@ -0,0 +1,90 @@ +/* + * Licensed to Jasig under one or more contributor license + * agreements. See the NOTICE file distributed with this work + * for additional information regarding copyright ownership. + * Jasig licenses this file to you 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 the following location: + * + * 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 org.jasig.cas.client.jaas; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.jasig.cas.client.util.AbstractCasFilter; +import org.jasig.cas.client.util.CommonUtils; + +/** + * Servlet filter performs a programmatic JAAS login using the Servlet 3.0 HttpServletRequest#login() facility. + * This component should be compatible with any servlet container that supports the Servlet 3.0/JEE6 specification. + *

+ * The filter executes when it receives a CAS ticket and expects the + * {@link CasLoginModule} JAAS module to perform the CAS + * ticket validation in order to produce an {@link org.jasig.cas.client.jaas.AssertionPrincipal} from which + * the CAS assertion is obtained and inserted into the session to enable SSO. + *

+ * If a service init-param is specified for this filter, it supersedes + * the service defined for the {@link CasLoginModule}. + * + * @author Daniel Fisher + * @author Marvin S. Addison + * @version $Revision$ + * @since 3.3 + */ +public final class Servlet3AuthenticationFilter extends AbstractCasFilter { + + public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, + final FilterChain chain) throws IOException, ServletException { + final HttpServletRequest request = (HttpServletRequest) servletRequest; + final HttpServletResponse response = (HttpServletResponse) servletResponse; + final HttpSession session = request.getSession(); + final String ticket = CommonUtils.safeGetParameter(request, getArtifactParameterName()); + + if (session != null && session.getAttribute(CONST_CAS_ASSERTION) == null && ticket != null) { + try { + final String service = constructServiceUrl(request, response); + logger.debug("Attempting CAS ticket validation with service={} and ticket={}", service, ticket); + request.login(service, ticket); + if (request.getUserPrincipal() instanceof AssertionPrincipal) { + final AssertionPrincipal principal = (AssertionPrincipal) request.getUserPrincipal(); + logger.debug("Installing CAS assertion into session."); + request.getSession().setAttribute(CONST_CAS_ASSERTION, principal.getAssertion()); + } else { + logger.debug("Aborting -- principal is not of type AssertionPrincipal"); + throw new GeneralSecurityException( + "JBoss Web authentication did not produce CAS AssertionPrincipal."); + } + } catch (final ServletException e) { + logger.debug("JAAS authentication failed."); + response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); + } catch (final GeneralSecurityException e) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); + } + } else if (session != null && request.getUserPrincipal() == null) { + // There is evidence that in some cases the principal can disappear + // in JBoss despite a valid session. + // This block forces consistency between principal and assertion. + logger.info("User principal not found. Removing CAS assertion from session to force re-authentication."); + session.removeAttribute(CONST_CAS_ASSERTION); + } + chain.doFilter(request, response); + } +} diff --git a/pom.xml b/pom.xml index b14e3f9..3630145 100644 --- a/pom.xml +++ b/pom.xml @@ -183,8 +183,8 @@ javax.servlet - servlet-api - 2.4 + javax.servlet-api + 3.0.1 provided