added check for role
This commit is contained in:
Scott Battaglia 2009-09-22 15:26:49 +00:00
parent bdb354531e
commit b16412731d
3 changed files with 153 additions and 31 deletions

View File

@ -67,7 +67,7 @@
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml</artifactId>
<version>1.1b</version>
<version>1.1</version>
<type>jar</type>
<scope>provided</scope>
<optional>true</optional>

View File

@ -5,9 +5,9 @@
*/
package org.jasig.cas.client.util;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
@ -18,20 +18,34 @@ import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.security.Principal;
import java.util.Collection;
import java.util.Iterator;
/**
* Implementation of a filter that wraps the normal HttpServletRequest with a
* wrapper that overrides the getRemoteUser method to retrieve the user from the
* CAS Assertion.
* wrapper that overrides the following methods to provide data from the
* CAS Assertion:
* <ul>
* <li>{@link HttpServletRequest#getUserPrincipal()}</li>
* <li>{@link HttpServletRequest#getRemoteUser()}</li>
* <li>{@link HttpServletRequest#isUserInRole(String)}</li>
* </ul>
* <p/>
* This filter needs to be configured in the chain so that it executes after
* both the authentication and the validation filters.
*
* @author Scott Battaglia
* @author Marvin S. Addison
* @version $Revision: 11729 $ $Date: 2007-09-26 14:22:30 -0400 (Tue, 26 Sep 2007) $
* @since 3.0
*/
public final class HttpServletRequestWrapperFilter implements Filter {
public final class HttpServletRequestWrapperFilter extends AbstractConfigurationFilter {
/** Name of the attribute used to answer role membership queries */
private String roleAttribute;
/** Whether or not to ignore case in role membership queries */
private boolean ignoreCase;
public void destroy() {
// nothing to do
@ -42,16 +56,13 @@ public final class HttpServletRequestWrapperFilter implements Filter {
* <code>request.getRemoteUser</code> to the underlying Assertion object
* stored in the user session.
*/
public void doFilter(final ServletRequest servletRequest,
final ServletResponse servletResponse, final FilterChain filterChain)
throws IOException, ServletException {
final Principal principal = retrievePrincipalFromSessionOrRequest(servletRequest);
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
final AttributePrincipal principal = retrievePrincipalFromSessionOrRequest(servletRequest);
filterChain.doFilter(new CasHttpServletRequestWrapper(
(HttpServletRequest) servletRequest, principal), servletResponse);
filterChain.doFilter(new CasHttpServletRequestWrapper((HttpServletRequest) servletRequest, principal), servletResponse);
}
protected Principal retrievePrincipalFromSessionOrRequest(final ServletRequest servletRequest) {
protected AttributePrincipal retrievePrincipalFromSessionOrRequest(final ServletRequest servletRequest) {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpSession session = request.getSession(false);
final Assertion assertion = (Assertion) (session == null ? request.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION) : session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION));
@ -60,14 +71,15 @@ public final class HttpServletRequestWrapperFilter implements Filter {
}
public void init(final FilterConfig filterConfig) throws ServletException {
// nothing to do
this.roleAttribute = getPropertyFromInitParams(filterConfig, "roleAttribute", null);
this.ignoreCase = Boolean.parseBoolean(getPropertyFromInitParams(filterConfig, "ignoreCase", "false"));
}
final class CasHttpServletRequestWrapper extends HttpServletRequestWrapper {
private final Principal principal;
private final AttributePrincipal principal;
CasHttpServletRequestWrapper(final HttpServletRequest request, final Principal principal) {
CasHttpServletRequestWrapper(final HttpServletRequest request, final AttributePrincipal principal) {
super(request);
this.principal = principal;
}
@ -79,5 +91,50 @@ public final class HttpServletRequestWrapperFilter implements Filter {
public String getRemoteUser() {
return principal != null ? this.principal.getName() : null;
}
public boolean isUserInRole(final String role) {
if (CommonUtils.isBlank(role)) {
log.debug("No valid role provided. Returning false.");
return false;
}
if (this.principal == null) {
log.debug("No Principal in Request. Returning false.");
return false;
}
if (CommonUtils.isBlank(roleAttribute)) {
log.debug("No Role Attribute Configured. Returning false.");
return false;
}
final Object value = this.principal.getAttributes().get(roleAttribute);
if (value instanceof Collection) {
for (final Iterator iter = ((Collection) value).iterator(); iter.hasNext();) {
if (rolesEqual(role, iter.next())) {
log.debug("User [" + getRemoteUser() + "] is in role [" + role + "]: " + true);
return true;
}
}
}
final boolean isMember = rolesEqual(role, value);
log.debug("User [" + getRemoteUser() + "] is in role [" + role + "]: " + isMember);
return isMember;
}
/**
* Determines whether the given role is equal to the candidate
* role attribute taking into account case sensitivity.
*
* @param given Role under consideration.
* @param candidate Role that the current user possesses.
*
* @return True if roles are equal, false otherwise.
*/
private boolean rolesEqual(final String given, final Object candidate) {
return ignoreCase ? given.equalsIgnoreCase(candidate.toString()) : given.equals(candidate);
}
}
}

View File

@ -6,7 +6,11 @@
package org.jasig.cas.client.util;
import junit.framework.TestCase;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.authentication.AttributePrincipalImpl;
import org.jasig.cas.client.validation.AssertionImpl;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
@ -17,6 +21,9 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* Tests for the HttpServletRequestWrapperFilter.
@ -28,33 +35,91 @@ import java.io.IOException;
public final class HttpServletRequestWrapperFilterTests extends TestCase {
private HttpServletRequestWrapperFilter filter = new HttpServletRequestWrapperFilter();
protected HttpServletRequest mockRequest;
protected void setUp() throws Exception {
this.filter.init(null);
this.filter.destroy();
}
public void testWrappedRequest() throws Exception {
final HttpServletRequestWrapperFilter filter = new HttpServletRequestWrapperFilter();
filter.init(new MockFilterConfig());
final MockHttpServletRequest request = new MockHttpServletRequest();
final MockHttpSession session = new MockHttpSession();
final FilterChain filterChain = new FilterChain() {
session.setAttribute(
AbstractCasFilter.CONST_CAS_ASSERTION,
new AssertionImpl("test"));
request.setSession(session);
filter.doFilter(request, new MockHttpServletResponse(), createFilterChain());
assertEquals("test", this.mockRequest.getRemoteUser());
filter.destroy();
}
public void testIsUserInRole() throws Exception {
final MockHttpServletRequest request = new MockHttpServletRequest();
final MockHttpSession session = new MockHttpSession();
final MockFilterConfig config = new MockFilterConfig();
config.addInitParameter("roleAttribute", "memberOf");
final HttpServletRequestWrapperFilter filter = new HttpServletRequestWrapperFilter();
filter.init(config);
final Map attributes = new HashMap();
attributes.put("memberOf", "administrators");
final AttributePrincipal principal = new AttributePrincipalImpl("alice", attributes);
session.setAttribute(
AbstractCasFilter.CONST_CAS_ASSERTION,
new AssertionImpl(principal));
request.setSession(session);
filter.doFilter(request, new MockHttpServletResponse(), createFilterChain());
assertEquals("alice", this.mockRequest.getRemoteUser());
assertTrue(this.mockRequest.isUserInRole("administrators"));
assertFalse(this.mockRequest.isUserInRole("ADMINISTRATORS"));
assertFalse(this.mockRequest.isUserInRole("users"));
assertFalse(this.mockRequest.isUserInRole(null));
filter.destroy();
}
public void testIsUserInRoleCaseInsensitive() throws Exception {
final MockHttpServletRequest request = new MockHttpServletRequest();
final MockHttpSession session = new MockHttpSession();
final MockFilterConfig config = new MockFilterConfig();
config.addInitParameter("roleAttribute", "groupMembership");
config.addInitParameter("ignoreCase", "true");
final HttpServletRequestWrapperFilter filter = new HttpServletRequestWrapperFilter();
filter.init(config);
final Map attributes = new HashMap();
attributes.put("groupMembership", Arrays.asList(new Object[] {"animals", "ducks"}));
final AttributePrincipal principal = new AttributePrincipalImpl("daffy", attributes);
session.setAttribute(
AbstractCasFilter.CONST_CAS_ASSERTION,
new AssertionImpl(principal));
request.setSession(session);
filter.doFilter(request, new MockHttpServletResponse(), createFilterChain());
assertEquals("daffy", this.mockRequest.getRemoteUser());
assertTrue(this.mockRequest.isUserInRole("animals"));
assertTrue(this.mockRequest.isUserInRole("ANIMALS"));
assertTrue(this.mockRequest.isUserInRole("ducks"));
assertTrue(this.mockRequest.isUserInRole("DUCKS"));
assertFalse(this.mockRequest.isUserInRole("varmints"));
assertFalse(this.mockRequest.isUserInRole(""));
filter.destroy();
}
private FilterChain createFilterChain() {
return new FilterChain() {
public void doFilter(ServletRequest request,
ServletResponse response) throws IOException, ServletException {
HttpServletRequestWrapperFilterTests.this.mockRequest = (HttpServletRequest) request;
}
};
session.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION,
new AssertionImpl("test"));
request.setSession(session);
this.filter.doFilter(request, new MockHttpServletResponse(),
filterChain);
assertEquals("test", this.mockRequest.getRemoteUser());
}
}