SEC-302: Add rolePrefix property to SecurityContextHolderAwareRequestFilter.

This commit is contained in:
Luke Taylor 2007-09-11 17:29:47 +00:00
parent 6a6bafa219
commit c0f5230667
5 changed files with 64 additions and 71 deletions

View File

@ -41,11 +41,16 @@ import javax.servlet.http.HttpSession;
/** /**
* Provides request parameters, headers and cookies from either an original request or a saved request.<p>Note that * Provides request parameters, headers and cookies from either an original request or a saved request.
* not all request parameters in the original request are emulated by this wrapper. Nevertheless, the important data *
* from the original request is emulated and this should prove adequate for most purposes (in particular standard HTTP * <p>Note that not all request parameters in the original request are emulated by this wrapper.
* GET and POST operations).</p> * Nevertheless, the important data from the original request is emulated and this should prove
* <p>Added into a request by {@link org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter}.</p> * adequate for most purposes (in particular standard HTTP GET and POST operations).</p>
*
* <p>Added into a request by {@link org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter}.</p>
*
*
* @see SecurityContextHolderAwareRequestFilter
* *
* @author Andrey Grebnev * @author Andrey Grebnev
* @author Ben Alex * @author Ben Alex
@ -72,8 +77,8 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
public SavedRequestAwareWrapper(HttpServletRequest request, PortResolver portResolver) { public SavedRequestAwareWrapper(HttpServletRequest request, PortResolver portResolver, String rolePrefix) {
super(request,portResolver); super(request, portResolver, rolePrefix);
HttpSession session = request.getSession(false); HttpSession session = request.getSession(false);
@ -113,8 +118,6 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
/** /**
* The default behavior of this method is to return getCookies() on the wrapped request object. * The default behavior of this method is to return getCookies() on the wrapped request object.
*
* @return DOCUMENT ME!
*/ */
public Cookie[] getCookies() { public Cookie[] getCookies() {
if (savedRequest == null) { if (savedRequest == null) {
@ -129,12 +132,6 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
/** /**
* The default behavior of this method is to return getDateHeader(String name) on the wrapped request * The default behavior of this method is to return getDateHeader(String name) on the wrapped request
* object. * object.
*
* @param name DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws IllegalArgumentException DOCUMENT ME!
*/ */
public long getDateHeader(String name) { public long getDateHeader(String name) {
if (savedRequest == null) { if (savedRequest == null) {
@ -143,13 +140,13 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
String value = getHeader(name); String value = getHeader(name);
if (value == null) { if (value == null) {
return (-1L); return -1L;
} }
// Attempt to convert the date header in a variety of formats // Attempt to convert the date header in a variety of formats
long result = FastHttpDateFormat.parseDate(value, formats); long result = FastHttpDateFormat.parseDate(value, formats);
if (result != (-1L)) { if (result != -1L) {
return result; return result;
} }
@ -159,10 +156,6 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
/** /**
* The default behavior of this method is to return getHeader(String name) on the wrapped request object. * The default behavior of this method is to return getHeader(String name) on the wrapped request object.
*
* @param name DOCUMENT ME!
*
* @return DOCUMENT ME!
*/ */
public String getHeader(String name) { public String getHeader(String name) {
if (savedRequest == null) { if (savedRequest == null) {
@ -183,8 +176,6 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
/** /**
* The default behavior of this method is to return getHeaderNames() on the wrapped request object. * The default behavior of this method is to return getHeaderNames() on the wrapped request object.
*
* @return DOCUMENT ME!
*/ */
public Enumeration getHeaderNames() { public Enumeration getHeaderNames() {
if (savedRequest == null) { if (savedRequest == null) {
@ -196,10 +187,6 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
/** /**
* The default behavior of this method is to return getHeaders(String name) on the wrapped request object. * The default behavior of this method is to return getHeaders(String name) on the wrapped request object.
*
* @param name DOCUMENT ME!
*
* @return DOCUMENT ME!
*/ */
public Enumeration getHeaders(String name) { public Enumeration getHeaders(String name) {
if (savedRequest == null) { if (savedRequest == null) {
@ -212,10 +199,6 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
/** /**
* The default behavior of this method is to return getIntHeader(String name) on the wrapped request * The default behavior of this method is to return getIntHeader(String name) on the wrapped request
* object. * object.
*
* @param name DOCUMENT ME!
*
* @return DOCUMENT ME!
*/ */
public int getIntHeader(String name) { public int getIntHeader(String name) {
if (savedRequest == null) { if (savedRequest == null) {
@ -224,17 +207,15 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
String value = getHeader(name); String value = getHeader(name);
if (value == null) { if (value == null) {
return (-1); return -1;
} else { } else {
return (Integer.parseInt(value)); return Integer.parseInt(value);
} }
} }
} }
/** /**
* The default behavior of this method is to return getLocale() on the wrapped request object. * The default behavior of this method is to return getLocale() on the wrapped request object.
*
* @return DOCUMENT ME!
*/ */
public Locale getLocale() { public Locale getLocale() {
if (savedRequest == null) { if (savedRequest == null) {
@ -260,7 +241,6 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
/** /**
* The default behavior of this method is to return getLocales() on the wrapped request object. * The default behavior of this method is to return getLocales() on the wrapped request object.
* *
* @return DOCUMENT ME!
*/ */
public Enumeration getLocales() { public Enumeration getLocales() {
if (savedRequest == null) { if (savedRequest == null) {
@ -282,7 +262,6 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
/** /**
* The default behavior of this method is to return getMethod() on the wrapped request object. * The default behavior of this method is to return getMethod() on the wrapped request object.
* *
* @return DOCUMENT ME!
*/ */
public String getMethod() { public String getMethod() {
if (savedRequest == null) { if (savedRequest == null) {
@ -295,10 +274,6 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
/** /**
* The default behavior of this method is to return getParameter(String name) on the wrapped request * The default behavior of this method is to return getParameter(String name) on the wrapped request
* object. * object.
*
* @param name DOCUMENT ME!
*
* @return DOCUMENT ME!
*/ */
public String getParameter(String name) { public String getParameter(String name) {
/* /*
@ -342,8 +317,6 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
/** /**
* The default behavior of this method is to return getParameterMap() on the wrapped request object. * The default behavior of this method is to return getParameterMap() on the wrapped request object.
*
* @return DOCUMENT ME!
*/ */
public Map getParameterMap() { public Map getParameterMap() {
if (savedRequest == null) { if (savedRequest == null) {
@ -355,8 +328,6 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
/** /**
* The default behavior of this method is to return getParameterNames() on the wrapped request object. * The default behavior of this method is to return getParameterNames() on the wrapped request object.
*
* @return DOCUMENT ME!
*/ */
public Enumeration getParameterNames() { public Enumeration getParameterNames() {
if (savedRequest == null) { if (savedRequest == null) {
@ -369,10 +340,6 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
/** /**
* The default behavior of this method is to return getParameterValues(String name) on the wrapped request * The default behavior of this method is to return getParameterValues(String name) on the wrapped request
* object. * object.
*
* @param name DOCUMENT ME!
*
* @return DOCUMENT ME!
*/ */
public String[] getParameterValues(String name) { public String[] getParameterValues(String name) {
if (savedRequest == null) { if (savedRequest == null) {

View File

@ -53,6 +53,7 @@ public class SecurityContextHolderAwareRequestFilter implements Filter {
private Class wrapperClass = SavedRequestAwareWrapper.class; private Class wrapperClass = SavedRequestAwareWrapper.class;
private Constructor constructor; private Constructor constructor;
private PortResolver portResolver = new PortResolverImpl(); private PortResolver portResolver = new PortResolverImpl();
private String rolePrefix;
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
@ -65,14 +66,15 @@ public class SecurityContextHolderAwareRequestFilter implements Filter {
if (!wrapperClass.isAssignableFrom(request.getClass())) { if (!wrapperClass.isAssignableFrom(request.getClass())) {
if (constructor == null) { if (constructor == null) {
try { try {
constructor = wrapperClass.getConstructor(new Class[] {HttpServletRequest.class, PortResolver.class}); constructor = wrapperClass.getConstructor(
new Class[] {HttpServletRequest.class, PortResolver.class, String.class});
} catch (Exception ex) { } catch (Exception ex) {
ReflectionUtils.handleReflectionException(ex); ReflectionUtils.handleReflectionException(ex);
} }
} }
try { try {
request = (HttpServletRequest) constructor.newInstance(new Object[] {request, portResolver}); request = (HttpServletRequest) constructor.newInstance(new Object[] {request, portResolver, rolePrefix});
} catch (Exception ex) { } catch (Exception ex) {
ReflectionUtils.handleReflectionException(ex); ReflectionUtils.handleReflectionException(ex);
} }
@ -93,4 +95,9 @@ public class SecurityContextHolderAwareRequestFilter implements Filter {
Assert.isTrue(HttpServletRequest.class.isAssignableFrom(wrapperClass), "Wrapper must be a HttpServletRequest"); Assert.isTrue(HttpServletRequest.class.isAssignableFrom(wrapperClass), "Wrapper must be a HttpServletRequest");
this.wrapperClass = wrapperClass; this.wrapperClass = wrapperClass;
} }
public void setRolePrefix(String rolePrefix) {
Assert.notNull(rolePrefix, "Role prefix must not be null");
this.rolePrefix = rolePrefix.trim();
}
} }

View File

@ -36,6 +36,8 @@ import javax.servlet.http.HttpServletRequestWrapper;
* SecurityContextHolderAwareRequestWrapper#isUserInRole(java.lang.String)} and {@link * SecurityContextHolderAwareRequestWrapper#isUserInRole(java.lang.String)} and {@link
* javax.servlet.http.HttpServletRequestWrapper#getRemoteUser()} responses. * javax.servlet.http.HttpServletRequestWrapper#getRemoteUser()} responses.
* *
* @see SecurityContextHolderAwareRequestFilter
*
* @author Orlando Garcia Carmona * @author Orlando Garcia Carmona
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
@ -45,10 +47,21 @@ public class SecurityContextHolderAwareRequestWrapper extends HttpServletRequest
private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl(); private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
/**
* The prefix passed by the filter. It will be prepended to any supplied role values before
* comparing it with the roles obtained from the security context.
*/
private String rolePrefix;
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
public SecurityContextHolderAwareRequestWrapper(HttpServletRequest request, PortResolver portResolver) { public SecurityContextHolderAwareRequestWrapper(
HttpServletRequest request,
PortResolver portResolver,
String rolePrefix) {
super(request); super(request);
this.rolePrefix = rolePrefix;
} }
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
@ -107,6 +120,10 @@ public class SecurityContextHolderAwareRequestWrapper extends HttpServletRequest
private boolean isGranted(String role) { private boolean isGranted(String role) {
Authentication auth = getAuthentication(); Authentication auth = getAuthentication();
if( rolePrefix != null ) {
role = rolePrefix + role;
}
if ((auth == null) || (auth.getPrincipal() == null) || (auth.getAuthorities() == null)) { if ((auth == null) || (auth.getPrincipal() == null) || (auth.getAuthorities() == null)) {
return false; return false;
} }

View File

@ -39,7 +39,6 @@ public class SecurityContextHolderAwareRequestFilterTests extends TestCase {
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
public SecurityContextHolderAwareRequestFilterTests() { public SecurityContextHolderAwareRequestFilterTests() {
super();
} }
public SecurityContextHolderAwareRequestFilterTests(String arg0) { public SecurityContextHolderAwareRequestFilterTests(String arg0) {
@ -48,10 +47,6 @@ public class SecurityContextHolderAwareRequestFilterTests extends TestCase {
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(SecurityContextHolderAwareRequestFilterTests.class);
}
public final void setUp() throws Exception { public final void setUp() throws Exception {
super.setUp(); super.setUp();
} }
@ -78,10 +73,6 @@ public class SecurityContextHolderAwareRequestFilterTests extends TestCase {
this.expectedServletRequest = expectedServletRequest; this.expectedServletRequest = expectedServletRequest;
} }
private MockFilterChain() {
super();
}
public void doFilter(ServletRequest request, ServletResponse response) public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException { throws IOException, ServletException {
if (request.getClass().isAssignableFrom(expectedServletRequest)) { if (request.getClass().isAssignableFrom(expectedServletRequest)) {

View File

@ -50,8 +50,7 @@ public class SecurityContextHolderAwareRequestWrapperTests extends TestCase {
SecurityContextHolder.clearContext(); SecurityContextHolder.clearContext();
} }
public void testCorrectOperationWithStringBasedPrincipal() public void testCorrectOperationWithStringBasedPrincipal() throws Exception {
throws Exception {
Authentication auth = new TestingAuthenticationToken("marissa", "koala", Authentication auth = new TestingAuthenticationToken("marissa", "koala",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FOO")}); new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FOO")});
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
@ -59,7 +58,7 @@ public class SecurityContextHolderAwareRequestWrapperTests extends TestCase {
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/"); request.setRequestURI("/");
SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request, new PortResolverImpl()); SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request, new PortResolverImpl(), "");
assertEquals("marissa", wrapper.getRemoteUser()); assertEquals("marissa", wrapper.getRemoteUser());
assertTrue(wrapper.isUserInRole("ROLE_FOO")); assertTrue(wrapper.isUserInRole("ROLE_FOO"));
@ -67,8 +66,20 @@ public class SecurityContextHolderAwareRequestWrapperTests extends TestCase {
assertEquals(auth, wrapper.getUserPrincipal()); assertEquals(auth, wrapper.getUserPrincipal());
} }
public void testCorrectOperationWithUserDetailsBasedPrincipal() public void testUseOfRolePrefixMeansItIsntNeededWhenCallngIsUserInRole() {
throws Exception { Authentication auth = new TestingAuthenticationToken("marissa", "koala",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_FOO")});
SecurityContextHolder.getContext().setAuthentication(auth);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/");
SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request, new PortResolverImpl(), "ROLE_");
assertTrue(wrapper.isUserInRole("FOO"));
}
public void testCorrectOperationWithUserDetailsBasedPrincipal() throws Exception {
Authentication auth = new TestingAuthenticationToken(new User("marissaAsUserDetails", "koala", true, true, Authentication auth = new TestingAuthenticationToken(new User("marissaAsUserDetails", "koala", true, true,
true, true, new GrantedAuthority[] {}), "koala", true, true, new GrantedAuthority[] {}), "koala",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_HELLO"), new GrantedAuthorityImpl("ROLE_FOOBAR")}); new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_HELLO"), new GrantedAuthorityImpl("ROLE_FOOBAR")});
@ -77,7 +88,7 @@ public class SecurityContextHolderAwareRequestWrapperTests extends TestCase {
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/"); request.setRequestURI("/");
SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request, new PortResolverImpl()); SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request, new PortResolverImpl(), "");
assertEquals("marissaAsUserDetails", wrapper.getRemoteUser()); assertEquals("marissaAsUserDetails", wrapper.getRemoteUser());
assertFalse(wrapper.isUserInRole("ROLE_FOO")); assertFalse(wrapper.isUserInRole("ROLE_FOO"));
@ -87,19 +98,19 @@ public class SecurityContextHolderAwareRequestWrapperTests extends TestCase {
assertEquals(auth, wrapper.getUserPrincipal()); assertEquals(auth, wrapper.getUserPrincipal());
} }
public void testNullAuthenticationHandling() throws Exception { public void testRoleIsntHeldIfAuthenticationIsNull() throws Exception {
SecurityContextHolder.getContext().setAuthentication(null); SecurityContextHolder.getContext().setAuthentication(null);
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/"); request.setRequestURI("/");
SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request,new PortResolverImpl()); SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request,new PortResolverImpl(), "");
assertNull(wrapper.getRemoteUser()); assertNull(wrapper.getRemoteUser());
assertFalse(wrapper.isUserInRole("ROLE_ANY")); assertFalse(wrapper.isUserInRole("ROLE_ANY"));
assertNull(wrapper.getUserPrincipal()); assertNull(wrapper.getUserPrincipal());
} }
public void testNullPrincipalHandling() throws Exception { public void testRolesArentHeldIfAuthenticationPrincipalIsNull() throws Exception {
Authentication auth = new TestingAuthenticationToken(null, "koala", Authentication auth = new TestingAuthenticationToken(null, "koala",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_HELLO"), new GrantedAuthorityImpl("ROLE_FOOBAR")}); new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_HELLO"), new GrantedAuthorityImpl("ROLE_FOOBAR")});
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
@ -107,7 +118,7 @@ public class SecurityContextHolderAwareRequestWrapperTests extends TestCase {
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/"); request.setRequestURI("/");
SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request, new PortResolverImpl()); SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request, new PortResolverImpl(), "");
assertNull(wrapper.getRemoteUser()); assertNull(wrapper.getRemoteUser());
assertFalse(wrapper.isUserInRole("ROLE_HELLO")); // principal is null, so reject assertFalse(wrapper.isUserInRole("ROLE_HELLO")); // principal is null, so reject