SEC-1238: Removed portlet module

This commit is contained in:
Luke Taylor 2009-09-09 20:54:10 +00:00
parent 1d00b92d25
commit aa2999caec
10 changed files with 0 additions and 1711 deletions

View File

@ -1,45 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>3.0.0.CI-SNAPSHOT</version>
</parent>
<artifactId>spring-security-portlet</artifactId>
<name>Spring Security - Portlet support</name>
<description>Spring Security - Support for JSR 168 Portlets</description>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
<dependency>
<groupId>javax.portlet</groupId>
<artifactId>portlet-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-portlet</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -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;
}
}

View File

@ -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<GrantedAuthority> preAuthenticatedGrantedAuthorities = null;
public PortletPreAuthenticatedAuthenticationDetails(PortletRequest request) {
super(request);
}
public List<GrantedAuthority> getGrantedAuthorities() {
Assert.notNull(preAuthenticatedGrantedAuthorities, "Pre-authenticated granted authorities have not been set");
return preAuthenticatedGrantedAuthorities;
}
public void setGrantedAuthorities(List<GrantedAuthority> authorities) {
this.preAuthenticatedGrantedAuthorities = Collections.unmodifiableList(authorities);
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(super.toString() + "; ");
sb.append("preAuthenticatedGrantedAuthorities: " + preAuthenticatedGrantedAuthorities);
return sb.toString();
}
}

View File

@ -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<String> getUserRoles(Object context, Set<String> mappableRoles) {
ArrayList<String> portletRoles = new ArrayList<String>();
for (String role : mappableRoles) {
if (((PortletRequest)context).isUserInRole(role)) {
portletRoles.add(role);
}
}
portletRoles.trimToSize();
return portletRoles;
}
}

View File

@ -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;
/**
* <p>This interceptor is responsible for processing portlet authentication requests. This
* is the portlet equivalent of the <code>UsernamePasswordAuthenticationProcessingFilter</code> used for
* traditional servlet-based web applications. It is applied to both <code>ActionRequest</code>s
* and <code>RenderRequest</code>s alike. If authentication is successful, the resulting
* {@link Authentication} object will be placed into the <code>SecurityContext</code>, which
* is guaranteed to have already been created by an earlier interceptor. If authentication
* fails, the <code>AuthenticationException</code> will be placed into the
* <code>APPLICATION_SCOPE</code> of the <code>PortletSession</code> with the attribute defined
* by {@link AbstractAuthenticationProcessingFilter#SPRING_SECURITY_LAST_EXCEPTION_KEY}.</p>
*
* <p>Some portals do not properly provide the identity of the current user via the
* <code>getRemoteUser()</code> or <code>getUserPrincipal()</code> methods of the
* <code>PortletRequest</code>. In these cases they sometimes make it available in the
* <code>USER_INFO</code> map provided as one of the attributes of the request. If this is
* the case in your portal, you can specify a list of <code>USER_INFO</code> attributes
* to check for the username via the <code>userNameAttributes</code> 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.</p>
*
* <p>This interceptor will put the <code>PortletRequest</code> object into the
* <code>details<code> property of the <code>Authentication</code> object that is sent
* as a request to the <code>AuthenticationManager</code>.
*
* @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 <code>PortletRequest<code> should return the name
* of the user in the <code>getRemoteUser()</code> method. It should also provide a
* <code>java.security.Principal</code> object from the <code>getUserPrincipal()</code>
* method. We will first try these to come up with a valid username.
* <p>Unfortunately, some portals do not properly return these values for authenticated
* users. So, if neither of those succeeds and if the <code>userNameAttributes</code>
* property has been populated, then we will search through the <code>USER_INFO<code>
* map from the request to see if we can find a valid username.
* <p>This method can be overridden by subclasses to provide special handling
* for portals with weak support for the JSR 168 spec.</p>
* @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.
* <p>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.</p>
* @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 <tt>PortletRequest</tt> will be used as the credentials.
* Defaults to false.
*
* @param useAuthTypeAsCredentials
*/
public void setUseAuthTypeAsCredentials(boolean useAuthTypeAsCredentials) {
this.useAuthTypeAsCredentials = useAuthTypeAsCredentials;
}
}

View File

