SEC-1131: Applied patch for portlet upgrade

This commit is contained in:
Luke Taylor 2009-04-12 05:52:20 +00:00
parent 365ae3936e
commit 7c4d54f356
12 changed files with 1006 additions and 952 deletions

View File

@ -1,6 +1,5 @@
package org.springframework.security.authoritymapping; package org.springframework.security.authoritymapping;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -25,9 +24,10 @@ public class SimpleMappableAttributesRetriever implements MappableAttributesRetr
return mappableAttributes; return mappableAttributes;
} }
public void setMappableAttributes(String[] aMappableRoles) { @SuppressWarnings("unchecked")
mappableAttributes = new HashSet<String>(aMappableRoles.length); public void setMappableAttributes(Set aMappableRoles) {
mappableAttributes.addAll(Arrays.asList(aMappableRoles)); mappableAttributes = new HashSet<String>();
mappableAttributes.addAll(aMappableRoles);
mappableAttributes = Collections.unmodifiableSet(mappableAttributes); mappableAttributes = Collections.unmodifiableSet(mappableAttributes);
} }

View File

@ -1,26 +1,27 @@
package org.springframework.security.authoritymapping; package org.springframework.security.authoritymapping;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Set; import java.util.Set;
import java.util.HashSet;
import junit.framework.TestCase;
import junit.framework.TestCase;
/** import org.springframework.util.StringUtils;
*
* @author TSARDD /**
* @since 18-okt-2007 *
*/ * @author TSARDD
public class SimpleMappableRolesRetrieverTests extends TestCase { * @since 18-okt-2007
*/
public final void testGetSetMappableRoles() { public class SimpleMappableRolesRetrieverTests extends TestCase {
String[] roles = new String[] { "Role1", "Role2" };
SimpleMappableAttributesRetriever r = new SimpleMappableAttributesRetriever(); public final void testGetSetMappableRoles() {
r.setMappableAttributes(roles); Set<String> roles = StringUtils.commaDelimitedListToSet("Role1,Role2");
Set<String> result = r.getMappableAttributes(); SimpleMappableAttributesRetriever r = new SimpleMappableAttributesRetriever();
Collection<String> rolesColl = Arrays.asList(roles); r.setMappableAttributes(roles);
assertTrue("Role collections do not match; result: " + result + ", expected: " + rolesColl, rolesColl.containsAll(result) Set<String> result = r.getMappableAttributes();
&& result.containsAll(rolesColl)); assertTrue("Role collections do not match; result: " + result + ", expected: " + roles, roles.containsAll(result)
} && result.containsAll(roles));
}
}
}

View File

@ -19,7 +19,7 @@
<module>samples</module> <module>samples</module>
<module>taglibs</module> <module>taglibs</module>
<module>itest</module> <module>itest</module>
<!-- module>portlet</module --> <module>portlet</module>
</modules> </modules>
<description>Spring Security</description> <description>Spring Security</description>

View File

