From aa2999caecc916879808840a3e6e2fcd03ebdaa2 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Wed, 9 Sep 2009 20:54:10 +0000 Subject: [PATCH] SEC-1238: Removed portlet module --- portlet/pom.xml | 45 -- .../portlet/PortletAuthenticationDetails.java | 35 -- ...PreAuthenticatedAuthenticationDetails.java | 35 -- ...henticatedAuthenticationDetailsSource.java | 30 -- .../portlet/PortletProcessingInterceptor.java | 352 ------------- ...tSessionContextIntegrationInterceptor.java | 476 ------------------ .../security/portlet/package.html | 5 - .../PortletProcessingInterceptorTests.java | 279 ---------- ...ionContextIntegrationInterceptorTests.java | 344 ------------- .../security/portlet/PortletTestUtils.java | 110 ---- 10 files changed, 1711 deletions(-) delete mode 100644 portlet/pom.xml delete mode 100644 portlet/src/main/java/org/springframework/security/portlet/PortletAuthenticationDetails.java delete mode 100644 portlet/src/main/java/org/springframework/security/portlet/PortletPreAuthenticatedAuthenticationDetails.java delete mode 100644 portlet/src/main/java/org/springframework/security/portlet/PortletPreAuthenticatedAuthenticationDetailsSource.java delete mode 100644 portlet/src/main/java/org/springframework/security/portlet/PortletProcessingInterceptor.java delete mode 100644 portlet/src/main/java/org/springframework/security/portlet/PortletSessionContextIntegrationInterceptor.java delete mode 100644 portlet/src/main/java/org/springframework/security/portlet/package.html delete mode 100644 portlet/src/test/java/org/springframework/security/portlet/PortletProcessingInterceptorTests.java delete mode 100644 portlet/src/test/java/org/springframework/security/portlet/PortletSessionContextIntegrationInterceptorTests.java delete mode 100644 portlet/src/test/java/org/springframework/security/portlet/PortletTestUtils.java diff --git a/portlet/pom.xml b/portlet/pom.xml deleted file mode 100644 index c2d0a109a4..0000000000 --- a/portlet/pom.xml +++ /dev/null @@ -1,45 +0,0 @@ - - 4.0.0 - - org.springframework.security - spring-security-parent - 3.0.0.CI-SNAPSHOT - - spring-security-portlet - Spring Security - Portlet support - Spring Security - Support for JSR 168 Portlets - - - - org.springframework.security - spring-security-web - ${project.version} - - - javax.servlet - servlet-api - - - javax.portlet - portlet-api - 2.0 - provided - - - org.springframework - spring-webmvc-portlet - ${spring.version} - - - org.springframework - spring-test - ${spring.version} - test - - - net.sf.ehcache - ehcache - - - - diff --git a/portlet/src/main/java/org/springframework/security/portlet/PortletAuthenticationDetails.java b/portlet/src/main/java/org/springframework/security/portlet/PortletAuthenticationDetails.java deleted file mode 100644 index b1ec7f2cba..0000000000 --- a/portlet/src/main/java/org/springframework/security/portlet/PortletAuthenticationDetails.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.springframework.security.portlet; - -import java.io.Serializable; -import java.util.Map; - -import javax.portlet.PortletRequest; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -@SuppressWarnings("unchecked") -public class PortletAuthenticationDetails implements Serializable { - //~ Instance fields ================================================================================================ - protected final Log logger = LogFactory.getLog(PortletAuthenticationDetails.class); - - protected Map userInfo; - - //~ Constructors =================================================================================================== - - public PortletAuthenticationDetails(PortletRequest request) { - try { - userInfo = (Map)request.getAttribute(PortletRequest.USER_INFO); - } catch (Exception e) { - logger.warn("unable to retrieve USER_INFO map from portlet request", e); - } - } - - public Map getUserInfo() { - return userInfo; - } - - public String toString() { - return "User info: " + userInfo; - } -} diff --git a/portlet/src/main/java/org/springframework/security/portlet/PortletPreAuthenticatedAuthenticationDetails.java b/portlet/src/main/java/org/springframework/security/portlet/PortletPreAuthenticatedAuthenticationDetails.java deleted file mode 100644 index 4e73b276e0..0000000000 --- a/portlet/src/main/java/org/springframework/security/portlet/PortletPreAuthenticatedAuthenticationDetails.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.springframework.security.portlet; - -import java.util.Collections; -import java.util.List; - -import javax.portlet.PortletRequest; - -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.MutableGrantedAuthoritiesContainer; -import org.springframework.util.Assert; - -public class PortletPreAuthenticatedAuthenticationDetails extends PortletAuthenticationDetails implements MutableGrantedAuthoritiesContainer { - - private List preAuthenticatedGrantedAuthorities = null; - - public PortletPreAuthenticatedAuthenticationDetails(PortletRequest request) { - super(request); - } - - public List getGrantedAuthorities() { - Assert.notNull(preAuthenticatedGrantedAuthorities, "Pre-authenticated granted authorities have not been set"); - return preAuthenticatedGrantedAuthorities; - } - - public void setGrantedAuthorities(List authorities) { - this.preAuthenticatedGrantedAuthorities = Collections.unmodifiableList(authorities); - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(super.toString() + "; "); - sb.append("preAuthenticatedGrantedAuthorities: " + preAuthenticatedGrantedAuthorities); - return sb.toString(); - } -} diff --git a/portlet/src/main/java/org/springframework/security/portlet/PortletPreAuthenticatedAuthenticationDetailsSource.java b/portlet/src/main/java/org/springframework/security/portlet/PortletPreAuthenticatedAuthenticationDetailsSource.java deleted file mode 100644 index 8af18efe49..0000000000 --- a/portlet/src/main/java/org/springframework/security/portlet/PortletPreAuthenticatedAuthenticationDetailsSource.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.springframework.security.portlet; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Set; - -import javax.portlet.PortletRequest; - -import org.springframework.security.web.authentication.preauth.j2ee.AbstractPreAuthenticatedAuthenticationDetailsSource; - -public class PortletPreAuthenticatedAuthenticationDetailsSource extends AbstractPreAuthenticatedAuthenticationDetailsSource { - - public PortletPreAuthenticatedAuthenticationDetailsSource() { - setClazz(PortletPreAuthenticatedAuthenticationDetails.class); - } - - protected Collection getUserRoles(Object context, Set mappableRoles) { - ArrayList portletRoles = new ArrayList(); - - for (String role : mappableRoles) { - if (((PortletRequest)context).isUserInRole(role)) { - portletRoles.add(role); - } - } - portletRoles.trimToSize(); - - return portletRoles; - } - -} diff --git a/portlet/src/main/java/org/springframework/security/portlet/PortletProcessingInterceptor.java b/portlet/src/main/java/org/springframework/security/portlet/PortletProcessingInterceptor.java deleted file mode 100644 index 030691ffc4..0000000000 --- a/portlet/src/main/java/org/springframework/security/portlet/PortletProcessingInterceptor.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright 2005-2007 the original author or authors. - * - * 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 org.springframework.security.portlet; - -import java.io.IOException; -import java.security.Principal; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.portlet.ActionRequest; -import javax.portlet.ActionResponse; -import javax.portlet.EventRequest; -import javax.portlet.EventResponse; -import javax.portlet.PortletRequest; -import javax.portlet.PortletResponse; -import javax.portlet.PortletSession; -import javax.portlet.RenderRequest; -import javax.portlet.RenderResponse; -import javax.portlet.ResourceRequest; -import javax.portlet.ResourceResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.security.authentication.AuthenticationDetailsSource; -import org.springframework.security.authentication.AuthenticationDetailsSourceImpl; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; -import org.springframework.util.Assert; -import org.springframework.web.portlet.HandlerInterceptor; -import org.springframework.web.portlet.ModelAndView; - -/** - *

This interceptor is responsible for processing portlet authentication requests. This - * is the portlet equivalent of the UsernamePasswordAuthenticationProcessingFilter used for - * traditional servlet-based web applications. It is applied to both ActionRequests - * and RenderRequests alike. If authentication is successful, the resulting - * {@link Authentication} object will be placed into the SecurityContext, which - * is guaranteed to have already been created by an earlier interceptor. If authentication - * fails, the AuthenticationException will be placed into the - * APPLICATION_SCOPE of the PortletSession with the attribute defined - * by {@link AbstractAuthenticationProcessingFilter#SPRING_SECURITY_LAST_EXCEPTION_KEY}.

- * - *

Some portals do not properly provide the identity of the current user via the - * getRemoteUser() or getUserPrincipal() methods of the - * PortletRequest. In these cases they sometimes make it available in the - * USER_INFO map provided as one of the attributes of the request. If this is - * the case in your portal, you can specify a list of USER_INFO attributes - * to check for the username via the userNameAttributes property of this bean. - * You can also completely override the {@link #getPrincipalFromRequest(PortletRequest)} - * and {@link #getCredentialsFromRequest(PortletRequest)} methods to suit the particular - * behavior of your portal.

- * - *

This interceptor will put the PortletRequest object into the - * details property of the Authentication object that is sent - * as a request to the AuthenticationManager. - * - * @see org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter - * @see org.springframework.security.web.authentication.UsernamePasswordAuthenticationProcessingFilter - * @author John A. Lewis - * @since 2.0 - * @version $Id$ - */ -@SuppressWarnings("unchecked") -public class PortletProcessingInterceptor implements HandlerInterceptor, InitializingBean { - - //~ Static fields/initializers ===================================================================================== - - private static final Log logger = LogFactory.getLog(PortletProcessingInterceptor.class); - - //~ Instance fields ================================================================================================ - - private AuthenticationManager authenticationManager; - - private List userNameAttributes; - - private AuthenticationDetailsSource authenticationDetailsSource; - - private boolean useAuthTypeAsCredentials = false; - - public PortletProcessingInterceptor() { - authenticationDetailsSource = new AuthenticationDetailsSourceImpl(); - ((AuthenticationDetailsSourceImpl)authenticationDetailsSource).setClazz(PortletAuthenticationDetails.class); - } - - //~ Methods ======================================================================================================== - - public void afterPropertiesSet() throws Exception { - Assert.notNull(authenticationManager, "An AuthenticationManager must be set"); - } - - public boolean preHandleAction(ActionRequest request, ActionResponse response, - Object handler) throws Exception { - return preHandle(request, response, handler); - } - - public boolean preHandleRender(RenderRequest request, - RenderResponse response, Object handler) throws Exception { - return preHandle(request, response, handler); - } - - public void postHandleRender(RenderRequest request, RenderResponse response, - Object handler, ModelAndView modelAndView) throws Exception { - } - - public void afterActionCompletion(ActionRequest request, ActionResponse response, - Object handler, Exception ex) throws Exception { - } - - public void afterRenderCompletion(RenderRequest request, RenderResponse response, - Object handler, Exception ex) throws Exception { - } - - /** - * {@inheritDoc} - */ - public boolean preHandleResource(ResourceRequest request, ResourceResponse response, Object handler) throws Exception { - return preHandle(request, response, handler); - } - - /** - * {@inheritDoc} - */ - public void postHandleResource(ResourceRequest request, ResourceResponse response, Object handler, ModelAndView modelAndView) throws Exception { - } - - public void afterResourceCompletion(ResourceRequest request, ResourceResponse response, Object handler, Exception ex) throws Exception { - } - - /** - * {@inheritDoc} - */ - public boolean preHandleEvent(EventRequest request, EventResponse response, Object handler) throws Exception { - return preHandle(request, response, handler); - } - - /** - * {@inheritDoc} - */ - public void afterEventCompletion(EventRequest request, EventResponse response, Object handler, Exception ex) throws Exception { - } - - /** - * Common preHandle method for both the action and render phases of the interceptor. - */ - private boolean preHandle(PortletRequest request, PortletResponse response, - Object handler) throws Exception { - - // get the SecurityContext - SecurityContext ctx = SecurityContextHolder.getContext(); - - if (logger.isDebugEnabled()) - logger.debug("Checking secure context token: " + ctx.getAuthentication()); - - // if there is no existing Authentication object, then lets create one - if (ctx.getAuthentication() == null) { - - try { - - // build the authentication request from the PortletRequest - PreAuthenticatedAuthenticationToken authRequest = new PreAuthenticatedAuthenticationToken( - getPrincipalFromRequest(request), - getCredentialsFromRequest(request)); - - // put the PortletRequest into the authentication request as the "details" - authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); - - if (logger.isDebugEnabled()) - logger.debug("Beginning authentication request for user '" + authRequest.getName() + "'"); - - onPreAuthentication(request, response); - - // ask the authentication manager to authenticate the request - // it will throw an AuthenticationException if it fails, otherwise it succeeded - Authentication authResult = authenticationManager.authenticate(authRequest); - - // process a successful authentication - if (logger.isDebugEnabled()) { - logger.debug("Authentication success: " + authResult); - } - - ctx.setAuthentication(authResult); - onSuccessfulAuthentication(request, response, authResult); - - } catch (AuthenticationException failed) { - // process an unsuccessful authentication - if (logger.isDebugEnabled()) { - logger.debug("Authentication failed - updating ContextHolder to contain null Authentication", failed); - } - ctx.setAuthentication(null); - request.getPortletSession().setAttribute( - AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, - failed, PortletSession.APPLICATION_SCOPE); - onUnsuccessfulAuthentication(request, response, failed); - } - } - - return true; - } - - /** - * This method attempts to extract a principal from the portlet request. - * According to the JSR 168 spec, the PortletRequest should return the name - * of the user in the getRemoteUser() method. It should also provide a - * java.security.Principal object from the getUserPrincipal() - * method. We will first try these to come up with a valid username. - *

Unfortunately, some portals do not properly return these values for authenticated - * users. So, if neither of those succeeds and if the userNameAttributes - * property has been populated, then we will search through the USER_INFO - * map from the request to see if we can find a valid username. - *

This method can be overridden by subclasses to provide special handling - * for portals with weak support for the JSR 168 spec.

- * @param request the portlet request object - * @return the determined principal object, or null if none found - */ - protected Object getPrincipalFromRequest(PortletRequest request) { - - // first try getRemoteUser() - String remoteUser = request.getRemoteUser(); - if (remoteUser != null) { - return remoteUser; - } - - // next try getUserPrincipal() - Principal userPrincipal = request.getUserPrincipal(); - if (userPrincipal != null) { - String userPrincipalName = userPrincipal.getName(); - if (userPrincipalName != null) { - return userPrincipalName; - } - } - - // last try entries in USER_INFO if any attributes were defined - if (this.userNameAttributes != null) { - Map userInfo = null; - try { - userInfo = (Map)request.getAttribute(PortletRequest.USER_INFO); - } catch (Exception e) { - logger.warn("unable to retrieve USER_INFO map from portlet request", e); - } - if (userInfo != null) { - Iterator i = this.userNameAttributes.iterator(); - while(i.hasNext()) { - Object principal = (String)userInfo.get(i.next()); - if (principal != null) { - return principal; - } - } - } - } - - // none found so return null - return null; - } - - /** - * This method attempts to extract a credentials from the portlet request. - * We are trusting the portal framework to authenticate the user, so all - * we are really doing is trying to put something intelligent in here to - * indicate the user is authenticated. According to the JSR 168 spec, - * PortletRequest.getAuthType() should return a non-null value if the - * user is authenticated and should be null if not authenticated. So we - * will use this as the credentials and the token will be trusted as - * authenticated if the credentials are not null. - *

This method can be overridden by subclasses to provide special handling - * for portals with weak support for the JSR 168 spec. If that is done, - * be sure the value is non-null for authenticated users and null for - * non-authenticated users.

- * @param request the portlet request object - * @return the determined credentials object, or null if none found - */ - protected Object getCredentialsFromRequest(PortletRequest request) { - if (useAuthTypeAsCredentials) { - return request.getAuthType(); - } - - return "dummy"; - } - - /** - * Callback for custom processing prior to the authentication attempt. - * @param request the portlet request to be authenticated - * @param response the portlet response to be authenticated - * @throws AuthenticationException to indicate that authentication attempt is not valid and should be terminated - * @throws IOException - */ - protected void onPreAuthentication(PortletRequest request, PortletResponse response) - throws AuthenticationException, IOException {} - - /** - * Callback for custom processing after a successful authentication attempt. - * @param request the portlet request that was authenticated - * @param response the portlet response that was authenticated - * @param authResult the resulting Authentication object - * @throws IOException - */ - protected void onSuccessfulAuthentication(PortletRequest request, PortletResponse response, Authentication authResult) - throws IOException {} - - /** - * Callback for custom processing after an unsuccessful authentication attempt. - * @param request the portlet request that failed authentication - * @param response the portlet response that failed authentication - * @param failed the AuthenticationException that occurred - * @throws IOException - */ - protected void onUnsuccessfulAuthentication(PortletRequest request, PortletResponse response, AuthenticationException failed) - throws IOException {} - - - public void setAuthenticationManager(AuthenticationManager authenticationManager) { - this.authenticationManager = authenticationManager; - } - - public void setUserNameAttributes(List userNameAttributes) { - this.userNameAttributes = userNameAttributes; - } - - public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) { - this.authenticationDetailsSource = authenticationDetailsSource; - } - - /** - * It true, the "authType" proerty of the PortletRequest will be used as the credentials. - * Defaults to false. - * - * @param useAuthTypeAsCredentials - */ - public void setUseAuthTypeAsCredentials(boolean useAuthTypeAsCredentials) { - this.useAuthTypeAsCredentials = useAuthTypeAsCredentials; - } -} diff --git a/portlet/src/main/java/org/springframework/security/portlet/PortletSessionContextIntegrationInterceptor.java b/portlet/src/main/java/org/springframework/security/portlet/PortletSessionContextIntegrationInterceptor.java deleted file mode 100644 index ed99c2f8d7..0000000000 --- a/portlet/src/main/java/org/springframework/security/portlet/PortletSessionContextIntegrationInterceptor.java +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright 2005-2007 the original author or authors. - * - * 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 org.springframework.security.portlet; - -import java.lang.reflect.Method; - -import javax.portlet.ActionRequest; -import javax.portlet.ActionResponse; -import javax.portlet.EventRequest; -import javax.portlet.EventResponse; -import javax.portlet.PortletException; -import javax.portlet.PortletRequest; -import javax.portlet.PortletResponse; -import javax.portlet.PortletSession; -import javax.portlet.RenderRequest; -import javax.portlet.RenderResponse; -import javax.portlet.ResourceRequest; -import javax.portlet.ResourceResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.context.HttpSessionSecurityContextRepository; -import org.springframework.security.web.context.SecurityContextPersistenceFilter; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.portlet.HandlerInterceptor; -import org.springframework.web.portlet.ModelAndView; - -/** - *

This interceptor populates the {@link SecurityContextHolder} with information obtained from the - * PortletSession. It is applied to both ActionRequests and - * RenderRequests

- * - *

The PortletSession will be queried to retrieve the SecurityContext that should - * be stored against the SecurityContextHolder for the duration of the portlet request. At the - * end of the request, any updates made to the SecurityContextHolder will be persisted back to the - * PortletSession by this interceptor.

- * - *

If a valid SecurityContext cannot be obtained from the PortletSession for - * whatever reason, a fresh SecurityContext will be created and used instead. The created object - * will be of the instance defined by the {@link #setContext(Class)} method. If this hasn't been set, a call to - * {@link SecurityContextHolder#createEmptyContext()} will be used to create the instance. - * - *

A PortletSession may be created by this interceptor if one does not already exist. If at the - * end of the portlet request the PortletSession does not exist, one will only be created if - * the current contents of the SecurityContextHolder are not the {@link java.lang.Object#equals} - * to a new instance of {@link #contextClass}. This avoids needless PortletSession creation, - * and automates the storage of changes made to the SecurityContextHolder. There is one exception to - * this rule, that is if the {@link #forceEagerSessionCreation} property is true, in which case - * sessions will always be created irrespective of normal session-minimization logic (the default is - * false, as this is resource intensive and not recommended).

- * - *

If for whatever reason no PortletSession should ever be created, the - * {@link #allowSessionCreation} property should be set to false. Only do this if you really need - * to conserve server memory and ensure all classes using the SecurityContextHolder are designed to - * have no persistence of the SecurityContext between web requests. Please note that if - * {@link #forceEagerSessionCreation} is true, the allowSessionCreation must also be - * true (setting it to false will cause a startup-time error).

- - *

This interceptor must be executed before

any authentication processing mechanisms. These - * mechanisms (specifically {@link org.springframework.security.portlet.PortletProcessingInterceptor}) expect the - * SecurityContextHolder to contain a valid SecurityContext by the time they execute.

- * - *

An important nuance to this interceptor is that (by default) the SecurityContext is stored - * into the APPLICATION_SCOPE of the PortletSession. This doesn't just mean you will be - * sharing it with all the other portlets in your webapp (which is generally a good idea). It also means that (if - * you have done all the other appropriate magic), you will share this SecurityContext with servlets in - * your webapp. This is very useful if you have servlets serving images or processing AJAX calls from your portlets - * since they can now use the {@link SecurityContextPersistenceFilter} to access the same SecurityContext - * object from the session. This allows these calls to be secured as well as the portlet calls.

- * - * Much of the logic of this interceptor comes from the {@link SecurityContextPersistenceFilter} class which - * fills the same purpose on the servlet side. Ben Alex and Patrick Burlson are listed as authors here because they - * are the authors of that class and there are blocks of code that essentially identical between the two. (Making this - * a good candidate for refactoring someday.) - * - *

Unlike HttpSessionContextIntegrationFilter, this interceptor does not check to see if it is - * getting applied multiple times. This shouldn't be a problem since the application of interceptors is under the - * control of the Spring Portlet MVC framework and tends to be more explicit and more predictable than the application - * of filters. However, you should still be careful to only apply this inteceptor to your request once.

- * - * @author John A. Lewis - * @author Ben Alex - * @author Patrick Burleson - * @since 2.0 - * @version $Id$ - */ -public class PortletSessionContextIntegrationInterceptor implements InitializingBean, HandlerInterceptor { - - //~ Static fields/initializers ===================================================================================== - - protected static final Log logger = LogFactory.getLog(PortletSessionContextIntegrationInterceptor.class); - - public static final String SPRING_SECURITY_CONTEXT_KEY = HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY; - - private static final String SESSION_EXISTED = PortletSessionContextIntegrationInterceptor.class.getName() + ".SESSION_EXISTED"; - private static final String CONTEXT_HASHCODE = PortletSessionContextIntegrationInterceptor.class.getName() + ".CONTEXT_HASHCODE"; - - //~ Instance fields ================================================================================================ - - private Class contextClass; - - private Object contextObject; - - /** - * Indicates if this interceptor can create a PortletSession if - * needed (sessions are always created sparingly, but setting this value to - * false will prohibit sessions from ever being created). - * Defaults to true. Do not set to false if - * you are have set {@link #forceEagerSessionCreation} to true, - * as the properties would be in conflict. - */ - private boolean allowSessionCreation = true; - - /** - * Indicates if this interceptor is required to create a PortletSession - * for every request before proceeding through the request process, even if the - * PortletSession would not ordinarily have been created. By - * default this is false, which is entirely appropriate for - * most circumstances as you do not want a PortletSession - * created unless the interceptor actually needs one. It is envisaged the main - * situation in which this property would be set to true is - * if using other interceptors that depend on a PortletSession - * already existing. This is only required in specialized cases, so leave it set to - * false unless you have an actual requirement and aware of the - * session creation overhead. - */ - private boolean forceEagerSessionCreation = false; - - /** - * Indicates whether the SecurityContext will be cloned from - * the PortletSession. The default is to simply reference - * (the default is false). The default may cause issues if - * concurrent threads need to have a different security identity from other - * threads being concurrently processed that share the same - * PortletSession. In most normal environments this does not - * represent an issue, as changes to the security identity in one thread is - * allowed to affect the security identity in other threads associated with - * the same PortletSession. For unusual cases where this is not - * permitted, change this value to true and ensure the - * {@link #contextClass} is set to a SecurityContext that - * implements {@link Cloneable} and overrides the clone() - * method. - */ - private boolean cloneFromPortletSession = false; - - /** - * Indicates wether the APPLICATION_SCOPE mode of the - * PortletSession should be used for storing the - * SecurityContext. The default is
true
. - * This allows it to be shared between the portlets in the webapp and - * potentially with servlets in the webapp as well. If this is set to - * false, then the PORTLET_SCOPE will be used - * instead. - */ - private boolean useApplicationScopePortletSession = true; - - - //~ Constructors =================================================================================================== - - public PortletSessionContextIntegrationInterceptor() throws PortletException { - this.contextObject = generateNewContext(); - } - - //~ Methods ======================================================================================================== - - public void afterPropertiesSet() throws Exception { - // check that session creation options make sense - if ((forceEagerSessionCreation == true) && (allowSessionCreation == false)) { - throw new IllegalArgumentException( - "If using forceEagerSessionCreation, you must set allowSessionCreation to also be true"); - } - } - - public boolean preHandleAction(ActionRequest request, ActionResponse response, - Object handler) throws Exception { - // call to common preHandle method - return preHandle(request, response, handler); - } - - public boolean preHandleRender(RenderRequest request, RenderResponse response, - Object handler) throws Exception { - // call to common preHandle method - return preHandle(request, response, handler); - } - - public void postHandleRender(RenderRequest request, RenderResponse response, - Object handler, ModelAndView modelAndView) throws Exception { - // no-op - } - - public void afterActionCompletion(ActionRequest request, ActionResponse response, - Object handler, Exception ex) throws Exception { - // call to common afterCompletion method - afterCompletion(request, response, handler, ex); - } - - public void afterRenderCompletion(RenderRequest request, RenderResponse response, - Object handler, Exception ex) throws Exception { - // call to common afterCompletion method - afterCompletion(request, response, handler, ex); - } - - /** - * {@inheritDoc} - */ - public boolean preHandleResource(ResourceRequest request, ResourceResponse response, Object handler) throws Exception { - return preHandle(request, response, handler); - } - - /** - * {@inheritDoc} - */ - public void postHandleResource(ResourceRequest request, ResourceResponse response, Object handler, ModelAndView modelAndView) throws Exception { - // no-op - } - - /** - * {@inheritDoc} - */ - public void afterResourceCompletion(ResourceRequest request, ResourceResponse response, Object handler, Exception ex) throws Exception { - // call to common afterCompletion method - afterCompletion(request, response, handler, ex); - } - - /** - * {@inheritDoc} - */ - public boolean preHandleEvent(EventRequest request, EventResponse response, Object handler) throws Exception { - return preHandle(request, response, handler); - } - - /** - * {@inheritDoc} - */ - public void afterEventCompletion(EventRequest request, EventResponse response, Object handler, Exception ex) throws Exception { - // call to common afterCompletion method - afterCompletion(request, response, handler, ex); - } - - private boolean preHandle(PortletRequest request, PortletResponse response, - Object handler) throws Exception { - - PortletSession portletSession = null; - boolean portletSessionExistedAtStartOfRequest = false; - - // see if the portlet session already exists (or should be eagerly created) - try { - portletSession = request.getPortletSession(forceEagerSessionCreation); - } catch (IllegalStateException ignored) {} - - // if there is a session, then see if there is a contextClass to bring in - if (portletSession != null) { - - // remember that the session already existed - portletSessionExistedAtStartOfRequest = true; - - // attempt to retrieve the contextClass from the session - Object contextFromSessionObject = portletSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY, portletSessionScope()); - - // if we got a contextClass then place it into the holder - if (contextFromSessionObject != null) { - - // if we are supposed to clone it, then do so - if (cloneFromPortletSession) { - Assert.isInstanceOf(Cloneable.class, contextFromSessionObject, - "Context must implement Clonable and provide a Object.clone() method"); - try { - Method m = contextFromSessionObject.getClass().getMethod("clone", new Class[] {}); - if (!m.isAccessible()) { - m.setAccessible(true); - } - contextFromSessionObject = m.invoke(contextFromSessionObject, new Object[] {}); - } - catch (Exception ex) { - ReflectionUtils.handleReflectionException(ex); - } - } - - // if what we got is a valid contextClass then place it into the holder, otherwise create a new one - if (contextFromSessionObject instanceof SecurityContext) { - if (logger.isDebugEnabled()) - logger.debug("Obtained from SPRING_SECURITY_CONTEXT a valid SecurityContext and " - + "set to SecurityContextHolder: '" + contextFromSessionObject + "'"); - SecurityContextHolder.setContext((SecurityContext) contextFromSessionObject); - } else { - if (logger.isWarnEnabled()) - logger.warn("SPRING_SECURITY_CONTEXT did not contain a SecurityContext but contained: '" - + contextFromSessionObject - + "'; are you improperly modifying the PortletSession directly " - + "(you should always use SecurityContextHolder) or using the PortletSession attribute " - + "reserved for this class? - new SecurityContext instance associated with " - + "SecurityContextHolder"); - SecurityContextHolder.setContext(generateNewContext()); - } - - } else { - - // there was no contextClass in the session, so create a new contextClass and put it in the holder - if (logger.isDebugEnabled()) - logger.debug("PortletSession returned null object for SPRING_SECURITY_CONTEXT - new " - + "SecurityContext instance associated with SecurityContextHolder"); - SecurityContextHolder.setContext(generateNewContext()); - } - - } else { - - // there was no session, so create a new contextClass and place it in the holder - if (logger.isDebugEnabled()) - logger.debug("No PortletSession currently exists - new SecurityContext instance " - + "associated with SecurityContextHolder"); - SecurityContextHolder.setContext(generateNewContext()); - - } - - // place attributes onto the request to remember if the session existed and the hashcode of the contextClass - request.setAttribute(SESSION_EXISTED, new Boolean(portletSessionExistedAtStartOfRequest)); - request.setAttribute(CONTEXT_HASHCODE, new Integer(SecurityContextHolder.getContext().hashCode())); - - return true; - } - - private void afterCompletion(PortletRequest request, PortletResponse response, - Object handler, Exception ex) throws Exception { - - PortletSession portletSession = null; - - // retrieve the attributes that remember if the session existed and the hashcode of the contextClass - boolean portletSessionExistedAtStartOfRequest = ((Boolean)request.getAttribute(SESSION_EXISTED)).booleanValue(); - int oldContextHashCode = ((Integer)request.getAttribute(CONTEXT_HASHCODE)).intValue(); - - // try to retrieve an existing portlet session - try { - portletSession = request.getPortletSession(false); - } catch (IllegalStateException ignored) {} - - // if there is now no session but there was one at the beginning then it must have been invalidated - if ((portletSession == null) && portletSessionExistedAtStartOfRequest) { - if (logger.isDebugEnabled()) - logger.debug("PortletSession is now null, but was not null at start of request; " - + "session was invalidated, so do not create a new session"); - } - - // create a new portlet session if we need to - if ((portletSession == null) && !portletSessionExistedAtStartOfRequest) { - - // if we're not allowed to create a new session, then report that - if (!allowSessionCreation) { - if (logger.isDebugEnabled()) - logger.debug("The PortletSession is currently null, and the " - + "PortletSessionContextIntegrationInterceptor is prohibited from creating a PortletSession " - + "(because the allowSessionCreation property is false) - SecurityContext thus not " - + "stored for next request"); - } - // if the contextClass was changed during the request, then go ahead and create a session - else if (!contextObject.equals(SecurityContextHolder.getContext())) { - if (logger.isDebugEnabled()) - logger.debug("PortletSession being created as SecurityContextHolder contents are non-default"); - try { - portletSession = request.getPortletSession(true); - } catch (IllegalStateException ignored) {} - } - // if nothing in the contextClass changed, then don't bother to create a session - else { - if (logger.isDebugEnabled()) - logger.debug("PortletSession is null, but SecurityContextHolder has not changed from default: ' " - + SecurityContextHolder.getContext() - + "'; not creating PortletSession or storing SecurityContextHolder contents"); - } - } - - // if the session exists and the contextClass has changes, then store the contextClass back into the session - if ((portletSession != null) - && (SecurityContextHolder.getContext().hashCode() != oldContextHashCode)) { - portletSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext(), portletSessionScope()); - if (logger.isDebugEnabled()) - logger.debug("SecurityContext stored to PortletSession: '" - + SecurityContextHolder.getContext() + "'"); - } - - // remove the contents of the holder - SecurityContextHolder.clearContext(); - if (logger.isDebugEnabled()) - logger.debug("SecurityContextHolder set to new contextClass, as request processing completed"); - - } - - /** - * Creates a new SecurityContext object. The specific class is - * determined by the setting of the {@link #contextClass} property. - * @return the new SecurityContext - * @throws PortletException if the creation throws an InstantiationException or - * an IllegalAccessException, then this method will wrap them in a - * PortletException - */ - SecurityContext generateNewContext() throws PortletException { - if (contextClass == null) { - return SecurityContextHolder.createEmptyContext(); - } - - try { - return this.contextClass.newInstance(); - } catch (InstantiationException ie) { - throw new PortletException(ie); - } catch (IllegalAccessException iae) { - throw new PortletException(iae); - } - } - - - private int portletSessionScope() { - // return the appropriate scope setting based on our property value - return (this.useApplicationScopePortletSession ? - PortletSession.APPLICATION_SCOPE : PortletSession.PORTLET_SCOPE); - } - - - public Class getContext() { - return contextClass; - } - - public void setContext(Class secureContext) { - this.contextClass = secureContext; - } - - public boolean isAllowSessionCreation() { - return allowSessionCreation; - } - - public void setAllowSessionCreation(boolean allowSessionCreation) { - this.allowSessionCreation = allowSessionCreation; - } - - public boolean isForceEagerSessionCreation() { - return forceEagerSessionCreation; - } - - public void setForceEagerSessionCreation(boolean forceEagerSessionCreation) { - this.forceEagerSessionCreation = forceEagerSessionCreation; - } - - public boolean isCloneFromPortletSession() { - return cloneFromPortletSession; - } - - public void setCloneFromPortletSession(boolean cloneFromPortletSession) { - this.cloneFromPortletSession = cloneFromPortletSession; - } - - public boolean isUseApplicationScopePortletSession() { - return useApplicationScopePortletSession; - } - - public void setUseApplicationScopePortletSession( - boolean useApplicationScopePortletSession) { - this.useApplicationScopePortletSession = useApplicationScopePortletSession; - } - -} diff --git a/portlet/src/main/java/org/springframework/security/portlet/package.html b/portlet/src/main/java/org/springframework/security/portlet/package.html deleted file mode 100644 index 3f8c54970a..0000000000 --- a/portlet/src/main/java/org/springframework/security/portlet/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -Authentication interceptor (and related classes) for use with the Portlet 1.0 (JSR 168) Specification. - - diff --git a/portlet/src/test/java/org/springframework/security/portlet/PortletProcessingInterceptorTests.java b/portlet/src/test/java/org/springframework/security/portlet/PortletProcessingInterceptorTests.java deleted file mode 100644 index 486eadaf22..0000000000 --- a/portlet/src/test/java/org/springframework/security/portlet/PortletProcessingInterceptorTests.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright 2005-2007 the original author or authors. - * - * 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 org.springframework.security.portlet; - -import static org.junit.Assert.*; - -import java.util.ArrayList; -import java.util.HashMap; - -import javax.portlet.PortletRequest; -import javax.portlet.PortletSession; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.mock.web.portlet.MockActionRequest; -import org.springframework.mock.web.portlet.MockActionResponse; -import org.springframework.mock.web.portlet.MockRenderRequest; -import org.springframework.mock.web.portlet.MockRenderResponse; -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.TestingAuthenticationToken; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.portlet.PortletProcessingInterceptor; - -/** - * Tests {@link PortletProcessingInterceptor}. - * - * @author John A. Lewis - * @since 2.0 - * @version $Id$ - */ -@SuppressWarnings("unchecked") -public class PortletProcessingInterceptorTests { - public static final String SPRING_SECURITY_LAST_EXCEPTION_KEY = "SPRING_SECURITY_LAST_EXCEPTION"; - //~ Methods ======================================================================================================== - - @Before - public void setUp() throws Exception { - SecurityContextHolder.clearContext(); - } - - @After - public void tearDown() throws Exception { - SecurityContextHolder.clearContext(); - } - - @Test(expected=IllegalArgumentException.class) - public void testRequiresAuthenticationManager() throws Exception { - PortletProcessingInterceptor interceptor = new PortletProcessingInterceptor(); - interceptor.afterPropertiesSet(); - } - - @Test - public void testNormalRenderRequestProcessing() throws Exception { - - // Build mock request and response - MockRenderRequest request = PortletTestUtils.createRenderRequest(); - MockRenderResponse response = PortletTestUtils.createRenderResponse(); - - // Prepare interceptor - PortletProcessingInterceptor interceptor = new PortletProcessingInterceptor(); - interceptor.setAuthenticationManager(new MockPortletAuthenticationManager()); - interceptor.afterPropertiesSet(); - - // Execute preHandlerRender phase and verify results - interceptor.preHandleRender(request, response, null); - assertEquals(PortletTestUtils.createAuthenticatedToken(), - SecurityContextHolder.getContext().getAuthentication()); - - // Execute postHandlerRender phase and verify nothing changed - interceptor.postHandleRender(request, response, null, null); - assertEquals(PortletTestUtils.createAuthenticatedToken(), - SecurityContextHolder.getContext().getAuthentication()); - - // Execute afterRenderCompletion phase and verify nothing changed - interceptor.afterRenderCompletion(request, response, null, null); - assertEquals(PortletTestUtils.createAuthenticatedToken(), - SecurityContextHolder.getContext().getAuthentication()); - } - - @Test - public void testNormalActionRequestProcessing() throws Exception { - - // Build mock request and response - MockActionRequest request = PortletTestUtils.createActionRequest(); - MockActionResponse response = PortletTestUtils.createActionResponse(); - - // Prepare interceptor - PortletProcessingInterceptor interceptor = new PortletProcessingInterceptor(); - interceptor.setAuthenticationManager(new MockPortletAuthenticationManager()); - interceptor.afterPropertiesSet(); - - // Execute preHandlerAction phase and verify results - interceptor.preHandleAction(request, response, null); - assertEquals(PortletTestUtils.createAuthenticatedToken(), - SecurityContextHolder.getContext().getAuthentication()); - - // Execute afterActionCompletion phase and verify nothing changed - interceptor.afterActionCompletion(request, response, null, null); - assertEquals(PortletTestUtils.createAuthenticatedToken(), - SecurityContextHolder.getContext().getAuthentication()); - } - - @Test - public void testAuthenticationFailsWithNoCredentials() throws Exception { - - // Build mock request and response - MockActionRequest request = new MockActionRequest(); - MockActionResponse response = new MockActionResponse(); - - // Prepare and execute interceptor - PortletProcessingInterceptor interceptor = new PortletProcessingInterceptor(); - interceptor.setAuthenticationManager(new MockPortletAuthenticationManager()); - interceptor.afterPropertiesSet(); - interceptor.preHandleAction(request, response, null); - - // Verify that authentication is empty - assertNull(SecurityContextHolder.getContext().getAuthentication()); - - // Verify that proper exception was thrown - assertTrue(request.getPortletSession().getAttribute( - AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, - PortletSession.APPLICATION_SCOPE) - instanceof BadCredentialsException); - } - - @Test - public void testExistingAuthenticationIsLeftAlone() throws Exception { - - // Build mock request and response - MockActionRequest request = PortletTestUtils.createActionRequest(); - MockActionResponse response = PortletTestUtils.createActionResponse(); - - // Prepare interceptor - PortletProcessingInterceptor interceptor = new PortletProcessingInterceptor(); - interceptor.setAuthenticationManager(new MockPortletAuthenticationManager()); - interceptor.afterPropertiesSet(); - - UsernamePasswordAuthenticationToken testingToken = new UsernamePasswordAuthenticationToken("dummy", "dummy"); - UsernamePasswordAuthenticationToken baselineToken = new UsernamePasswordAuthenticationToken("dummy", "dummy"); - SecurityContextHolder.getContext().setAuthentication(testingToken); - - // Execute preHandlerAction phase and verify results - interceptor.preHandleAction(request, response, null); - assertTrue(SecurityContextHolder.getContext().getAuthentication() == testingToken); - assertEquals(baselineToken, SecurityContextHolder.getContext().getAuthentication()); - - // Execute afterActionCompletion phase and verify nothing changed - interceptor.afterActionCompletion(request, response, null, null); - assertTrue(SecurityContextHolder.getContext().getAuthentication() == testingToken); - assertEquals(baselineToken, SecurityContextHolder.getContext().getAuthentication()); - } - - @Test - public void testUsernameFromRemoteUser() throws Exception { - - // Build mock request and response - MockActionRequest request = new MockActionRequest(); - MockActionResponse response = new MockActionResponse(); - request.setRemoteUser(PortletTestUtils.TESTUSER); - request.setAuthType(PortletRequest.FORM_AUTH); - - // Prepare and execute interceptor - PortletProcessingInterceptor interceptor = new PortletProcessingInterceptor(); - interceptor.setAuthenticationManager(new MockPortletAuthenticationManager()); - interceptor.afterPropertiesSet(); - interceptor.preHandleAction(request, response, null); - - // Verify username - assertEquals(PortletTestUtils.TESTUSER, - SecurityContextHolder.getContext().getAuthentication().getName()); - } - - @Test - public void testUsernameFromPrincipal() throws Exception { - - // Build mock request and response - MockActionRequest request = new MockActionRequest(); - MockActionResponse response = new MockActionResponse(); - request.setUserPrincipal(new TestingAuthenticationToken(PortletTestUtils.TESTUSER, PortletTestUtils.TESTCRED)); - request.setAuthType(PortletRequest.FORM_AUTH); - - // Prepare and execute interceptor - PortletProcessingInterceptor interceptor = new PortletProcessingInterceptor(); - interceptor.setAuthenticationManager(new MockPortletAuthenticationManager()); - interceptor.afterPropertiesSet(); - interceptor.preHandleAction(request, response, null); - - // Verify username - assertEquals(PortletTestUtils.TESTUSER, - SecurityContextHolder.getContext().getAuthentication().getName()); - } - - @Test - public void testUsernameFromUserInfo() throws Exception { - - // Build mock request and response - MockActionRequest request = new MockActionRequest(); - MockActionResponse response = new MockActionResponse(); - HashMap userInfo = new HashMap(); - userInfo.put("user.name.given", "Test"); - userInfo.put("user.name.family", "User"); - userInfo.put("user.id", "mytestuser"); - request.setAttribute(PortletRequest.USER_INFO, userInfo); - request.setAuthType(PortletRequest.FORM_AUTH); - - // Prepare and execute interceptor - PortletProcessingInterceptor interceptor = new PortletProcessingInterceptor(); - interceptor.setAuthenticationManager(new MockPortletAuthenticationManager()); - ArrayList userNameAttributes = new ArrayList(); - userNameAttributes.add("user.name"); - userNameAttributes.add("user.id"); - interceptor.setUserNameAttributes(userNameAttributes); - interceptor.afterPropertiesSet(); - interceptor.preHandleAction(request, response, null); - - // Verify username - assertEquals("mytestuser", SecurityContextHolder.getContext().getAuthentication().getName()); - } - - //~ Inner Classes ================================================================================================== - - private static class MockPortletAuthenticationManager implements AuthenticationManager { - - public Authentication authenticate(Authentication token) { - - // Make sure we got a valid token - if (!(token instanceof PreAuthenticatedAuthenticationToken)) { - fail("Expected PreAuthenticatedAuthenticationToken object-- got: " + token); - } - - // Make sure the token details are the PortletRequest -// if (!(token.getDetails() instanceof PortletRequest)) { -// TestCase.fail("Expected Authentication.getDetails to be a PortletRequest object -- got: " + token.getDetails()); -// } - - // Make sure it's got a principal - if (token.getPrincipal() == null) { - throw new BadCredentialsException("Mock authentication manager rejecting null principal"); - } - - // Make sure it's got credentials - if (token.getCredentials() == null) { - throw new BadCredentialsException("Mock authentication manager rejecting null credentials"); - } - - // create resulting Authentication object - User user = new User(token.getName(), token.getCredentials().toString(), true, true, true, true, - AuthorityUtils.createAuthorityList(PortletTestUtils.TESTROLE1, PortletTestUtils.TESTROLE2)); - PreAuthenticatedAuthenticationToken result = new PreAuthenticatedAuthenticationToken( - user, user.getPassword(), user.getAuthorities()); - result.setAuthenticated(true); - return result; - } - - } - -} diff --git a/portlet/src/test/java/org/springframework/security/portlet/PortletSessionContextIntegrationInterceptorTests.java b/portlet/src/test/java/org/springframework/security/portlet/PortletSessionContextIntegrationInterceptorTests.java deleted file mode 100644 index 8a7180f845..0000000000 --- a/portlet/src/test/java/org/springframework/security/portlet/PortletSessionContextIntegrationInterceptorTests.java +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright 2005-2007 the original author or authors. - * - * 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 org.springframework.security.portlet; - -import javax.portlet.PortletSession; - -import junit.framework.TestCase; - -import org.springframework.mock.web.portlet.MockActionRequest; -import org.springframework.mock.web.portlet.MockActionResponse; -import org.springframework.mock.web.portlet.MockRenderRequest; -import org.springframework.mock.web.portlet.MockRenderResponse; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.context.SecurityContextImpl; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; - -/** - * Tests {@link PortletSessionContextIntegrationInterceptor}. - * - * @author John A. Lewis - * @since 2.0 - * @version $Id$ - */ -public class PortletSessionContextIntegrationInterceptorTests extends TestCase { - - //~ Methods ======================================================================================================== - - public void setUp() throws Exception { - super.setUp(); - SecurityContextHolder.clearContext(); - } - - public void tearDown() throws Exception { - super.tearDown(); - SecurityContextHolder.clearContext(); - } - - public void testDetectsIncompatibleSessionProperties() throws Exception { - PortletSessionContextIntegrationInterceptor interceptor = new PortletSessionContextIntegrationInterceptor(); - try { - interceptor.setAllowSessionCreation(false); - interceptor.setForceEagerSessionCreation(true); - interceptor.afterPropertiesSet(); - fail("Shown have thrown IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - // ignore - } - interceptor.setAllowSessionCreation(true); - interceptor.afterPropertiesSet(); - } - - public void testNormalRenderRequestProcessing() throws Exception { - - // Build an Authentication object we simulate came from PortletSession - PreAuthenticatedAuthenticationToken sessionPrincipal = PortletTestUtils.createAuthenticatedToken(); - PreAuthenticatedAuthenticationToken baselinePrincipal = PortletTestUtils.createAuthenticatedToken(); - - // Build a Context to store in PortletSession (simulating prior request) - SecurityContext sc = new SecurityContextImpl(); - sc.setAuthentication(sessionPrincipal); - - // Build mock request and response - MockRenderRequest request = PortletTestUtils.createRenderRequest(); - MockRenderResponse response = PortletTestUtils.createRenderResponse(); - request.getPortletSession().setAttribute( - PortletSessionContextIntegrationInterceptor.SPRING_SECURITY_CONTEXT_KEY, - sc, PortletSession.APPLICATION_SCOPE); - - // Prepare interceptor - PortletSessionContextIntegrationInterceptor interceptor = new PortletSessionContextIntegrationInterceptor(); - interceptor.afterPropertiesSet(); - - // Verify the SecurityContextHolder starts empty - assertNull(SecurityContextHolder.getContext().getAuthentication()); - - // Run preHandleRender phase and verify SecurityContextHolder contains our Authentication - interceptor.preHandleRender(request, response, null); - assertEquals(baselinePrincipal, SecurityContextHolder.getContext().getAuthentication()); - - // Run postHandleRender phase and verify the SecurityContextHolder still contains our Authentication - interceptor.postHandleRender(request, response, null, null); - assertEquals(baselinePrincipal, SecurityContextHolder.getContext().getAuthentication()); - - // Run afterRenderCompletion phase and verify the SecurityContextHolder is empty - interceptor.afterRenderCompletion(request, response, null, null); - assertNull(SecurityContextHolder.getContext().getAuthentication()); - } - - public void testNormalActionRequestProcessing() throws Exception { - - // Build an Authentication object we simulate came from PortletSession - PreAuthenticatedAuthenticationToken sessionPrincipal = PortletTestUtils.createAuthenticatedToken(); - PreAuthenticatedAuthenticationToken baselinePrincipal = PortletTestUtils.createAuthenticatedToken(); - - // Build a Context to store in PortletSession (simulating prior request) - SecurityContext sc = new SecurityContextImpl(); - sc.setAuthentication(sessionPrincipal); - - // Build mock request and response - MockActionRequest request = PortletTestUtils.createActionRequest(); - MockActionResponse response = PortletTestUtils.createActionResponse(); - request.getPortletSession().setAttribute( - PortletSessionContextIntegrationInterceptor.SPRING_SECURITY_CONTEXT_KEY, - sc, PortletSession.APPLICATION_SCOPE); - - // Prepare interceptor - PortletSessionContextIntegrationInterceptor interceptor = new PortletSessionContextIntegrationInterceptor(); - interceptor.afterPropertiesSet(); - - // Verify the SecurityContextHolder starts empty - assertNull(SecurityContextHolder.getContext().getAuthentication()); - - // Run preHandleAction phase and verify SecurityContextHolder contains our Authentication - interceptor.preHandleAction(request, response, null); - assertEquals(baselinePrincipal, SecurityContextHolder.getContext().getAuthentication()); - - // Run afterActionCompletion phase and verify the SecurityContextHolder is empty - interceptor.afterActionCompletion(request, response, null, null); - assertNull(SecurityContextHolder.getContext().getAuthentication()); - } - - public void testUpdatesCopiedBackIntoSession() throws Exception { - - // Build an Authentication object we simulate came from PortletSession - PreAuthenticatedAuthenticationToken sessionPrincipal = PortletTestUtils.createAuthenticatedToken(); - PreAuthenticatedAuthenticationToken baselinePrincipal = PortletTestUtils.createAuthenticatedToken(); - - // Build a Context to store in PortletSession (simulating prior request) - SecurityContext sc = new SecurityContextImpl(); - sc.setAuthentication(sessionPrincipal); - - // Build mock request and response - MockActionRequest request = PortletTestUtils.createActionRequest(); - MockActionResponse response = PortletTestUtils.createActionResponse(); - request.getPortletSession().setAttribute( - PortletSessionContextIntegrationInterceptor.SPRING_SECURITY_CONTEXT_KEY, - sc, PortletSession.APPLICATION_SCOPE); - - // Prepare interceptor - PortletSessionContextIntegrationInterceptor interceptor = new PortletSessionContextIntegrationInterceptor(); - interceptor.afterPropertiesSet(); - - // Verify the SecurityContextHolder starts empty - assertNull(SecurityContextHolder.getContext().getAuthentication()); - - // Run preHandleAction phase and verify SecurityContextHolder contains our Authentication - interceptor.preHandleAction(request, response, null); - assertEquals(baselinePrincipal, SecurityContextHolder.getContext().getAuthentication()); - - // Perform updates to principal - sessionPrincipal = PortletTestUtils.createAuthenticatedToken( - new User(PortletTestUtils.TESTUSER, PortletTestUtils.TESTCRED, true, true, true, true, - AuthorityUtils.createAuthorityList("UPDATEDROLE1"))); - baselinePrincipal = PortletTestUtils.createAuthenticatedToken( - new User(PortletTestUtils.TESTUSER, PortletTestUtils.TESTCRED, true, true, true, true, - AuthorityUtils.createAuthorityList("UPDATEDROLE1"))); - - // Store updated principal into SecurityContextHolder - SecurityContextHolder.getContext().setAuthentication(sessionPrincipal); - - // Run afterActionCompletion phase and verify the SecurityContextHolder is empty - interceptor.afterActionCompletion(request, response, null, null); - assertNull(SecurityContextHolder.getContext().getAuthentication()); - - // Verify the new principal is stored in the session - sc = (SecurityContext)request.getPortletSession().getAttribute( - PortletSessionContextIntegrationInterceptor.SPRING_SECURITY_CONTEXT_KEY, - PortletSession.APPLICATION_SCOPE); - assertEquals(baselinePrincipal, sc.getAuthentication()); - } - - public void testPortletSessionCreatedWhenContextHolderChanges() throws Exception { - - // Build mock request and response - MockActionRequest request = PortletTestUtils.createActionRequest(); - MockActionResponse response = PortletTestUtils.createActionResponse(); - - // Prepare the interceptor - PortletSessionContextIntegrationInterceptor interceptor = new PortletSessionContextIntegrationInterceptor(); - interceptor.afterPropertiesSet(); - - // Execute the interceptor - interceptor.preHandleAction(request, response, null); - PreAuthenticatedAuthenticationToken principal = PortletTestUtils.createAuthenticatedToken(); - SecurityContextHolder.getContext().setAuthentication(principal); - interceptor.afterActionCompletion(request, response, null, null); - - // Verify Authentication is in the PortletSession - SecurityContext sc = (SecurityContext)request.getPortletSession(false). - getAttribute(PortletSessionContextIntegrationInterceptor.SPRING_SECURITY_CONTEXT_KEY, PortletSession.APPLICATION_SCOPE); - assertEquals(principal, ((SecurityContext)sc).getAuthentication()); - } - - public void testPortletSessionEagerlyCreatedWhenDirected() throws Exception { - - // Build mock request and response - MockActionRequest request = PortletTestUtils.createActionRequest(); - MockActionResponse response = PortletTestUtils.createActionResponse(); - - // Prepare the interceptor - PortletSessionContextIntegrationInterceptor interceptor = new PortletSessionContextIntegrationInterceptor(); - interceptor.setForceEagerSessionCreation(true); // non-default - interceptor.afterPropertiesSet(); - - // Execute the interceptor - interceptor.preHandleAction(request, response, null); - interceptor.afterActionCompletion(request, response, null, null); - - // Check the session is not null - assertNotNull(request.getPortletSession(false)); - } - - public void testPortletSessionNotCreatedUnlessContextHolderChanges() throws Exception { - - // Build mock request and response - MockActionRequest request = PortletTestUtils.createActionRequest(); - MockActionResponse response = PortletTestUtils.createActionResponse(); - - // Prepare the interceptor - PortletSessionContextIntegrationInterceptor interceptor = new PortletSessionContextIntegrationInterceptor(); - interceptor.afterPropertiesSet(); - - // Execute the interceptor - interceptor.preHandleAction(request, response, null); - interceptor.afterActionCompletion(request, response, null, null); - - // Check the session is null - assertNull(request.getPortletSession(false)); - } - - public void testPortletSessionWithNonContextInWellKnownLocationIsOverwritten() - throws Exception { - - // Build mock request and response - MockActionRequest request = PortletTestUtils.createActionRequest(); - MockActionResponse response = PortletTestUtils.createActionResponse(); - request.getPortletSession().setAttribute( - PortletSessionContextIntegrationInterceptor.SPRING_SECURITY_CONTEXT_KEY, - "NOT_A_CONTEXT_OBJECT", PortletSession.APPLICATION_SCOPE); - - // Prepare the interceptor - PortletSessionContextIntegrationInterceptor interceptor = new PortletSessionContextIntegrationInterceptor(); - interceptor.afterPropertiesSet(); - - // Execute the interceptor - interceptor.preHandleAction(request, response, null); - PreAuthenticatedAuthenticationToken principal = PortletTestUtils.createAuthenticatedToken(); - SecurityContextHolder.getContext().setAuthentication(principal); - interceptor.afterActionCompletion(request, response, null, null); - - // Verify Authentication is in the PortletSession - SecurityContext sc = (SecurityContext)request.getPortletSession(false). - getAttribute(PortletSessionContextIntegrationInterceptor.SPRING_SECURITY_CONTEXT_KEY, PortletSession.APPLICATION_SCOPE); - assertEquals(principal, ((SecurityContext)sc).getAuthentication()); - } - - public void testPortletSessionCreationNotAllowed() throws Exception { - - // Build mock request and response - MockActionRequest request = PortletTestUtils.createActionRequest(); - MockActionResponse response = PortletTestUtils.createActionResponse(); - - // Prepare the interceptor - PortletSessionContextIntegrationInterceptor interceptor = new PortletSessionContextIntegrationInterceptor(); - interceptor.setAllowSessionCreation(false); // non-default - interceptor.afterPropertiesSet(); - - // Execute the interceptor - interceptor.preHandleAction(request, response, null); - PreAuthenticatedAuthenticationToken principal = PortletTestUtils.createAuthenticatedToken(); - SecurityContextHolder.getContext().setAuthentication(principal); - interceptor.afterActionCompletion(request, response, null, null); - - // Check the session is null - assertNull(request.getPortletSession(false)); - } - - public void testUsePortletScopeSession() throws Exception { - - // Build an Authentication object we simulate came from PortletSession - PreAuthenticatedAuthenticationToken sessionPrincipal = PortletTestUtils.createAuthenticatedToken(); - PreAuthenticatedAuthenticationToken baselinePrincipal = PortletTestUtils.createAuthenticatedToken(); - - // Build a Context to store in PortletSession (simulating prior request) - SecurityContext sc = new SecurityContextImpl(); - sc.setAuthentication(sessionPrincipal); - - // Build mock request and response - MockActionRequest request = PortletTestUtils.createActionRequest(); - MockActionResponse response = PortletTestUtils.createActionResponse(); - request.getPortletSession().setAttribute( - PortletSessionContextIntegrationInterceptor.SPRING_SECURITY_CONTEXT_KEY, - sc, PortletSession.PORTLET_SCOPE); - - // Prepare interceptor - PortletSessionContextIntegrationInterceptor interceptor = new PortletSessionContextIntegrationInterceptor(); - interceptor.setUseApplicationScopePortletSession(false); // non-default - interceptor.afterPropertiesSet(); - - // Run preHandleAction phase and verify SecurityContextHolder contains our Authentication - interceptor.preHandleAction(request, response, null); - assertEquals(baselinePrincipal, SecurityContextHolder.getContext().getAuthentication()); - - // Perform updates to principal - sessionPrincipal = PortletTestUtils.createAuthenticatedToken( - new User(PortletTestUtils.TESTUSER, PortletTestUtils.TESTCRED, true, true, true, true, - AuthorityUtils.createAuthorityList("UPDATEDROLE1"))); - baselinePrincipal = PortletTestUtils.createAuthenticatedToken( - new User(PortletTestUtils.TESTUSER, PortletTestUtils.TESTCRED, true, true, true, true, - AuthorityUtils.createAuthorityList("UPDATEDROLE1"))); - - // Store updated principal into SecurityContextHolder - SecurityContextHolder.getContext().setAuthentication(sessionPrincipal); - - // Run afterActionCompletion phase and verify the SecurityContextHolder is empty - interceptor.afterActionCompletion(request, response, null, null); - assertNull(SecurityContextHolder.getContext().getAuthentication()); - - // Verify the new principal is stored in the session - sc = (SecurityContext)request.getPortletSession().getAttribute( - PortletSessionContextIntegrationInterceptor.SPRING_SECURITY_CONTEXT_KEY, - PortletSession.PORTLET_SCOPE); - assertEquals(baselinePrincipal, sc.getAuthentication()); - } - - -} diff --git a/portlet/src/test/java/org/springframework/security/portlet/PortletTestUtils.java b/portlet/src/test/java/org/springframework/security/portlet/PortletTestUtils.java deleted file mode 100644 index 13ec038065..0000000000 --- a/portlet/src/test/java/org/springframework/security/portlet/PortletTestUtils.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2005-2007 the original author or authors. - * - * 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 org.springframework.security.portlet; - -import javax.portlet.PortletRequest; - -import org.springframework.mock.web.portlet.MockActionRequest; -import org.springframework.mock.web.portlet.MockActionResponse; -import org.springframework.mock.web.portlet.MockPortletRequest; -import org.springframework.mock.web.portlet.MockRenderRequest; -import org.springframework.mock.web.portlet.MockRenderResponse; -import org.springframework.security.authentication.TestingAuthenticationToken; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; - -/** - * Utilities for testing Portlet (JSR 168) based security. - * - * @author John A. Lewis - * @since 2.0 - * @version $Id$ - */ -public class PortletTestUtils { - - //~ Static fields/initializers ===================================================================================== - - public static final String PORTALROLE1 = "ONE"; - public static final String PORTALROLE2 = "TWO"; - - public static final String TESTUSER = "testuser"; - public static final String TESTCRED = PortletRequest.FORM_AUTH; - public static final String TESTROLE1 = "ROLE_" + PORTALROLE1; - public static final String TESTROLE2 = "ROLE_" + PORTALROLE2; - - //~ Methods ======================================================================================================== - - public static UserDetails createUser() { - return new User(PortletTestUtils.TESTUSER, "dummy", true, true, true, true, - AuthorityUtils.createAuthorityList(TESTROLE1, TESTROLE2)); - } - - public static void applyPortletRequestSecurity(MockPortletRequest request) { - request.setRemoteUser(TESTUSER); - request.setUserPrincipal(new TestingAuthenticationToken(TESTUSER, TESTCRED)); - request.addUserRole(PORTALROLE1); - request.addUserRole(PORTALROLE2); -// request.setAuthType(PortletRequest.FORM_AUTH); - } - - public static MockRenderRequest createRenderRequest() { - MockRenderRequest request = new MockRenderRequest(); - applyPortletRequestSecurity(request); - return request; - } - - public static MockRenderResponse createRenderResponse() { - MockRenderResponse response = new MockRenderResponse(); - return response; - } - - public static MockActionRequest createActionRequest() { - MockActionRequest request = new MockActionRequest(); - applyPortletRequestSecurity(request); - return request; - } - - public static MockActionResponse createActionResponse() { - MockActionResponse response = new MockActionResponse(); - return response; - } - - public static PreAuthenticatedAuthenticationToken createToken(PortletRequest request) { - PreAuthenticatedAuthenticationToken token = new PreAuthenticatedAuthenticationToken(TESTUSER, TESTCRED); - token.setDetails(new PortletAuthenticationDetails(request)); - return token; - } - - public static PreAuthenticatedAuthenticationToken createToken() { - MockRenderRequest request = createRenderRequest(); - return createToken(request); - } - - public static PreAuthenticatedAuthenticationToken createAuthenticatedToken(UserDetails user) { - PreAuthenticatedAuthenticationToken result = new PreAuthenticatedAuthenticationToken( - user, user.getPassword(), user.getAuthorities()); - result.setAuthenticated(true); - return result; - } - - public static PreAuthenticatedAuthenticationToken createAuthenticatedToken() { - return createAuthenticatedToken(createUser()); - } - -}