@ -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;
/**
* <p>This interceptor populates the {@link SecurityContextHolder} with information obtained from the
* <code>PortletSession</code>. It is applied to both <code>ActionRequest</code>s and
* <code>RenderRequest</code>s</p>
*
* <p>The <code>PortletSession</code> will be queried to retrieve the <code>SecurityContext</code> that should
* be stored against the <code>SecurityContextHolder</code> for the duration of the portlet request. At the
* end of the request, any updates made to the <code>SecurityContextHolder</code> will be persisted back to the
* <code>PortletSession</code> by this interceptor.</p>
*
* <p> If a valid <code>SecurityContext</code> cannot be obtained from the <code>PortletSession</code> for
* whatever reason, a fresh <code>SecurityContext</code> 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.
*
* <p>A <code>PortletSession</code> may be created by this interceptor if one does not already exist. If at the
* end of the portlet request the <code>PortletSession</code> does not exist, one will <b>only</b> be created if
* the current contents of the <code>SecurityContextHolder</code> are not the {@link java.lang.Object#equals}
* to a <code>new</code> instance of {@link #contextClass}. This avoids needless <code>PortletSession</code> creation,
* and automates the storage of changes made to the <code>SecurityContextHolder</code>. There is one exception to
* this rule, that is if the {@link #forceEagerSessionCreation} property is <code>true</code>, in which case
* sessions will always be created irrespective of normal session-minimization logic (the default is
* <code>false</code>, as this is resource intensive and not recommended).</p>
*
* <p>If for whatever reason no <code>PortletSession</code> should <b>ever</b> be created, the
* {@link #allowSessionCreation} property should be set to <code>false</code>. Only do this if you really need
* to conserve server memory and ensure all classes using the <code>SecurityContextHolder</code> are designed to
* have no persistence of the <code>SecurityContext</code> between web requests. Please note that if
* {@link #forceEagerSessionCreation} is <code>true</code>, the <code>allowSessionCreation</code> must also be
* <code>true</code> (setting it to <code>false</code> will cause a startup-time error).</p>
* <p>This interceptor <b>must</b> be executed <b>before</p> any authentication processing mechanisms. These
* mechanisms (specifically {@link org.springframework.security.portlet.PortletProcessingInterceptor}) expect the
* <code>SecurityContextHolder</code> to contain a valid <code>SecurityContext</code> by the time they execute.</p>
*
* <p>An important nuance to this interceptor is that (by default) the <code>SecurityContext</code> is stored
* into the <code>APPLICATION_SCOPE</code> of the <code>PortletSession</code>. 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 <code>SecurityContext</code> 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 <code>SecurityContext<code>
* object from the session. This allows these calls to be secured as well as the portlet calls.</p>
*
* 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.)
*
* <p>Unlike <code>HttpSessionContextIntegrationFilter</code>, 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.</p>
*
* @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<? extends SecurityContext> contextClass;
private Object contextObject;
/**
* Indicates if this interceptor can create a <code>PortletSession</code> if
* needed (sessions are always created sparingly, but setting this value to
* <code>false</code> will prohibit sessions from ever being created).
* Defaults to <code>true</code>. Do not set to <code>false</code> if
* you are have set {@link #forceEagerSessionCreation} to <code>true</code>,
* as the properties would be in conflict.
*/
private boolean allowSessionCreation = true;
/**
* Indicates if this interceptor is required to create a <code>PortletSession</code>
* for every request before proceeding through the request process, even if the
* <code>PortletSession</code> would not ordinarily have been created. By
* default this is <code>false</code>, which is entirely appropriate for
* most circumstances as you do not want a <code>PortletSession</code>
* created unless the interceptor actually needs one. It is envisaged the main
* situation in which this property would be set to <code>true</code> is
* if using other interceptors that depend on a <code>PortletSession</code>
* already existing. This is only required in specialized cases, so leave it set to
* <code>false</code> unless you have an actual requirement and aware of the
* session creation overhead.
*/
private boolean forceEagerSessionCreation = false;
/**
* Indicates whether the <code>SecurityContext</code> will be cloned from
* the <code>PortletSession</code>. The default is to simply reference
* (the default is <code>false</code>). 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
* <code>PortletSession</code>. 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 <code>PortletSession</code>. For unusual cases where this is not
* permitted, change this value to <code>true</code> and ensure the
* {@link #contextClass} is set to a <code>SecurityContext</code> that
* implements {@link Cloneable} and overrides the <code>clone()</code>
* method.
*/
private boolean cloneFromPortletSession = false;
/**
* Indicates wether the <code>APPLICATION_SCOPE</code> mode of the
* <code>PortletSession</code> should be used for storing the
* <code>SecurityContext</code>. The default is </code>true</code>.
* 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
* <code>false</code>, then the <code>PORTLET_SCOPE</code> 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 <code>SecurityContext</code> object. The specific class is
* determined by the setting of the {@link #contextClass} property.
* @return the new <code>SecurityContext</code>
* @throws PortletException if the creation throws an <code>InstantiationException</code> or
* an <code>IllegalAccessException</code>, then this method will wrap them in a
* <code>PortletException</code>
*/
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<? extends SecurityContext> getContext() {
return contextClass;
}
public void setContext(Class<? extends SecurityContext> 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;
}
}

View File

@ -1,5 +0,0 @@
<html>
<body>
Authentication interceptor (and related classes) for use with the Portlet 1.0 (JSR 168) Specification.
</body>
</html>

View File

@ -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;
}
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}