@ -12,9 +12,9 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.springframework.security</groupId> <groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId> <artifactId>spring-security-web</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId> <artifactId>servlet-api</artifactId>
@ -22,13 +22,13 @@
<dependency> <dependency>
<groupId>javax.portlet</groupId> <groupId>javax.portlet</groupId>
<artifactId>portlet-api</artifactId> <artifactId>portlet-api</artifactId>
<version>1.0</version> <version>2.0</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-portlet</artifactId> <artifactId>org.springframework.web.portlet</artifactId>
<version>2.0.8</version> <version>${spring.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
@ -42,4 +42,4 @@
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,437 +1,468 @@
/* /*
* Copyright 2005-2007 the original author or authors. * Copyright 2005-2007 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.security.context; package org.springframework.security.context;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import javax.portlet.ActionRequest; import javax.portlet.*;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException; import org.apache.commons.logging.Log;
import javax.portlet.PortletRequest; import org.apache.commons.logging.LogFactory;
import javax.portlet.PortletResponse; import org.springframework.beans.factory.InitializingBean;
import javax.portlet.PortletSession; import org.springframework.util.Assert;
import javax.portlet.RenderRequest; import org.springframework.util.ReflectionUtils;
import javax.portlet.RenderResponse; import org.springframework.web.portlet.HandlerInterceptor;
import org.springframework.web.portlet.ModelAndView;
import org.apache.commons.logging.Log; import org.springframework.security.web.context.SecurityContextPersistenceFilter;
import org.apache.commons.logging.LogFactory; import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert; /**
import org.springframework.util.ReflectionUtils; * <p>This interceptor populates the {@link SecurityContextHolder} with information obtained from the
import org.springframework.web.portlet.HandlerInterceptor; * <code>PortletSession</code>. It is applied to both <code>ActionRequest</code>s and
import org.springframework.web.portlet.ModelAndView; * <code>RenderRequest</code>s</p>
*
/** * <p>The <code>PortletSession</code> will be queried to retrieve the <code>SecurityContext</code> that should
* <p>This interceptor populates the {@link SecurityContextHolder} with information obtained from the * be stored against the <code>SecurityContextHolder</code> for the duration of the portlet request. At the
* <code>PortletSession</code>. It is applied to both <code>ActionRequest</code>s and * end of the request, any updates made to the <code>SecurityContextHolder</code> will be persisted back to the
* <code>RenderRequest</code>s</p> * <code>PortletSession</code> by this interceptor.</p>
* *
* <p>The <code>PortletSession</code> will be queried to retrieve the <code>SecurityContext</code> that should * <p> If a valid <code>SecurityContext</code> cannot be obtained from the <code>PortletSession</code> for
* be stored against the <code>SecurityContextHolder</code> for the duration of the portlet request. At the * whatever reason, a fresh <code>SecurityContext</code> will be created and used instead. The created object
* end of the request, any updates made to the <code>SecurityContextHolder</code> will be persisted back to the * will be of the instance defined by the {@link #setContext(Class)} method (which defaults to
* <code>PortletSession</code> by this interceptor.</p> * {@link org.springframework.security.context.SecurityContextImpl}. </p>
* *
* <p> If a valid <code>SecurityContext</code> cannot be obtained from the <code>PortletSession</code> for * <p>A <code>PortletSession</code> may be created by this interceptor if one does not already exist. If at the
* whatever reason, a fresh <code>SecurityContext</code> will be created and used instead. The created object * end of the portlet request the <code>PortletSession</code> does not exist, one will <b>only</b> be created if
* will be of the instance defined by the {@link #setContext(Class)} method (which defaults to * the current contents of the <code>SecurityContextHolder</code> are not the {@link java.lang.Object#equals}
* {@link org.springframework.security.context.SecurityContextImpl}. </p> * to a <code>new</code> instance of {@link #context}. This avoids needless <code>PortletSession</code> creation,
* * and automates the storage of changes made to the <code>SecurityContextHolder</code>. There is one exception to
* <p>A <code>PortletSession</code> may be created by this interceptor if one does not already exist. If at the * this rule, that is if the {@link #forceEagerSessionCreation} property is <code>true</code>, in which case
* end of the portlet request the <code>PortletSession</code> does not exist, one will <b>only</b> be created if * sessions will always be created irrespective of normal session-minimization logic (the default is
* the current contents of the <code>SecurityContextHolder</code> are not the {@link java.lang.Object#equals} * <code>false</code>, as this is resource intensive and not recommended).</p>
* to a <code>new</code> instance of {@link #context}. This avoids needless <code>PortletSession</code> creation, *
* and automates the storage of changes made to the <code>SecurityContextHolder</code>. There is one exception to * <p>If for whatever reason no <code>PortletSession</code> should <b>ever</b> be created, the
* this rule, that is if the {@link #forceEagerSessionCreation} property is <code>true</code>, in which case * {@link #allowSessionCreation} property should be set to <code>false</code>. Only do this if you really need
* sessions will always be created irrespective of normal session-minimization logic (the default is * to conserve server memory and ensure all classes using the <code>SecurityContextHolder</code> are designed to
* <code>false</code>, as this is resource intensive and not recommended).</p> * 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
* <p>If for whatever reason no <code>PortletSession</code> should <b>ever</b> be created, the * <code>true</code> (setting it to <code>false</code> will cause a startup-time error).</p>
* {@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 * <p>This interceptor <b>must</b> be executed <b>before</p> any authentication processing mechanisms. These
* have no persistence of the <code>SecurityContext</code> between web requests. Please note that if * mechanisms (specifically {@link org.springframework.security.ui.portlet.PortletProcessingInterceptor}) expect the
* {@link #forceEagerSessionCreation} is <code>true</code>, the <code>allowSessionCreation</code> must also be * <code>SecurityContextHolder</code> to contain a valid <code>SecurityContext</code> by the time they execute.</p>
* <code>true</code> (setting it to <code>false</code> will cause a startup-time error).</p> *
* <p>An important nuance to this interceptor is that (by default) the <code>SecurityContext</code> is stored
* <p>This interceptor <b>must</b> be executed <b>before</p> any authentication processing mechanisms. These * into the <code>APPLICATION_SCOPE</code> of the <code>PortletSession</code>. This doesn't just mean you will be
* mechanisms (specifically {@link org.springframework.security.ui.portlet.PortletProcessingInterceptor}) expect the * sharing it with all the other portlets in your webapp (which is generally a good idea). It also means that (if
* <code>SecurityContextHolder</code> to contain a valid <code>SecurityContext</code> by the time they execute.</p> * 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
* <p>An important nuance to this interceptor is that (by default) the <code>SecurityContext</code> is stored * since they can now use the {@link SecurityContextPersistenceFilter} to access the same <code>SecurityContext<code>
* into the <code>APPLICATION_SCOPE</code> of the <code>PortletSession</code>. This doesn't just mean you will be * object from the session. This allows these calls to be secured as well as the portlet calls.</p>
* 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 * Much of the logic of this interceptor comes from the {@link SecurityContextPersistenceFilter} class which
* your webapp. This is very useful if you have servlets serving images or processing AJAX calls from your portlets * fills the same purpose on the servlet side. Ben Alex and Patrick Burlson are listed as authors here because they
* since they can now use the {@link HttpSessionContextIntegrationFilter} to access the same <code>SecurityContext<code> * are the authors of that class and there are blocks of code that essentially identical between the two. (Making this
* object from the session. This allows these calls to be secured as well as the portlet calls.</p> * a good candidate for refactoring someday.)
* *
* Much of the logic of this interceptor comes from the {@link HttpSessionContextIntegrationFilter} class which * <p>Unlike <code>HttpSessionContextIntegrationFilter</code>, this interceptor does not check to see if it is
* fills the same purpose on the servlet side. Ben Alex and Patrick Burlson are listed as authors here because they * getting applied multiple times. This shouldn't be a problem since the application of interceptors is under the
* are the authors of that class and there are blocks of code that essentially identical between the two. (Making this * control of the Spring Portlet MVC framework and tends to be more explicit and more predictable than the application
* a good candidate for refactoring someday.) * of filters. However, you should still be careful to only apply this inteceptor to your request once.</p>
* *
* <p>Unlike <code>HttpSessionContextIntegrationFilter</code>, this interceptor does not check to see if it is * @author John A. Lewis
* getting applied multiple times. This shouldn't be a problem since the application of interceptors is under the * @author Ben Alex
* control of the Spring Portlet MVC framework and tends to be more explicit and more predictable than the application * @author Patrick Burleson
* of filters. However, you should still be careful to only apply this inteceptor to your request once.</p> * @since 2.0
* * @version $Id$
* @author John A. Lewis */
* @author Ben Alex public class PortletSessionContextIntegrationInterceptor
* @author Patrick Burleson implements InitializingBean, HandlerInterceptor {
* @since 2.0
* @version $Id$ //~ Static fields/initializers =====================================================================================
*/
public class PortletSessionContextIntegrationInterceptor protected static final Log logger = LogFactory.getLog(PortletSessionContextIntegrationInterceptor.class);
implements InitializingBean, HandlerInterceptor {
public static final String SPRING_SECURITY_CONTEXT_KEY = HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY;
//~ Static fields/initializers =====================================================================================
private static final String SESSION_EXISTED = PortletSessionContextIntegrationInterceptor.class.getName() + ".SESSION_EXISTED";
protected static final Log logger = LogFactory.getLog(PortletSessionContextIntegrationInterceptor.class); private static final String CONTEXT_HASHCODE = PortletSessionContextIntegrationInterceptor.class.getName() + ".CONTEXT_HASHCODE";
public static final String SPRING_SECURITY_CONTEXT_KEY = HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY; //~ Instance fields ================================================================================================
private static final String SESSION_EXISTED = PortletSessionContextIntegrationInterceptor.class.getName() + ".SESSION_EXISTED"; private Class context = SecurityContextImpl.class;
private static final String CONTEXT_HASHCODE = PortletSessionContextIntegrationInterceptor.class.getName() + ".CONTEXT_HASHCODE";
private Object contextObject;
//~ Instance fields ================================================================================================
/**
private Class context = SecurityContextImpl.class; * Indicates if this interceptor can create a <code>PortletSession</code> if
* needed (sessions are always created sparingly, but setting this value to
private Object contextObject; * <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>,
* Indicates if this interceptor can create a <code>PortletSession</code> if * as the properties would be in conflict.
* needed (sessions are always created sparingly, but setting this value to */
* <code>false</code> will prohibit sessions from ever being created). private boolean allowSessionCreation = true;
* 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. * Indicates if this interceptor is required to create a <code>PortletSession</code>
*/ * for every request before proceeding through the request process, even if the
private boolean allowSessionCreation = true; * <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>
* Indicates if this interceptor is required to create a <code>PortletSession</code> * created unless the interceptor actually needs one. It is envisaged the main
* for every request before proceeding through the request process, even if the * situation in which this property would be set to <code>true</code> is
* <code>PortletSession</code> would not ordinarily have been created. By * if using other interceptors that depend on a <code>PortletSession</code>
* default this is <code>false</code>, which is entirely appropriate for * already existing. This is only required in specialized cases, so leave it set to
* most circumstances as you do not want a <code>PortletSession</code> * <code>false</code> unless you have an actual requirement and aware of the
* created unless the interceptor actually needs one. It is envisaged the main * session creation overhead.
* situation in which this property would be set to <code>true</code> is */
* if using other interceptors that depend on a <code>PortletSession</code> private boolean forceEagerSessionCreation = false;
* 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. * Indicates whether the <code>SecurityContext</code> will be cloned from
*/ * the <code>PortletSession</code>. The default is to simply reference
private boolean forceEagerSessionCreation = false; * (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
* Indicates whether the <code>SecurityContext</code> will be cloned from * <code>PortletSession</code>. In most normal environments this does not
* the <code>PortletSession</code>. The default is to simply reference * represent an issue, as changes to the security identity in one thread is
* (the default is <code>false</code>). The default may cause issues if * allowed to affect the security identity in other threads associated with
* concurrent threads need to have a different security identity from other * the same <code>PortletSession</code>. For unusual cases where this is not
* threads being concurrently processed that share the same * permitted, change this value to <code>true</code> and ensure the
* <code>PortletSession</code>. In most normal environments this does not * {@link #context} is set to a <code>SecurityContext</code> that
* represent an issue, as changes to the security identity in one thread is * implements {@link Cloneable} and overrides the <code>clone()</code>
* allowed to affect the security identity in other threads associated with * method.
* the same <code>PortletSession</code>. For unusual cases where this is not */
* permitted, change this value to <code>true</code> and ensure the private boolean cloneFromPortletSession = false;
* {@link #context} is set to a <code>SecurityContext</code> that
* implements {@link Cloneable} and overrides the <code>clone()</code> /**
* method. * Indicates wether the <code>APPLICATION_SCOPE</code> mode of the
*/ * <code>PortletSession</code> should be used for storing the
private boolean cloneFromPortletSession = false; * <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
* Indicates wether the <code>APPLICATION_SCOPE</code> mode of the * <code>false</code>, then the <code>PORTLET_SCOPE</code> will be used
* <code>PortletSession</code> should be used for storing the * instead.
* <code>SecurityContext</code>. The default is </code>true</code>. */
* This allows it to be shared between the portlets in the webapp and private boolean useApplicationScopePortletSession = true;
* 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. //~ Constructors ===================================================================================================
*/
private boolean useApplicationScopePortletSession = true; public PortletSessionContextIntegrationInterceptor() throws PortletException {
this.contextObject = generateNewContext();
}
//~ Constructors ===================================================================================================
//~ Methods ========================================================================================================
public PortletSessionContextIntegrationInterceptor() throws PortletException {
this.contextObject = generateNewContext(); public void afterPropertiesSet() throws Exception {
}
// check that the value of context is legal
//~ Methods ======================================================================================================== if ((this.context == null) || (!SecurityContext.class.isAssignableFrom(this.context))) {
throw new IllegalArgumentException("context must be defined and implement SecurityContext "
public void afterPropertiesSet() throws Exception { + "(typically use org.springframework.security.context.SecurityContextImpl; existing class is "
+ this.context + ")");
// check that the value of context is legal }
if ((this.context == null) || (!SecurityContext.class.isAssignableFrom(this.context))) {
throw new IllegalArgumentException("context must be defined and implement SecurityContext " // check that session creation options make sense
+ "(typically use org.springframework.security.context.SecurityContextImpl; existing class is " if ((forceEagerSessionCreation == true) && (allowSessionCreation == false)) {
+ this.context + ")"); throw new IllegalArgumentException(
} "If using forceEagerSessionCreation, you must set allowSessionCreation to also be true");
}
// check that session creation options make sense }
if ((forceEagerSessionCreation == true) && (allowSessionCreation == false)) {
throw new IllegalArgumentException( public boolean preHandleAction(ActionRequest request, ActionResponse response,
"If using forceEagerSessionCreation, you must set allowSessionCreation to also be true"); Object handler) throws Exception {
} // call to common preHandle method
} return preHandle(request, response, handler);
}
public boolean preHandleAction(ActionRequest request, ActionResponse response,
Object handler) throws Exception { public boolean preHandleRender(RenderRequest request, RenderResponse response,
// call to common preHandle method Object handler) throws Exception {
return preHandle(request, response, handler); // call to common preHandle method
} return preHandle(request, response, handler);
}
public boolean preHandleRender(RenderRequest request, RenderResponse response,
Object handler) throws Exception { public void postHandleRender(RenderRequest request, RenderResponse response,
// call to common preHandle method Object handler, ModelAndView modelAndView) throws Exception {
return preHandle(request, response, handler); // no-op
} }
public void postHandleRender(RenderRequest request, RenderResponse response, public void afterActionCompletion(ActionRequest request, ActionResponse response,
Object handler, ModelAndView modelAndView) throws Exception { Object handler, Exception ex) throws Exception {
// no-op // call to common afterCompletion method
} afterCompletion(request, response, handler, ex);
}
public void afterActionCompletion(ActionRequest request, ActionResponse response,
Object handler, Exception ex) throws Exception { public void afterRenderCompletion(RenderRequest request, RenderResponse response,
// call to common afterCompletion method Object handler, Exception ex) throws Exception {
afterCompletion(request, response, handler, ex); // 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 * {@inheritDoc}
afterCompletion(request, response, handler, ex); */
} public boolean preHandleResource(ResourceRequest request, ResourceResponse response, Object handler) throws Exception {
return preHandle(request, response, handler);
}
private boolean preHandle(PortletRequest request, PortletResponse response,
Object handler) throws Exception { /**
* {@inheritDoc}
PortletSession portletSession = null; */
boolean portletSessionExistedAtStartOfRequest = false; public void postHandleResource(ResourceRequest request, ResourceResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// no-op
// see if the portlet session already exists (or should be eagerly created) }
try {
portletSession = request.getPortletSession(forceEagerSessionCreation); /**
} catch (IllegalStateException ignored) {} * {@inheritDoc}
*/
// if there is a session, then see if there is a context to bring in public void afterResourceCompletion(ResourceRequest request, ResourceResponse response, Object handler, Exception ex) throws Exception {
if (portletSession != null) { // call to common afterCompletion method
afterCompletion(request, response, handler, ex);
// remember that the session already existed }
portletSessionExistedAtStartOfRequest = true;
/**
// attempt to retrieve the context from the session * {@inheritDoc}
Object contextFromSessionObject = portletSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY, portletSessionScope()); */
public boolean preHandleEvent(EventRequest request, EventResponse response, Object handler) throws Exception {
// if we got a context then place it into the holder return preHandle(request, response, handler);
if (contextFromSessionObject != null) { }
// if we are supposed to clone it, then do so /**
if (cloneFromPortletSession) { * {@inheritDoc}
Assert.isInstanceOf(Cloneable.class, contextFromSessionObject, */
"Context must implement Clonable and provide a Object.clone() method"); public void afterEventCompletion(EventRequest request, EventResponse response, Object handler, Exception ex) throws Exception {
try { // call to common afterCompletion method
Method m = contextFromSessionObject.getClass().getMethod("clone", new Class[] {}); afterCompletion(request, response, handler, ex);
if (!m.isAccessible()) { }
m.setAccessible(true);
} private boolean preHandle(PortletRequest request, PortletResponse response,
contextFromSessionObject = m.invoke(contextFromSessionObject, new Object[] {}); Object handler) throws Exception {
}
catch (Exception ex) { PortletSession portletSession = null;
ReflectionUtils.handleReflectionException(ex); boolean portletSessionExistedAtStartOfRequest = false;
}
} // see if the portlet session already exists (or should be eagerly created)
try {
// if what we got is a valid context then place it into the holder, otherwise create a new one portletSession = request.getPortletSession(forceEagerSessionCreation);
if (contextFromSessionObject instanceof SecurityContext) { } catch (IllegalStateException ignored) {}
if (logger.isDebugEnabled())
logger.debug("Obtained from SPRING_SECURITY_CONTEXT a valid SecurityContext and " // if there is a session, then see if there is a context to bring in
+ "set to SecurityContextHolder: '" + contextFromSessionObject + "'"); if (portletSession != null) {
SecurityContextHolder.setContext((SecurityContext) contextFromSessionObject);
} else { // remember that the session already existed
if (logger.isWarnEnabled()) portletSessionExistedAtStartOfRequest = true;
logger.warn("SPRING_SECURITY_CONTEXT did not contain a SecurityContext but contained: '"
+ contextFromSessionObject // attempt to retrieve the context from the session
+ "'; are you improperly modifying the PortletSession directly " Object contextFromSessionObject = portletSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY, portletSessionScope());
+ "(you should always use SecurityContextHolder) or using the PortletSession attribute "
+ "reserved for this class? - new SecurityContext instance associated with " // if we got a context then place it into the holder
+ "SecurityContextHolder"); if (contextFromSessionObject != null) {
SecurityContextHolder.setContext(generateNewContext());
} // if we are supposed to clone it, then do so
if (cloneFromPortletSession) {
} else { Assert.isInstanceOf(Cloneable.class, contextFromSessionObject,
"Context must implement Clonable and provide a Object.clone() method");
// there was no context in the session, so create a new context and put it in the holder try {
if (logger.isDebugEnabled()) Method m = contextFromSessionObject.getClass().getMethod("clone", new Class[] {});
logger.debug("PortletSession returned null object for SPRING_SECURITY_CONTEXT - new " if (!m.isAccessible()) {
+ "SecurityContext instance associated with SecurityContextHolder"); m.setAccessible(true);
SecurityContextHolder.setContext(generateNewContext()); }
} contextFromSessionObject = m.invoke(contextFromSessionObject, new Object[] {});
}
} else { catch (Exception ex) {
ReflectionUtils.handleReflectionException(ex);
// there was no session, so create a new context and place it in the holder }
if (logger.isDebugEnabled()) }
logger.debug("No PortletSession currently exists - new SecurityContext instance "
+ "associated with SecurityContextHolder"); // if what we got is a valid context then place it into the holder, otherwise create a new one
SecurityContextHolder.setContext(generateNewContext()); if (contextFromSessionObject instanceof SecurityContext) {
if (logger.isDebugEnabled())
} logger.debug("Obtained from SPRING_SECURITY_CONTEXT a valid SecurityContext and "
+ "set to SecurityContextHolder: '" + contextFromSessionObject + "'");
// place attributes onto the request to remember if the session existed and the hashcode of the context SecurityContextHolder.setContext((SecurityContext) contextFromSessionObject);
request.setAttribute(SESSION_EXISTED, new Boolean(portletSessionExistedAtStartOfRequest)); } else {
request.setAttribute(CONTEXT_HASHCODE, new Integer(SecurityContextHolder.getContext().hashCode())); if (logger.isWarnEnabled())
logger.warn("SPRING_SECURITY_CONTEXT did not contain a SecurityContext but contained: '"
return true; + contextFromSessionObject
} + "'; are you improperly modifying the PortletSession directly "
+ "(you should always use SecurityContextHolder) or using the PortletSession attribute "
private void afterCompletion(PortletRequest request, PortletResponse response, + "reserved for this class? - new SecurityContext instance associated with "
Object handler, Exception ex) throws Exception { + "SecurityContextHolder");
SecurityContextHolder.setContext(generateNewContext());
PortletSession portletSession = null; }
// retrieve the attributes that remember if the session existed and the hashcode of the context } else {
boolean portletSessionExistedAtStartOfRequest = ((Boolean)request.getAttribute(SESSION_EXISTED)).booleanValue();
int oldContextHashCode = ((Integer)request.getAttribute(CONTEXT_HASHCODE)).intValue(); // there was no context in the session, so create a new context and put it in the holder
if (logger.isDebugEnabled())
// try to retrieve an existing portlet session logger.debug("PortletSession returned null object for SPRING_SECURITY_CONTEXT - new "
try { + "SecurityContext instance associated with SecurityContextHolder");
portletSession = request.getPortletSession(false); SecurityContextHolder.setContext(generateNewContext());
} catch (IllegalStateException ignored) {} }
// if there is now no session but there was one at the beginning then it must have been invalidated } else {
if ((portletSession == null) && portletSessionExistedAtStartOfRequest) {
if (logger.isDebugEnabled()) // there was no session, so create a new context and place it in the holder
logger.debug("PortletSession is now null, but was not null at start of request; " if (logger.isDebugEnabled())
+ "session was invalidated, so do not create a new session"); logger.debug("No PortletSession currently exists - new SecurityContext instance "
} + "associated with SecurityContextHolder");
SecurityContextHolder.setContext(generateNewContext());
// 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 // place attributes onto the request to remember if the session existed and the hashcode of the context
if (!allowSessionCreation) { request.setAttribute(SESSION_EXISTED, new Boolean(portletSessionExistedAtStartOfRequest));
if (logger.isDebugEnabled()) request.setAttribute(CONTEXT_HASHCODE, new Integer(SecurityContextHolder.getContext().hashCode()));
logger.debug("The PortletSession is currently null, and the "
+ "PortletSessionContextIntegrationInterceptor is prohibited from creating a PortletSession " return true;
+ "(because the allowSessionCreation property is false) - SecurityContext thus not " }
+ "stored for next request");
} private void afterCompletion(PortletRequest request, PortletResponse response,
// if the context was changed during the request, then go ahead and create a session Object handler, Exception ex) throws Exception {
else if (!contextObject.equals(SecurityContextHolder.getContext())) {
if (logger.isDebugEnabled()) PortletSession portletSession = null;
logger.debug("PortletSession being created as SecurityContextHolder contents are non-default");
try { // retrieve the attributes that remember if the session existed and the hashcode of the context
portletSession = request.getPortletSession(true); boolean portletSessionExistedAtStartOfRequest = ((Boolean)request.getAttribute(SESSION_EXISTED)).booleanValue();
} catch (IllegalStateException ignored) {} int oldContextHashCode = ((Integer)request.getAttribute(CONTEXT_HASHCODE)).intValue();
}
// if nothing in the context changed, then don't bother to create a session // try to retrieve an existing portlet session
else { try {
if (logger.isDebugEnabled()) portletSession = request.getPortletSession(false);
logger.debug("PortletSession is null, but SecurityContextHolder has not changed from default: ' " } catch (IllegalStateException ignored) {}
+ SecurityContextHolder.getContext()
+ "'; not creating PortletSession or storing SecurityContextHolder contents"); // 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; "
// if the session exists and the context has changes, then store the context back into the session + "session was invalidated, so do not create a new session");
if ((portletSession != null) }
&& (SecurityContextHolder.getContext().hashCode() != oldContextHashCode)) {
portletSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext(), portletSessionScope()); // create a new portlet session if we need to
if (logger.isDebugEnabled()) if ((portletSession == null) && !portletSessionExistedAtStartOfRequest) {
logger.debug("SecurityContext stored to PortletSession: '"
+ SecurityContextHolder.getContext() + "'"); // if we're not allowed to create a new session, then report that
} if (!allowSessionCreation) {
if (logger.isDebugEnabled())
// remove the contents of the holder logger.debug("The PortletSession is currently null, and the "
SecurityContextHolder.clearContext(); + "PortletSessionContextIntegrationInterceptor is prohibited from creating a PortletSession "
if (logger.isDebugEnabled()) + "(because the allowSessionCreation property is false) - SecurityContext thus not "
logger.debug("SecurityContextHolder set to new context, as request processing completed"); + "stored for next request");
}
} // if the context was changed during the request, then go ahead and create a session
else if (!contextObject.equals(SecurityContextHolder.getContext())) {
/** if (logger.isDebugEnabled())
* Creates a new <code>SecurityContext</code> object. The specific class is logger.debug("PortletSession being created as SecurityContextHolder contents are non-default");
* determined by the setting of the {@link #context} property. try {
* @return the new <code>SecurityContext</code> portletSession = request.getPortletSession(true);
* @throws PortletException if the creation throws an <code>InstantiationException</code> or } catch (IllegalStateException ignored) {}
* an <code>IllegalAccessException</code>, then this method will wrap them in a }
* <code>PortletException</code> // if nothing in the context changed, then don't bother to create a session
*/ else {
public SecurityContext generateNewContext() throws PortletException { if (logger.isDebugEnabled())
try { logger.debug("PortletSession is null, but SecurityContextHolder has not changed from default: ' "
return (SecurityContext) this.context.newInstance(); + SecurityContextHolder.getContext()
} catch (InstantiationException ie) { + "'; not creating PortletSession or storing SecurityContextHolder contents");
throw new PortletException(ie); }
} catch (IllegalAccessException iae) { }
throw new PortletException(iae);
} // if the session exists and the context has changes, then store the context back into the session
} if ((portletSession != null)
&& (SecurityContextHolder.getContext().hashCode() != oldContextHashCode)) {
portletSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext(), portletSessionScope());
private int portletSessionScope() { if (logger.isDebugEnabled())
// return the appropriate scope setting based on our property value logger.debug("SecurityContext stored to PortletSession: '"
return (this.useApplicationScopePortletSession ? + SecurityContextHolder.getContext() + "'");
PortletSession.APPLICATION_SCOPE : PortletSession.PORTLET_SCOPE); }
}
// remove the contents of the holder
SecurityContextHolder.clearContext();
public Class getContext() { if (logger.isDebugEnabled())
return context; logger.debug("SecurityContextHolder set to new context, as request processing completed");
}
}
public void setContext(Class secureContext) {
this.context = secureContext; /**
} * Creates a new <code>SecurityContext</code> object. The specific class is
* determined by the setting of the {@link #context} property.
public boolean isAllowSessionCreation() { * @return the new <code>SecurityContext</code>
return allowSessionCreation; * @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>
public void setAllowSessionCreation(boolean allowSessionCreation) { */
this.allowSessionCreation = allowSessionCreation; public SecurityContext generateNewContext() throws PortletException {
} try {
return (SecurityContext) this.context.newInstance();
public boolean isForceEagerSessionCreation() { } catch (InstantiationException ie) {
return forceEagerSessionCreation; throw new PortletException(ie);
} } catch (IllegalAccessException iae) {
throw new PortletException(iae);
public void setForceEagerSessionCreation(boolean forceEagerSessionCreation) { }
this.forceEagerSessionCreation = forceEagerSessionCreation; }
}
public boolean isCloneFromPortletSession() { private int portletSessionScope() {
return cloneFromPortletSession; // return the appropriate scope setting based on our property value
} return (this.useApplicationScopePortletSession ?
PortletSession.APPLICATION_SCOPE : PortletSession.PORTLET_SCOPE);
public void setCloneFromPortletSession(boolean cloneFromPortletSession) { }
this.cloneFromPortletSession = cloneFromPortletSession;
}
public Class getContext() {
public boolean isUseApplicationScopePortletSession() { return context;
return useApplicationScopePortletSession; }
}
public void setContext(Class secureContext) {
public void setUseApplicationScopePortletSession( this.context = secureContext;
boolean useApplicationScopePortletSession) { }
this.useApplicationScopePortletSession = useApplicationScopePortletSession;
} 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

@ -6,7 +6,7 @@ import java.util.Set;
import javax.portlet.PortletRequest; import javax.portlet.PortletRequest;
import org.springframework.security.ui.preauth.j2ee.AbstractPreAuthenticatedAuthenticationDetailsSource; import org.springframework.security.web.authentication.preauth.j2ee.AbstractPreAuthenticatedAuthenticationDetailsSource;
public class PortletPreAuthenticatedAuthenticationDetailsSource extends AbstractPreAuthenticatedAuthenticationDetailsSource { public class PortletPreAuthenticatedAuthenticationDetailsSource extends AbstractPreAuthenticatedAuthenticationDetailsSource {

View File

@ -1,322 +1,342 @@
/* /*
* Copyright 2005-2007 the original author or authors. * Copyright 2005-2007 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.security.ui.portlet; package org.springframework.security.ui.portlet;
import java.io.IOException; import java.io.IOException;
import java.security.Principal; import java.security.Principal;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.portlet.ActionRequest; import javax.portlet.*;
import javax.portlet.ActionResponse;
import javax.portlet.PortletRequest; import org.springframework.security.Authentication;
import javax.portlet.PortletResponse; import org.springframework.security.AuthenticationDetailsSource;
import javax.portlet.PortletSession; import org.springframework.security.AuthenticationDetailsSourceImpl;
import javax.portlet.RenderRequest; import org.springframework.security.AuthenticationException;
import javax.portlet.RenderResponse; import org.springframework.security.AuthenticationManager;
import org.springframework.security.web.authentication.AbstractProcessingFilter;
import org.springframework.security.Authentication; import org.springframework.security.context.SecurityContext;
import org.springframework.security.AuthenticationDetailsSource; import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.AuthenticationDetailsSourceImpl; import org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.security.AuthenticationException; import org.springframework.security.web.authentication.AbstractProcessingFilter;
import org.springframework.security.AuthenticationManager; import org.apache.commons.logging.Log;
import org.springframework.security.context.SecurityContext; import org.apache.commons.logging.LogFactory;
import org.springframework.security.context.SecurityContextHolder; import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.util.Assert;
import org.springframework.security.ui.AbstractProcessingFilter; import org.springframework.web.portlet.HandlerInterceptor;
import org.apache.commons.logging.Log; import org.springframework.web.portlet.ModelAndView;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean; /**
import org.springframework.util.Assert; * <p>This interceptor is responsible for processing portlet authentication requests. This
import org.springframework.web.portlet.HandlerInterceptor; * is the portlet equivalent of the <code>AuthenticationProcessingFilter</code> used for
import org.springframework.web.portlet.ModelAndView; * 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
* <p>This interceptor is responsible for processing portlet authentication requests. This * is guaranteed to have already been created by an earlier interceptor. If authentication
* is the portlet equivalent of the <code>AuthenticationProcessingFilter</code> used for * fails, the <code>AuthenticationException</code> will be placed into the
* traditional servlet-based web applications. It is applied to both <code>ActionRequest</code>s * <code>APPLICATION_SCOPE</code> of the <code>PortletSession</code> with the attribute defined
* and <code>RenderRequest</code>s alike. If authentication is successful, the resulting * by {@link AbstractProcessingFilter#SPRING_SECURITY_LAST_EXCEPTION_KEY}.</p>
* {@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 * <p>Some portals do not properly provide the identity of the current user via the
* fails, the <code>AuthenticationException</code> will be placed into the * <code>getRemoteUser()</code> or <code>getUserPrincipal()</code> methods of the
* <code>APPLICATION_SCOPE</code> of the <code>PortletSession</code> with the attribute defined * <code>PortletRequest</code>. In these cases they sometimes make it available in the
* by {@link AbstractProcessingFilter#SPRING_SECURITY_LAST_EXCEPTION_KEY}.</p> * <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
* <p>Some portals do not properly provide the identity of the current user via the * to check for the username via the <code>userNameAttributes</code> property of this bean.
* <code>getRemoteUser()</code> or <code>getUserPrincipal()</code> methods of the * You can also completely override the {@link #getPrincipalFromRequest(PortletRequest)}
* <code>PortletRequest</code>. In these cases they sometimes make it available in the * and {@link #getCredentialsFromRequest(PortletRequest)} methods to suit the particular
* <code>USER_INFO</code> map provided as one of the attributes of the request. If this is * behavior of your portal.</p>
* 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. * <p>This interceptor will put the <code>PortletRequest</code> object into the
* You can also completely override the {@link #getPrincipalFromRequest(PortletRequest)} * <code>details<code> property of the <code>Authentication</code> object that is sent
* and {@link #getCredentialsFromRequest(PortletRequest)} methods to suit the particular * as a request to the <code>AuthenticationManager</code>.
* behavior of your portal.</p> *
* * @see org.springframework.security.web.authentication.AbstractProcessingFilter
* <p>This interceptor will put the <code>PortletRequest</code> object into the * @see org.springframework.security.web.authentication.AuthenticationProcessingFilter
* <code>details<code> property of the <code>Authentication</code> object that is sent * @author John A. Lewis
* as a request to the <code>AuthenticationManager</code>. This is done so that the request * @since 2.0
* is available to classes like {@link ContainerPortletAuthoritiesPopulator} that need * @version $Id$
* access to information from the portlet container. The {@link PortletAuthenticationProvider} */
* will replace this with the <code>USER_INFO</code> map in the resulting <code>Authentication</code> public class PortletProcessingInterceptor implements HandlerInterceptor, InitializingBean {
* object.</p>
* //~ Static fields/initializers =====================================================================================
* @see org.springframework.security.ui.AbstractProcessingFilter
* @see org.springframework.security.ui.webapp.AuthenticationProcessingFilter private static final Log logger = LogFactory.getLog(PortletProcessingInterceptor.class);
* @author John A. Lewis
* @since 2.0 //~ Instance fields ================================================================================================
* @version $Id$
*/ private AuthenticationManager authenticationManager;
public class PortletProcessingInterceptor implements HandlerInterceptor, InitializingBean {
private List userNameAttributes;
//~ Static fields/initializers =====================================================================================
private AuthenticationDetailsSource authenticationDetailsSource;
private static final Log logger = LogFactory.getLog(PortletProcessingInterceptor.class);
private boolean useAuthTypeAsCredentials = false;
//~ Instance fields ================================================================================================
public PortletProcessingInterceptor() {
private AuthenticationManager authenticationManager; authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
((AuthenticationDetailsSourceImpl)authenticationDetailsSource).setClazz(PortletAuthenticationDetails.class);
private List userNameAttributes; }
private AuthenticationDetailsSource authenticationDetailsSource; //~ Methods ========================================================================================================
private boolean useAuthTypeAsCredentials = false; public void afterPropertiesSet() throws Exception {
Assert.notNull(authenticationManager, "An AuthenticationManager must be set");
public PortletProcessingInterceptor() { }
authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
((AuthenticationDetailsSourceImpl)authenticationDetailsSource).setClazz(PortletAuthenticationDetails.class); public boolean preHandleAction(ActionRequest request, ActionResponse response,
} Object handler) throws Exception {
return preHandle(request, response, handler);
//~ Methods ======================================================================================================== }
public void afterPropertiesSet() throws Exception { public boolean preHandleRender(RenderRequest request,
Assert.notNull(authenticationManager, "An AuthenticationManager must be set"); RenderResponse response, Object handler) throws Exception {
} return preHandle(request, response, handler);
}
public boolean preHandleAction(ActionRequest request, ActionResponse response,
Object handler) throws Exception { public void postHandleRender(RenderRequest request, RenderResponse response,
return preHandle(request, response, handler); Object handler, ModelAndView modelAndView) throws Exception {
} }
public boolean preHandleRender(RenderRequest request, public void afterActionCompletion(ActionRequest request, ActionResponse response,
RenderResponse response, Object handler) throws Exception { Object handler, Exception ex) throws Exception {
return preHandle(request, response, handler); }
}
public void afterRenderCompletion(RenderRequest request, RenderResponse response,
public void postHandleRender(RenderRequest request, RenderResponse response, Object handler, Exception ex) throws Exception {
Object handler, ModelAndView modelAndView) throws Exception { }
}
/**
public void afterActionCompletion(ActionRequest request, ActionResponse response, * {@inheritDoc}
Object handler, Exception ex) throws Exception { */
} public boolean preHandleResource(ResourceRequest request, ResourceResponse response, Object handler) throws Exception {
return preHandle(request, response, handler);
public void afterRenderCompletion(RenderRequest request, RenderResponse response, }
Object handler, Exception ex) throws Exception {
} /**
* {@inheritDoc}
/** */
* Common preHandle method for both the action and render phases of the interceptor. public void postHandleResource(ResourceRequest request, ResourceResponse response, Object handler, ModelAndView modelAndView) throws Exception {
*/ }
private boolean preHandle(PortletRequest request, PortletResponse response,
Object handler) throws Exception { public void afterResourceCompletion(ResourceRequest request, ResourceResponse response, Object handler, Exception ex) throws Exception {
}
// get the SecurityContext
SecurityContext ctx = SecurityContextHolder.getContext(); /**
* {@inheritDoc}
if (logger.isDebugEnabled()) */
logger.debug("Checking secure context token: " + ctx.getAuthentication()); public boolean preHandleEvent(EventRequest request, EventResponse response, Object handler) throws Exception {
return preHandle(request, response, handler);
// if there is no existing Authentication object, then lets create one }
if (ctx.getAuthentication() == null) {
/**
try { * {@inheritDoc}
*/
// build the authentication request from the PortletRequest public void afterEventCompletion(EventRequest request, EventResponse response, Object handler, Exception ex) throws Exception {
PreAuthenticatedAuthenticationToken authRequest = new PreAuthenticatedAuthenticationToken( }
getPrincipalFromRequest(request),
getCredentialsFromRequest(request)); /**
* Common preHandle method for both the action and render phases of the interceptor.
// put the PortletRequest into the authentication request as the "details" */
authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); private boolean preHandle(PortletRequest request, PortletResponse response,
Object handler) throws Exception {
if (logger.isDebugEnabled())
logger.debug("Beginning authentication request for user '" + authRequest.getName() + "'"); // get the SecurityContext
SecurityContext ctx = SecurityContextHolder.getContext();
onPreAuthentication(request, response);
if (logger.isDebugEnabled())
// ask the authentication manager to authenticate the request logger.debug("Checking secure context token: " + ctx.getAuthentication());
// it will throw an AuthenticationException if it fails, otherwise it succeeded
Authentication authResult = authenticationManager.authenticate(authRequest); // if there is no existing Authentication object, then lets create one
if (ctx.getAuthentication() == null) {
// process a successful authentication
if (logger.isDebugEnabled()) { try {
logger.debug("Authentication success: " + authResult);
} // build the authentication request from the PortletRequest
PreAuthenticatedAuthenticationToken authRequest = new PreAuthenticatedAuthenticationToken(
ctx.setAuthentication(authResult); getPrincipalFromRequest(request),
onSuccessfulAuthentication(request, response, authResult); getCredentialsFromRequest(request));
} catch (AuthenticationException failed) { // put the PortletRequest into the authentication request as the "details"
// process an unsuccessful authentication authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
if (logger.isDebugEnabled()) {
logger.debug("Authentication failed - updating ContextHolder to contain null Authentication", failed); if (logger.isDebugEnabled())
} logger.debug("Beginning authentication request for user '" + authRequest.getName() + "'");
ctx.setAuthentication(null);
request.getPortletSession().setAttribute( onPreAuthentication(request, response);
AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY,
failed, PortletSession.APPLICATION_SCOPE); // ask the authentication manager to authenticate the request
onUnsuccessfulAuthentication(request, response, failed); // it will throw an AuthenticationException if it fails, otherwise it succeeded
} Authentication authResult = authenticationManager.authenticate(authRequest);
}
// process a successful authentication
return true; if (logger.isDebugEnabled()) {
} logger.debug("Authentication success: " + authResult);
}
/**
* This method attempts to extract a principal from the portlet request. ctx.setAuthentication(authResult);
* According to the JSR 168 spec, the <code>PortletRequest<code> should return the name onSuccessfulAuthentication(request, response, authResult);
* 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> } catch (AuthenticationException failed) {
* method. We will first try these to come up with a valid username. // process an unsuccessful authentication
* <p>Unfortunately, some portals do not properly return these values for authenticated if (logger.isDebugEnabled()) {
* users. So, if neither of those succeeds and if the <code>userNameAttributes</code> logger.debug("Authentication failed - updating ContextHolder to contain null Authentication", failed);
* 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. ctx.setAuthentication(null);
* <p>This method can be overridden by subclasses to provide special handling request.getPortletSession().setAttribute(
* for portals with weak support for the JSR 168 spec.</p> AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY,
* @param request the portlet request object failed, PortletSession.APPLICATION_SCOPE);
* @return the determined principal object, or null if none found onUnsuccessfulAuthentication(request, response, failed);
*/ }
protected Object getPrincipalFromRequest(PortletRequest request) { }
// first try getRemoteUser() return true;
String remoteUser = request.getRemoteUser(); }
if (remoteUser != null) {
return remoteUser; /**
} * 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
// next try getUserPrincipal() * of the user in the <code>getRemoteUser()</code> method. It should also provide a
Principal userPrincipal = request.getUserPrincipal(); * <code>java.security.Principal</code> object from the <code>getUserPrincipal()</code>
if (userPrincipal != null) { * method. We will first try these to come up with a valid username.
String userPrincipalName = userPrincipal.getName(); * <p>Unfortunately, some portals do not properly return these values for authenticated
if (userPrincipalName != null) { * users. So, if neither of those succeeds and if the <code>userNameAttributes</code>
return userPrincipalName; * 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>
// last try entries in USER_INFO if any attributes were defined * @param request the portlet request object
if (this.userNameAttributes != null) { * @return the determined principal object, or null if none found
Map userInfo = null; */
try { protected Object getPrincipalFromRequest(PortletRequest request) {
userInfo = (Map)request.getAttribute(PortletRequest.USER_INFO);
} catch (Exception e) { // first try getRemoteUser()
logger.warn("unable to retrieve USER_INFO map from portlet request", e); String remoteUser = request.getRemoteUser();
} if (remoteUser != null) {
if (userInfo != null) { return remoteUser;
Iterator i = this.userNameAttributes.iterator(); }
while(i.hasNext()) {
Object principal = (String)userInfo.get(i.next()); // next try getUserPrincipal()
if (principal != null) { Principal userPrincipal = request.getUserPrincipal();
return principal; if (userPrincipal != null) {
} String userPrincipalName = userPrincipal.getName();
} if (userPrincipalName != null) {
} return userPrincipalName;
} }
}
// none found so return null
return null; // last try entries in USER_INFO if any attributes were defined
} if (this.userNameAttributes != null) {
Map userInfo = null;
/** try {
* This method attempts to extract a credentials from the portlet request. userInfo = (Map)request.getAttribute(PortletRequest.USER_INFO);
* We are trusting the portal framework to authenticate the user, so all } catch (Exception e) {
* we are really doing is trying to put something intelligent in here to logger.warn("unable to retrieve USER_INFO map from portlet request", e);
* indicate the user is authenticated. According to the JSR 168 spec, }
* PortletRequest.getAuthType() should return a non-null value if the if (userInfo != null) {
* user is authenticated and should be null if not authenticated. So we Iterator i = this.userNameAttributes.iterator();
* will use this as the credentials and the token will be trusted as while(i.hasNext()) {
* authenticated if the credentials are not null. Object principal = (String)userInfo.get(i.next());
* <p>This method can be overridden by subclasses to provide special handling if (principal != null) {
* for portals with weak support for the JSR 168 spec. If that is done, return principal;
* 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) { // none found so return null
if (useAuthTypeAsCredentials) { return null;
return request.getAuthType(); }
}
/**
return "dummy"; * 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,
* Callback for custom processing prior to the authentication attempt. * PortletRequest.getAuthType() should return a non-null value if the
* @param request the portlet request to be authenticated * user is authenticated and should be null if not authenticated. So we
* @param response the portlet response to be authenticated * will use this as the credentials and the token will be trusted as
* @throws AuthenticationException to indicate that authentication attempt is not valid and should be terminated * authenticated if the credentials are not null.
* @throws IOException * <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,
protected void onPreAuthentication(PortletRequest request, PortletResponse response) * be sure the value is non-null for authenticated users and null for
throws AuthenticationException, IOException {} * non-authenticated users.</p>
* @param request the portlet request object
/** * @return the determined credentials object, or null if none found
* Callback for custom processing after a successful authentication attempt. */
* @param request the portlet request that was authenticated protected Object getCredentialsFromRequest(PortletRequest request) {
* @param response the portlet response that was authenticated if (useAuthTypeAsCredentials) {
* @param authResult the resulting Authentication object return request.getAuthType();
* @throws IOException }
*/
protected void onSuccessfulAuthentication(PortletRequest request, PortletResponse response, Authentication authResult) return "dummy";
throws IOException {} }
/** /**
* Callback for custom processing after an unsuccessful authentication attempt. * Callback for custom processing prior to the authentication attempt.
* @param request the portlet request that failed authentication * @param request the portlet request to be authenticated
* @param response the portlet response that failed authentication * @param response the portlet response to be authenticated
* @param failed the AuthenticationException that occurred * @throws AuthenticationException to indicate that authentication attempt is not valid and should be terminated
* @throws IOException * @throws IOException
*/ */
protected void onUnsuccessfulAuthentication(PortletRequest request, PortletResponse response, AuthenticationException failed) protected void onPreAuthentication(PortletRequest request, PortletResponse response)
throws IOException {} throws AuthenticationException, IOException {}
/**
public void setAuthenticationManager(AuthenticationManager authenticationManager) { * Callback for custom processing after a successful authentication attempt.
this.authenticationManager = authenticationManager; * @param request the portlet request that was authenticated
} * @param response the portlet response that was authenticated
* @param authResult the resulting Authentication object
public void setUserNameAttributes(List userNameAttributes) { * @throws IOException
this.userNameAttributes = userNameAttributes; */
} protected void onSuccessfulAuthentication(PortletRequest request, PortletResponse response, Authentication authResult)
throws IOException {}
public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) {
this.authenticationDetailsSource = authenticationDetailsSource; /**
} * 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
* It true, the "authType" proerty of the <tt>PortletRequest</tt> will be used as the credentials. * @param failed the AuthenticationException that occurred
* Defaults to false. * @throws IOException
* */
* @param useAuthTypeAsCredentials protected void onUnsuccessfulAuthentication(PortletRequest request, PortletResponse response, AuthenticationException failed)
*/ throws IOException {}
public void setUseAuthTypeAsCredentials(boolean useAuthTypeAsCredentials) {
this.useAuthTypeAsCredentials = useAuthTypeAsCredentials;
} 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

@ -34,6 +34,7 @@ import org.springframework.mock.web.portlet.MockRenderResponse;
import org.springframework.security.Authentication; import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationManager; import org.springframework.security.AuthenticationManager;
import org.springframework.security.BadCredentialsException; import org.springframework.security.BadCredentialsException;
import org.springframework.security.web.authentication.AbstractProcessingFilter;
import org.springframework.security.context.SecurityContextHolder; import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.TestingAuthenticationToken; import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.security.providers.UsernamePasswordAuthenticationToken;

View File

@ -16,7 +16,7 @@
<module>preauth</module> <module>preauth</module>
<module>openid</module> <module>openid</module>
<module>ldap</module> <module>ldap</module>
<!-- module>portlet</module --> <module>portlet</module>
<module>cas</module> <module>cas</module>
</modules> </modules>
<dependencies> <dependencies>

View File

@ -11,11 +11,11 @@ import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse; import javax.portlet.RenderResponse;
import org.springframework.security.context.SecurityContextHolder; import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.ui.AbstractProcessingFilter; import org.springframework.security.web.authentication.AbstractProcessingFilter;
/** /**
* A simple portlet which prints out the contents of the current {@link SecurityContext} * A simple portlet which prints out the contents of the current {@link org.springframework.security.context.SecurityContext}
* *
* @author Luke Taylor * @author Luke Taylor
*/ */

View File

@ -38,7 +38,7 @@
<property name="mappableRolesRetriever"> <property name="mappableRolesRetriever">
<bean class="org.springframework.security.authoritymapping.SimpleMappableAttributesRetriever"> <bean class="org.springframework.security.authoritymapping.SimpleMappableAttributesRetriever">
<property name="mappableAttributes"> <property name="mappableAttributes">
<list> <set>
<value>tomcat</value> <value>tomcat</value>
<value>admin</value> <value>admin</value>
<value>manager</value> <value>manager</value>
@ -47,7 +47,7 @@
<value>Guest</value> <value>Guest</value>
<value>User</value> <value>User</value>
<value>Power User</value> <value>Power User</value>
</list> </set>
</property> </property>
</bean> </bean>
</property> </property>

View File

@ -1,150 +1,151 @@
package org.springframework.security.web.authentication.preauth.j2ee; package org.springframework.security.web.authentication.preauth.j2ee;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.springframework.security.authoritymapping.MappableAttributesRetriever; import org.springframework.security.authoritymapping.MappableAttributesRetriever;
import org.springframework.security.authoritymapping.Attributes2GrantedAuthoritiesMapper; import org.springframework.security.authoritymapping.Attributes2GrantedAuthoritiesMapper;
import org.springframework.security.authoritymapping.SimpleMappableAttributesRetriever; import org.springframework.security.authoritymapping.SimpleMappableAttributesRetriever;
import org.springframework.security.authoritymapping.SimpleAttributes2GrantedAuthoritiesMapper; import org.springframework.security.authoritymapping.SimpleAttributes2GrantedAuthoritiesMapper;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails; import org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails;
import org.springframework.security.web.authentication.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource; import org.springframework.security.web.authentication.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource;
import org.springframework.security.GrantedAuthority; import org.springframework.security.GrantedAuthority;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.util.StringUtils;
/**
* /**
* @author TSARDD *
*/ * @author TSARDD
public class J2eeBasedPreAuthenticatedWebAuthenticationDetailsSourceTests extends TestCase { */
public class J2eeBasedPreAuthenticatedWebAuthenticationDetailsSourceTests extends TestCase {
public final void testAfterPropertiesSetException() {
J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource t = new J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource(); public final void testAfterPropertiesSetException() {
try { J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource t = new J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource();
t.afterPropertiesSet(); try {
fail("AfterPropertiesSet didn't throw expected exception"); t.afterPropertiesSet();
} catch (IllegalArgumentException expected) { fail("AfterPropertiesSet didn't throw expected exception");
} catch (Exception unexpected) { } catch (IllegalArgumentException expected) {
fail("AfterPropertiesSet throws unexpected exception"); } catch (Exception unexpected) {
} fail("AfterPropertiesSet throws unexpected exception");
} }
}
public final void testBuildDetailsHttpServletRequestNoMappedNoUserRoles() {
String[] mappedRoles = new String[] {}; public final void testBuildDetailsHttpServletRequestNoMappedNoUserRoles() {
String[] roles = new String[] {}; String[] mappedRoles = new String[] {};
String[] expectedRoles = new String[] {}; String[] roles = new String[] {};
testDetails(mappedRoles, roles, expectedRoles); String[] expectedRoles = new String[] {};
} testDetails(mappedRoles, roles, expectedRoles);
}
public final void testBuildDetailsHttpServletRequestNoMappedUnmappedUserRoles() {
String[] mappedRoles = new String[] {}; public final void testBuildDetailsHttpServletRequestNoMappedUnmappedUserRoles() {
String[] roles = new String[] { "Role1", "Role2" }; String[] mappedRoles = new String[] {};
String[] expectedRoles = new String[] {}; String[] roles = new String[] { "Role1", "Role2" };
testDetails(mappedRoles, roles, expectedRoles); String[] expectedRoles = new String[] {};
} testDetails(mappedRoles, roles, expectedRoles);
}
public final void testBuildDetailsHttpServletRequestNoUserRoles() {
String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" }; public final void testBuildDetailsHttpServletRequestNoUserRoles() {
String[] roles = new String[] {}; String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
String[] expectedRoles = new String[] {}; String[] roles = new String[] {};
testDetails(mappedRoles, roles, expectedRoles); String[] expectedRoles = new String[] {};
} testDetails(mappedRoles, roles, expectedRoles);
}
public final void testBuildDetailsHttpServletRequestAllUserRoles() {
String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" }; public final void testBuildDetailsHttpServletRequestAllUserRoles() {
String[] roles = new String[] { "Role1", "Role2", "Role3", "Role4" }; String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
String[] expectedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" }; String[] roles = new String[] { "Role1", "Role2", "Role3", "Role4" };
testDetails(mappedRoles, roles, expectedRoles); String[] expectedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
} testDetails(mappedRoles, roles, expectedRoles);
}
public final void testBuildDetailsHttpServletRequestUnmappedUserRoles() {
String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" }; public final void testBuildDetailsHttpServletRequestUnmappedUserRoles() {
String[] roles = new String[] { "Role1", "Role2", "Role3", "Role4", "Role5" }; String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
String[] expectedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" }; String[] roles = new String[] { "Role1", "Role2", "Role3", "Role4", "Role5" };
testDetails(mappedRoles, roles, expectedRoles); String[] expectedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
} testDetails(mappedRoles, roles, expectedRoles);
}
public final void testBuildDetailsHttpServletRequestPartialUserRoles() {
String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" }; public final void testBuildDetailsHttpServletRequestPartialUserRoles() {
String[] roles = new String[] { "Role2", "Role3" }; String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
String[] expectedRoles = new String[] { "Role2", "Role3" }; String[] roles = new String[] { "Role2", "Role3" };
testDetails(mappedRoles, roles, expectedRoles); String[] expectedRoles = new String[] { "Role2", "Role3" };
} testDetails(mappedRoles, roles, expectedRoles);
}
public final void testBuildDetailsHttpServletRequestPartialAndUnmappedUserRoles() {
String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" }; public final void testBuildDetailsHttpServletRequestPartialAndUnmappedUserRoles() {
String[] roles = new String[] { "Role2", "Role3", "Role5" }; String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
String[] expectedRoles = new String[] { "Role2", "Role3" }; String[] roles = new String[] { "Role2", "Role3", "Role5" };
testDetails(mappedRoles, roles, expectedRoles); String[] expectedRoles = new String[] { "Role2", "Role3" };
} testDetails(mappedRoles, roles, expectedRoles);
}
private void testDetails(String[] mappedRoles, String[] userRoles, String[] expectedRoles) {
J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource src = getJ2eeBasedPreAuthenticatedWebAuthenticationDetailsSource(mappedRoles); private void testDetails(String[] mappedRoles, String[] userRoles, String[] expectedRoles) {
Object o = src.buildDetails(getRequest("testUser", userRoles)); J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource src = getJ2eeBasedPreAuthenticatedWebAuthenticationDetailsSource(mappedRoles);
assertNotNull(o); Object o = src.buildDetails(getRequest("testUser", userRoles));
assertTrue("Returned object not of type PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails, actual type: " + o.getClass(), assertNotNull(o);
o instanceof PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails); assertTrue("Returned object not of type PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails, actual type: " + o.getClass(),
PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails details = (PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails) o; o instanceof PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails);
List<GrantedAuthority> gas = details.getGrantedAuthorities(); PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails details = (PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails) o;
assertNotNull("Granted authorities should not be null", gas); List<GrantedAuthority> gas = details.getGrantedAuthorities();
assertEquals(expectedRoles.length, gas.size()); assertNotNull("Granted authorities should not be null", gas);
assertEquals(expectedRoles.length, gas.size());
Collection<String> expectedRolesColl = Arrays.asList(expectedRoles);
Collection<String> gasRolesSet = new HashSet<String>(); Collection<String> expectedRolesColl = Arrays.asList(expectedRoles);
for (int i = 0; i < gas.size(); i++) { Collection<String> gasRolesSet = new HashSet<String>();
gasRolesSet.add(gas.get(i).getAuthority()); for (int i = 0; i < gas.size(); i++) {
} gasRolesSet.add(gas.get(i).getAuthority());
assertTrue("Granted Authorities do not match expected roles", expectedRolesColl.containsAll(gasRolesSet) }
&& gasRolesSet.containsAll(expectedRolesColl)); assertTrue("Granted Authorities do not match expected roles", expectedRolesColl.containsAll(gasRolesSet)
} && gasRolesSet.containsAll(expectedRolesColl));
}
private final J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource getJ2eeBasedPreAuthenticatedWebAuthenticationDetailsSource(
String[] mappedRoles) { private final J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource getJ2eeBasedPreAuthenticatedWebAuthenticationDetailsSource(
J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource result = new J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource(); String[] mappedRoles) {
result.setMappableRolesRetriever(getMappableRolesRetriever(mappedRoles)); J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource result = new J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource();
result.setUserRoles2GrantedAuthoritiesMapper(getJ2eeUserRoles2GrantedAuthoritiesMapper()); result.setMappableRolesRetriever(getMappableRolesRetriever(mappedRoles));
result.setClazz(PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails.class); result.setUserRoles2GrantedAuthoritiesMapper(getJ2eeUserRoles2GrantedAuthoritiesMapper());
result.setClazz(PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails.class);
try {
result.afterPropertiesSet(); try {
} catch (Exception expected) { result.afterPropertiesSet();
fail("AfterPropertiesSet throws unexpected exception"); } catch (Exception expected) {
} fail("AfterPropertiesSet throws unexpected exception");
return result; }
} return result;
}
private MappableAttributesRetriever getMappableRolesRetriever(String[] mappedRoles) {
SimpleMappableAttributesRetriever result = new SimpleMappableAttributesRetriever(); private MappableAttributesRetriever getMappableRolesRetriever(String[] mappedRoles) {
result.setMappableAttributes(mappedRoles); SimpleMappableAttributesRetriever result = new SimpleMappableAttributesRetriever();
return result; result.setMappableAttributes(new HashSet<String>(Arrays.asList(mappedRoles)));
} return result;
}
private Attributes2GrantedAuthoritiesMapper getJ2eeUserRoles2GrantedAuthoritiesMapper() {
SimpleAttributes2GrantedAuthoritiesMapper result = new SimpleAttributes2GrantedAuthoritiesMapper(); private Attributes2GrantedAuthoritiesMapper getJ2eeUserRoles2GrantedAuthoritiesMapper() {
result.setAddPrefixIfAlreadyExisting(false); SimpleAttributes2GrantedAuthoritiesMapper result = new SimpleAttributes2GrantedAuthoritiesMapper();
result.setConvertAttributeToLowerCase(false); result.setAddPrefixIfAlreadyExisting(false);
result.setConvertAttributeToUpperCase(false); result.setConvertAttributeToLowerCase(false);
result.setAttributePrefix(""); result.setConvertAttributeToUpperCase(false);
return result; result.setAttributePrefix("");
} return result;
}
private final HttpServletRequest getRequest(final String userName,final String[] aRoles)
{ private final HttpServletRequest getRequest(final String userName,final String[] aRoles)
MockHttpServletRequest req = new MockHttpServletRequest() { {
private Set<String> roles = new HashSet<String>(Arrays.asList(aRoles)); MockHttpServletRequest req = new MockHttpServletRequest() {
public boolean isUserInRole(String arg0) { private Set<String> roles = new HashSet<String>(Arrays.asList(aRoles));
return roles.contains(arg0); public boolean isUserInRole(String arg0) {
} return roles.contains(arg0);
}; }
req.setRemoteUser(userName); };
return req; req.setRemoteUser(userName);
} return req;
} }
}