Significantly refactor "well-known location model" to authentication processing mechanism and HttpSessionContextIntegrationFilter model.

This commit is contained in:
Ben Alex 2005-02-21 06:48:31 +00:00
parent ba02d45677
commit dda66a0454
63 changed files with 1332 additions and 1345 deletions

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,7 +16,14 @@
package net.sf.acegisecurity.adapters.jboss;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.ui.AbstractIntegrationFilter;
import net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.security.Principal;
@ -28,33 +35,88 @@ import javax.naming.NamingException;
import javax.security.auth.Subject;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* Populates a {@link net.sf.acegisecurity.context.SecureContext} from JBoss'
* <code>java:comp/env/security/subject</code>.
* Populates a {@link net.sf.acegisecurity.context.security.SecureContext} from
* JBoss' <code>java:comp/env/security/subject</code>.
*
* <p>
* See {@link AbstractIntegrationFilter} for further information.
* This filter <b>never</b> preserves the <code>Authentication</code> on the
* <code>ContextHolder</code> - it is replaced every request.
* </p>
*
* <p>
* See {@link HttpSessionContextIntegrationFilter} for further information.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class JbossIntegrationFilter extends AbstractIntegrationFilter {
public class JbossIntegrationFilter implements Filter {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(JbossIntegrationFilter.class);
//~ Methods ================================================================
/**
* Not supported for this type of well-known location.
*
* @param request DOCUMENT ME!
* @param authentication DOCUMENT ME!
* Does nothing. We use IoC container lifecycle services instead.
*/
public void commitToContainer(ServletRequest request,
Authentication authentication) {}
public void destroy() {}
public Object extractFromContainer(ServletRequest request) {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
SecureContext sc = SecureContextUtils.getSecureContext();
Object principal = extractFromContainer(request);
if ((principal != null) && principal instanceof Authentication) {
sc.setAuthentication((Authentication) principal);
if (logger.isDebugEnabled()) {
logger.debug(
"ContextHolder updated with Authentication from container: '"
+ principal + "'");
}
} else {
if (logger.isDebugEnabled()) {
logger.debug(
"ContextHolder not set with new Authentication as Principal was: '"
+ principal + "'");
}
}
chain.doFilter(request, response);
}
/**
* Does nothing. We use IoC container lifecycle services instead.
*
* @param arg0 ignored
*
* @throws ServletException ignored
*/
public void init(FilterConfig arg0) throws ServletException {}
/**
* Provided so that unit tests can override.
*
* @return a <code>Context</code> that can be used for lookup
*
* @throws NamingException DOCUMENT ME!
*/
protected Context getLookupContext() throws NamingException {
return new InitialContext();
}
private Object extractFromContainer(ServletRequest request) {
Subject subject = null;
try {
@ -94,15 +156,4 @@ public class JbossIntegrationFilter extends AbstractIntegrationFilter {
return null;
}
/**
* Provided so that unit tests can override.
*
* @return a <code>Context</code> that can be used for lookup
*
* @throws NamingException DOCUMENT ME!
*/
protected Context getLookupContext() throws NamingException {
return new InitialContext();
}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,9 +20,14 @@ import junit.framework.TestCase;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.adapters.PrincipalAcegiUserToken;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContextUtils;
import org.springframework.mock.web.MockHttpServletRequest;
import java.io.IOException;
import java.security.Principal;
import java.util.HashSet;
@ -32,6 +37,13 @@ import javax.naming.Context;
import javax.security.auth.Subject;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* Tests {@link JbossIntegrationFilter}.
@ -52,15 +64,11 @@ public class JbossIntegrationFilterTests extends TestCase {
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
}
public static void main(String[] args) {
junit.textui.TestRunner.run(JbossIntegrationFilterTests.class);
}
public void testCorrectOperation() {
public void testCorrectOperation() throws Exception {
PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")});
@ -68,59 +76,77 @@ public class JbossIntegrationFilterTests extends TestCase {
JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(
makeIntoSubject(principal)));
Object result = filter.extractFromContainer(new MockHttpServletRequest());
MockHttpServletRequest request = new MockHttpServletRequest();
MockFilterChain chain = new MockFilterChain();
if (!(result instanceof PrincipalAcegiUserToken)) {
fail("Should have returned PrincipalAcegiUserToken");
}
filter.doFilter(request, null, chain);
PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result;
assertEquals(principal, result);
MockHttpServletRequest mockRequest = new MockHttpServletRequest();
mockRequest.setUserPrincipal(principal);
filter.commitToContainer(mockRequest, principal);
assertEquals(principal,
SecureContextUtils.getSecureContext().getAuthentication());
ContextHolder.setContext(null);
}
public void testReturnsNullIfContextReturnsSomethingOtherThanASubject() {
public void testReturnsNullIfContextReturnsSomethingOtherThanASubject()
throws Exception {
JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(
"THIS_IS_NOT_A_SUBJECT"));
assertEquals(null,
filter.extractFromContainer(new MockHttpServletRequest(null, null)));
MockHttpServletRequest request = new MockHttpServletRequest();
MockFilterChain chain = new MockFilterChain();
filter.doFilter(request, null, chain);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
}
public void testReturnsNullIfInitialContextHasNullPrincipal() {
public void testReturnsNullIfInitialContextHasNullPrincipal()
throws Exception {
JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(
makeIntoSubject(null)));
assertEquals(null,
filter.extractFromContainer(new MockHttpServletRequest(null, null)));
MockHttpServletRequest request = new MockHttpServletRequest();
MockFilterChain chain = new MockFilterChain();
filter.doFilter(request, null, chain);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
}
public void testReturnsNullIfInitialContextHasNullSubject() {
public void testReturnsNullIfInitialContextHasNullSubject()
throws Exception {
JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(
null));
assertEquals(null,
filter.extractFromContainer(new MockHttpServletRequest(null, null)));
MockHttpServletRequest request = new MockHttpServletRequest();
MockFilterChain chain = new MockFilterChain();
filter.doFilter(request, null, chain);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
}
public void testReturnsNullIfInitialContextIsNull() {
public void testReturnsNullIfInitialContextIsNull()
throws Exception {
JbossIntegrationFilter filter = new MockJbossIntegrationFilter(null);
Object result = filter.extractFromContainer(new MockHttpServletRequest(
null, null));
assertEquals(null, filter.extractFromContainer(null));
MockHttpServletRequest request = new MockHttpServletRequest();
MockFilterChain chain = new MockFilterChain();
filter.doFilter(request, null, chain);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
}
public void testReturnsNullIfPrincipalNotAnAuthenticationImplementation() {
public void testReturnsNullIfPrincipalNotAnAuthenticationImplementation()
throws Exception {
JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(
makeIntoSubject(new Principal() {
public String getName() {
return "MockPrincipal";
}
})));
assertEquals(null,
filter.extractFromContainer(new MockHttpServletRequest(null, null)));
MockHttpServletRequest request = new MockHttpServletRequest();
MockFilterChain chain = new MockFilterChain();
filter.doFilter(request, null, chain);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
}
public void testTestingObjectReturnsInitialContext()
@ -129,10 +155,35 @@ public class JbossIntegrationFilterTests extends TestCase {
assertTrue(filter.getLookupContext() instanceof Context);
}
protected void setUp() throws Exception {
super.setUp();
ContextHolder.setContext(new SecureContextImpl());
}
protected void tearDown() throws Exception {
super.tearDown();
ContextHolder.setContext(null);
}
private void executeFilterInContainerSimulator(FilterConfig filterConfig,
Filter filter, ServletRequest request, ServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
filter.init(filterConfig);
filter.doFilter(request, response, filterChain);
filter.destroy();
}
private Subject makeIntoSubject(Principal principal) {
Set principals = new HashSet();
principals.add(principal);
return new Subject(false, principals, new HashSet(), new HashSet());
}
//~ Inner Classes ==========================================================
private class MockFilterChain implements FilterChain {
public void doFilter(ServletRequest arg0, ServletResponse arg1)
throws IOException, ServletException {}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,7 +29,8 @@ import java.security.Principal;
* </p>
*
* <p>
* Stored in a request {@link net.sf.acegisecurity.context.SecureContext}.
* Stored in a request {@link
* net.sf.acegisecurity.context.security.SecureContext}.
* </p>
*
* @author Ben Alex

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,7 +18,7 @@ package net.sf.acegisecurity;
/**
* Thrown if an authentication request is rejected because there is no {@link
* Authentication} object in the {@link
* net.sf.acegisecurity.context.SecureContext}.
* net.sf.acegisecurity.context.security.SecureContext}.
*
* @author Ben Alex
* @version $Id$

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -25,8 +25,8 @@ package net.sf.acegisecurity;
* object invocation only. The {@link
* net.sf.acegisecurity.intercept.AbstractSecurityInterceptor} will replace
* the <code>Authentication</code> object held in the {@link
* net.sf.acegisecurity.context.SecureContext} for the duration of the secure
* object callback only, returning it to the original
* net.sf.acegisecurity.context.security.SecureContext} for the duration of
* the secure object callback only, returning it to the original
* <code>Authentication</code> object when the callback ends.
* </p>
*

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,27 +16,47 @@
package net.sf.acegisecurity.adapters;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.ui.AbstractIntegrationFilter;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.security.Principal;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
/**
* Populates a {@link net.sf.acegisecurity.context.SecureContext} from the
* container's <code>HttpServletRequest.getUserPrincipal()</code>.
* Populates <code>ContextHolder</code> with the <code>Authentication</code>
* obtained from the container's
* <code>HttpServletRequest.getUserPrincipal()</code>.
*
* <p>
* See {@link AbstractIntegrationFilter} for further information.
* Used this filter with container adapters only.
* </p>
*
* <p>
* This filter <b>never</b> preserves the <code>Authentication</code> on the
* <code>ContextHolder</code> - it is replaced every request.
* </p>
*
* <p>
* See {@link HttpSessionContextIntegrationFilter} for further information.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class HttpRequestIntegrationFilter extends AbstractIntegrationFilter {
public class HttpRequestIntegrationFilter implements Filter {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(HttpRequestIntegrationFilter.class);
@ -44,19 +64,47 @@ public class HttpRequestIntegrationFilter extends AbstractIntegrationFilter {
//~ Methods ================================================================
/**
* Not supported for this type of well-known location.
*
* @param request DOCUMENT ME!
* @param authentication DOCUMENT ME!
* Does nothing. We use IoC container lifecycle services instead.
*/
public void commitToContainer(ServletRequest request,
Authentication authentication) {}
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
SecureContext sc = SecureContextUtils.getSecureContext();
public Object extractFromContainer(ServletRequest request) {
if (request instanceof HttpServletRequest) {
return ((HttpServletRequest) request).getUserPrincipal();
Principal principal = ((HttpServletRequest) request)
.getUserPrincipal();
if ((principal != null) && principal instanceof Authentication) {
sc.setAuthentication((Authentication) principal);
if (logger.isDebugEnabled()) {
logger.debug(
"ContextHolder updated with Authentication from container: '"
+ principal + "'");
}
} else {
if (logger.isDebugEnabled()) {
logger.debug(
"ContextHolder not set with new Authentication as Principal was: '"
+ principal + "'");
}
}
} else {
return null;
throw new IllegalArgumentException(
"Only HttpServletRequest is acceptable");
}
chain.doFilter(request, response);
}
/**
* Does nothing. We use IoC container lifecycle services instead.
*
* @param arg0 ignored
*
* @throws ServletException ignored
*/
public void init(FilterConfig arg0) throws ServletException {}
}

View File

@ -0,0 +1,289 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.acegisecurity.context;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* <p>
* Populates the <code>ContextHolder</code> with information obtained from the
* <code>HttpSession</code>.
* </p>
*
* <p>
* The <code>HttpSession</code> will be queried to retrieve the
* <code>Context</code> that should be stored against the
* <code>ContextHolder</code> for the duration of the web request. At the end
* of the web request, any updates made to the <code>ContextHolder</code> will
* be persisted back to the <code>HttpSession</code> by this filter.
* </p>
*
* <p>
* If a valid <code>Context</code> cannot be obtained from the
* <code>HttpSession</code> for whatever reason, a fresh <code>Context</code>
* will be created and used instead. The created object will be of the
* instance defined by the {@link #setContext(Class)} method.
* </p>
*
* <p>
* No <code>HttpSession</code> will be created by this filter if one does not
* already exist. If at the end of the web request the
* <code>HttpSession</code> does not exist, a <code>HttpSession</code> will
* <b>only</b> be created if the current contents of
* <code>ContextHolder</code> are not {@link
* java.lang.Object#equals(java.lang.Object)} to a <code>new</code> instance
* of {@link #setContext(Class)}. This avoids needless
* <code>HttpSession</code> creation, but automates the storage of changes
* made to the <code>ContextHolder</code>.
* </p>
*
* <P>
* This filter will only execute once per request, to resolve servlet container
* (specifically Weblogic) incompatibilities.
* </p>
*
* <p>
* If for whatever reason no <code>HttpSession</code> should <b>ever</b> be
* created (eg this filter is only being used with Basic authentication or
* similar clients that will never present the same <code>jsessionid</code>
* etc), the {@link #setAllowSessionCreation(boolean)} should be set to
* <code>false</code>. Only do this if you really need to conserve server
* memory and are sure ensure all classes using the <code>ContextHolder</code>
* are designed to have no persistence of the <code>Context</code> between web
* requests.
* </p>
*
* <p>
* This filter MUST be executed BEFORE any authentication procesing mechanisms.
* Authentication processing mechanisms (eg BASIC, CAS processing filters etc)
* expect the <code>ContextHolder</code> to be contain a valid
* <code>SecureContext</code> by the time they execute.
* </p>
*
* @author Ben Alex
* @author Patrick Burleson
* @version $Id$
*/
public class HttpSessionContextIntegrationFilter implements InitializingBean,
Filter {
//~ Static fields/initializers =============================================
protected static final Log logger = LogFactory.getLog(HttpSessionContextIntegrationFilter.class);
private static final String FILTER_APPLIED = "__acegi_session_integration_filter_applied";
public static final String ACEGI_SECURITY_CONTEXT_KEY = "ACEGI_SECURITY_CONTEXT";
//~ Instance fields ========================================================
private Class context;
private Object contextObject;
/**
* Indicates if this filter can create a <code>HttpSession</code> if needed
* (sessions are always created sparingly, but setting this value to false
* will prohibit sessions from ever being created). Defaults to true.
*/
private boolean allowSessionCreation = true;
//~ Methods ================================================================
public void setAllowSessionCreation(boolean allowSessionCreation) {
this.allowSessionCreation = allowSessionCreation;
}
public boolean isAllowSessionCreation() {
return allowSessionCreation;
}
public void setContext(Class secureContext) {
this.context = secureContext;
}
public Class getContext() {
return context;
}
public void afterPropertiesSet() throws Exception {
if ((this.context == null)
|| (!Context.class.isAssignableFrom(this.context))) {
throw new IllegalArgumentException(
"context must be defined and implement Context (typically use net.sf.acegisecurity.context.security.SecureContextImpl)");
}
this.contextObject = generateNewContext();
}
/**
* Does nothing. We use IoC container lifecycle services instead.
*/
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if ((request != null) && (request.getAttribute(FILTER_APPLIED) != null)) {
// ensure that filter is only applied once per request
chain.doFilter(request, response);
} else {
if (request != null) {
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
}
if (ContextHolder.getContext() != null) {
if (logger.isWarnEnabled()) {
logger.warn(
"ContextHolder should have been null but contained: '"
+ ContextHolder.getContext() + "'; setting to null now");
}
ContextHolder.setContext(null);
}
HttpSession httpSession = null;
try {
httpSession = ((HttpServletRequest) request).getSession(false);
} catch (IllegalStateException ignored) {}
if (httpSession != null) {
Object contextObject = httpSession.getAttribute(ACEGI_SECURITY_CONTEXT_KEY);
if (contextObject != null) {
if (contextObject instanceof Context) {
if (logger.isDebugEnabled()) {
logger.debug(
"Obtained from ACEGI_SECURITY_CONTEXT a valid Context and set to ContextHolder: '"
+ contextObject + "'");
}
ContextHolder.setContext((Context) contextObject);
} else {
if (logger.isWarnEnabled()) {
logger.warn(
"ACEGI_SECURITY_CONTEXT did not contain a Context but contained: '"
+ contextObject
+ "'; are you improperly modifying the HttpSession directly (you should always use ContextHolder) or using the HttpSession attribute reserved for this class?");
}
}
} else {
if (logger.isDebugEnabled()) {
logger.debug(
"HttpSession returned null object for ACEGI_SECURITY_CONTEXT");
}
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("No HttpSession currently exists");
}
}
if (ContextHolder.getContext() == null) {
ContextHolder.setContext(generateNewContext());
if (logger.isDebugEnabled()) {
logger.debug(
"As ContextHolder null, setup ContextHolder with a fresh new instance: '"
+ ContextHolder.getContext() + "'");
}
}
// Proceed with chain
chain.doFilter(request, response);
// Store context back to HttpSession
try {
httpSession = ((HttpServletRequest) request).getSession(false);
} catch (IllegalStateException ignored) {}
// Generate a HttpSession only if we need to
if (httpSession == null) {
if (!allowSessionCreation) {
if (logger.isDebugEnabled()) {
logger.debug(
"Whilst ContextHolder contents have changed, the HttpSessionContextIntegrationFilter is prohibited from creating a HttpSession by the allowSessionCreation property being false");
}
} else if (!contextObject.equals(ContextHolder.getContext())) {
if (logger.isDebugEnabled()) {
logger.debug(
"HttpSession being created as ContextHolder contents are non-default");
}
try {
httpSession = ((HttpServletRequest) request).getSession(true);
} catch (IllegalStateException ignored) {}
} else {
if (logger.isDebugEnabled()) {
logger.debug(
"HttpSession still null, but ContextHolder has not changed from default: ' "
+ ContextHolder.getContext()
+ "'; not creating HttpSession or storing ContextHolder contents");
}
}
}
// If HttpSession exists, store current ContextHolder contents
if (httpSession != null) {
httpSession.setAttribute(ACEGI_SECURITY_CONTEXT_KEY,
ContextHolder.getContext());
if (logger.isDebugEnabled()) {
logger.debug("Context stored to HttpSession: '"
+ ContextHolder.getContext() + "'");
}
}
// Remove ContextHolder contents
ContextHolder.setContext(null);
if (logger.isDebugEnabled()) {
logger.debug(
"ContextHolder set to null as request processing completed");
}
}
}
public Context generateNewContext() throws ServletException {
try {
return (Context) this.context.newInstance();
} catch (InstantiationException ie) {
throw new ServletException(ie);
} catch (IllegalAccessException iae) {
throw new ServletException(iae);
}
}
/**
* Does nothing. We use IoC container lifecycle services instead.
*
* @param filterConfig ignored
*
* @throws ServletException ignored
*/
public void init(FilterConfig filterConfig) throws ServletException {}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,12 +13,12 @@
* limitations under the License.
*/
package net.sf.acegisecurity.ui.httpinvoker;
package net.sf.acegisecurity.context.httpinvoker;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.AuthenticationCredentialsNotFoundException;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.security.SecureContext;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,7 +13,7 @@
* limitations under the License.
*/
package net.sf.acegisecurity.ui.rmi;
package net.sf.acegisecurity.context.rmi;
import net.sf.acegisecurity.context.Context;
import net.sf.acegisecurity.context.ContextHolder;
@ -34,10 +34,10 @@ import java.lang.reflect.InvocationTargetException;
*
* <p>
* When constructed on the client via {@link
* net.sf.acegisecurity.ui.rmi.ContextPropagatingRemoteInvocationFactory}, the
* contents of the <code>ContextHolder</code> are stored inside the object.
* The object is then passed to the server that is processing the remote
* invocation. Upon the server invoking the remote invocation, it will
* net.sf.acegisecurity.context.rmi.ContextPropagatingRemoteInvocationFactory},
* the contents of the <code>ContextHolder</code> are stored inside the
* object. The object is then passed to the server that is processing the
* remote invocation. Upon the server invoking the remote invocation, it will
* retrieve the passed contents of the <code>ContextHolder</code> and set them
* to the server-side <code>ContextHolder</code> whilst the target object is
* invoked. When the target invocation has been completed, the server-side

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,7 +13,7 @@
* limitations under the License.
*/
package net.sf.acegisecurity.ui.rmi;
package net.sf.acegisecurity.context.rmi;
import org.aopalliance.intercept.MethodInvocation;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,9 +13,10 @@
* limitations under the License.
*/
package net.sf.acegisecurity.context;
package net.sf.acegisecurity.context.security;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.context.Context;
/**

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,9 +13,11 @@
* limitations under the License.
*/
package net.sf.acegisecurity.context;
package net.sf.acegisecurity.context.security;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.context.ContextImpl;
import net.sf.acegisecurity.context.ContextInvalidException;
/**
@ -39,6 +41,25 @@ public class SecureContextImpl extends ContextImpl implements SecureContext {
return this.authentication;
}
public boolean equals(Object obj) {
if (obj instanceof SecureContextImpl) {
SecureContextImpl test = (SecureContextImpl) obj;
if ((this.getAuthentication() == null)
&& (test.getAuthentication() == null)) {
return true;
}
if ((this.getAuthentication() != null)
&& (test.getAuthentication() != null)
&& this.getAuthentication().equals(test.getAuthentication())) {
return true;
}
}
return false;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(super.toString());

View File

@ -0,0 +1,45 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.acegisecurity.context.security;
import net.sf.acegisecurity.context.ContextHolder;
/**
* A simple static method for quickly accessing the <code>SecureContext</code>.
*
* <p>
* Expects the <code>ContextHolder</code> to be populated and contain a valid
* <code>SecureContext</code>.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class SecureContextUtils {
//~ Methods ================================================================
public static SecureContext getSecureContext() {
if ((ContextHolder.getContext() == null)
|| !(ContextHolder.getContext() instanceof SecureContext)) {
throw new IllegalStateException("ContextHolder invalid: '"
+ ContextHolder.getContext()
+ "': are your filters ordered correctly? HttpSessionContextIntegrationFilter should have already executed by this time (look for it in the stack dump below)");
}
return (SecureContext) ContextHolder.getContext();
}
}

View File

@ -0,0 +1,7 @@
<html>
<body>
Provides a <code>Context</code> that is designed to be compatible with
Acegi Security.
</body>
</html>

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,7 +27,7 @@ import net.sf.acegisecurity.ConfigAttributeDefinition;
import net.sf.acegisecurity.RunAsManager;
import net.sf.acegisecurity.context.Context;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.intercept.event.AuthenticationCredentialsNotFoundEvent;
import net.sf.acegisecurity.intercept.event.AuthenticationFailureEvent;
import net.sf.acegisecurity.intercept.event.AuthorizationFailureEvent;
@ -104,7 +104,6 @@ import java.util.Set;
* object, return the <code>ContextHolder</code> to the object that existed
* after the call to <code>AuthenticationManager</code>.
* </li>
*
* <li>
* If an <code>AfterInvocationManager</code> is defined, invoke the invocation
* manager and allow it to replace the object due to be returned to the

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,7 +20,7 @@ import net.sf.acegisecurity.acl.AclEntry;
import net.sf.acegisecurity.acl.AclManager;
import net.sf.acegisecurity.acl.basic.AbstractBasicAclEntry;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.security.SecureContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,7 +18,7 @@ package net.sf.acegisecurity.taglibs.authz;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.security.SecureContext;
import java.io.IOException;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,14 +18,15 @@ package net.sf.acegisecurity.taglibs.authz;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.security.SecureContext;
import org.springframework.web.util.ExpressionEvaluationUtils;
import java.util.*;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
import java.util.*;
import org.springframework.web.util.ExpressionEvaluationUtils;
/**
@ -70,19 +71,18 @@ public class AuthorizeTag extends TagSupport {
public int doStartTag() throws JspException {
if (((null == ifAllGranted) || "".equals(ifAllGranted))
&& ((null == ifAnyGranted) || "".equals(ifAnyGranted))
&& ((null == ifNotGranted) || "".equals(ifNotGranted))) {
&& ((null == ifAnyGranted) || "".equals(ifAnyGranted))
&& ((null == ifNotGranted) || "".equals(ifNotGranted))) {
return Tag.SKIP_BODY;
}
final Collection granted = getPrincipalAuthorities();
final String evaledIfNotGranted =
ExpressionEvaluationUtils.evaluateString(
"ifNotGranted", ifNotGranted, pageContext);
final String evaledIfNotGranted = ExpressionEvaluationUtils
.evaluateString("ifNotGranted", ifNotGranted, pageContext);
if ((null != evaledIfNotGranted) && !"".equals(evaledIfNotGranted)) {
Set grantedCopy = retainAll(
granted,
Set grantedCopy = retainAll(granted,
parseAuthoritiesString(evaledIfNotGranted));
if (!grantedCopy.isEmpty()) {
@ -90,22 +90,20 @@ public class AuthorizeTag extends TagSupport {
}
}
final String evaledIfAllGranted =
ExpressionEvaluationUtils.evaluateString(
"ifAllGranted", ifAllGranted, pageContext);
final String evaledIfAllGranted = ExpressionEvaluationUtils
.evaluateString("ifAllGranted", ifAllGranted, pageContext);
if ((null != evaledIfAllGranted) && !"".equals(evaledIfAllGranted)) {
if (!granted.containsAll(
parseAuthoritiesString(evaledIfAllGranted))) {
if (!granted.containsAll(parseAuthoritiesString(evaledIfAllGranted))) {
return Tag.SKIP_BODY;
}
}
final String evaledIfAnyGranted =
ExpressionEvaluationUtils.evaluateString(
"ifAnyGranted", ifAnyGranted, pageContext);
final String evaledIfAnyGranted = ExpressionEvaluationUtils
.evaluateString("ifAnyGranted", ifAnyGranted, pageContext);
if ((null != evaledIfAnyGranted) && !"".equals(evaledIfAnyGranted)) {
Set grantedCopy = retainAll(
granted,
Set grantedCopy = retainAll(granted,
parseAuthoritiesString(evaledIfAnyGranted));
if (grantedCopy.isEmpty()) {
@ -148,7 +146,7 @@ public class AuthorizeTag extends TagSupport {
}
private Set retainAll(final Collection granted,
final Set requiredAuthorities) {
final Set requiredAuthorities) {
Set grantedCopy = new HashSet(granted);
grantedCopy.retainAll(requiredAuthorities);

View File

@ -1,232 +0,0 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.acegisecurity.ui;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.context.Context;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* Automatically populates a {@link net.sf.acegisecurity.context.SecureContext}
* from a subclass-provided <code>Authentication</code> object.
*
* <p>
* The container hosting the Acegi Security System for Spring secured
* application is expected to expose an {@link Authentication} object in a
* well-known location. The <code>Authentication</code> object will have been
* created by the Acegi Security System for Spring and placed into the
* well-known location via approaches such as container adapters or container
* sessions.
* </p>
*
* <P>
* Once the <code>Authentication</code> object has been extracted from the
* well-known location, the <code>AbstractIntegrationFilter</code> handles
* putting it into the {@link ContextHolder}. It then removes it once the
* filter chain has completed.
* </p>
*
* <p>
* This filter will not abort if an <code>Authentication</code> object cannot
* be obtained from the well-known location. It will simply continue the
* filter chain as normal.
* </p>
*
* <p>
* If the <code>ContextHolder</code> does not contain a valid {@link
* SecureContext}, one will be created. The created object will be of the
* instance defined by the {@link #setSecureContext(Class)} method.
* </p>
*
* <P>
* This filter will only execute once per request, to resolve servlet container
* (specifically Weblogic) incompatibilities.
* </p>
*
* @author Ben Alex
* @author Patrick Burleson
* @version $Id$
*/
public abstract class AbstractIntegrationFilter implements InitializingBean,
Filter {
//~ Static fields/initializers =============================================
protected static final Log logger = LogFactory.getLog(AbstractIntegrationFilter.class);
private static final String FILTER_APPLIED = "__acegi_integration_filterapplied";
//~ Instance fields ========================================================
private Class secureContext = SecureContextImpl.class;
//~ Methods ================================================================
public void setSecureContext(Class secureContext) {
this.secureContext = secureContext;
}
public Class getSecureContext() {
return secureContext;
}
public void afterPropertiesSet() throws Exception {
if ((this.secureContext == null)
|| (!SecureContext.class.isAssignableFrom(this.secureContext))) {
throw new IllegalArgumentException(
"secureContext must be defined and implement SecureContext");
}
}
/**
* Writes a new <code>Authentication</code> object to the container's
* well-known location, if supported the subclass.
*
* @param request which may be required by the implementing method to
* access the well-known location for the current principal
* @param authentication the new object to be written to the container
*/
public abstract void commitToContainer(ServletRequest request,
Authentication authentication);
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if ((request != null) && (request.getAttribute(FILTER_APPLIED) != null)) {
// ensure that filter is only applied once per request
chain.doFilter(request, response);
} else {
if (request != null) {
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
}
// Populate authentication information
Object extracted = this.extractFromContainer(request);
if (extracted instanceof Authentication) {
if (logger.isDebugEnabled()) {
logger.debug("Authentication '" + extracted
+ "' added to ContextHolder from container");
}
Authentication auth = (Authentication) extracted;
// Get or create existing SecureContext
SecureContext sc = null;
if ((ContextHolder.getContext() == null)
|| !(ContextHolder.getContext() instanceof SecureContext)) {
try {
sc = (SecureContext) this.secureContext.newInstance();
} catch (InstantiationException ie) {
throw new ServletException(ie);
} catch (IllegalAccessException iae) {
throw new ServletException(iae);
}
} else {
sc = (SecureContext) ContextHolder.getContext();
}
// Add Authentication to SecureContext, and save
sc.setAuthentication(auth);
ContextHolder.setContext((Context) sc);
} else {
if (logger.isDebugEnabled()) {
logger.debug(
"Authentication not added to ContextHolder (could not extract an authentication object from the container which is an instance of Authentication)");
}
}
// Proceed with chain
chain.doFilter(request, response);
// Remove authentication information
if ((ContextHolder.getContext() != null)
&& ContextHolder.getContext() instanceof SecureContext) {
// Get context holder
SecureContext secureContext = (SecureContext) ContextHolder
.getContext();
if (logger.isDebugEnabled()) {
logger.debug(
"Updating container with new Authentication object ('"
+ secureContext.getAuthentication()
+ "'), and then removing Authentication from ContextHolder");
}
// Update container with new Authentication object (may have been updated during method invocation)
this.commitToContainer(request,
secureContext.getAuthentication());
// Remove authentication information from ContextHolder
secureContext.setAuthentication(null);
ContextHolder.setContext((Context) secureContext);
} else {
if (logger.isDebugEnabled()) {
logger.debug(
"ContextHolder does not contain any authentication information");
}
}
}
}
/**
* Subclasses must override this method to provide the <code>Object</code>
* that contains the <code>Authentication</code> interface.
*
* <p>
* For convenience we have allowed any <code>Object</code> to be returned
* by subclasses, as the abstract class will ensure class casting safety
* and ignore objects that do not implement <code>Authentication</code>.
* </p>
*
* <p>
* If no <code>Authentication</code> object is available, subclasses should
* return <code>null</code>.
* </p>
*
* <p>
* If the subclass can locate multiple authentication objects, they should
* return the object that was created by the Acegi Security System for
* Spring (ie the object that implements <code>Authentication</code>).
* </p>
*
* @param request the request, which may be of use in extracting the
* authentication object
*
* @return <code>null</code> or an object that implements
* <code>Authentication</code>
*/
public abstract Object extractFromContainer(ServletRequest request);
public void init(FilterConfig filterConfig) throws ServletException {}
}

View File

@ -22,8 +22,10 @@ import net.sf.acegisecurity.AuthenticationServiceException;
import net.sf.acegisecurity.BadCredentialsException;
import net.sf.acegisecurity.DisabledException;
import net.sf.acegisecurity.LockedException;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextUtils;
import net.sf.acegisecurity.providers.cas.ProxyUntrustedException;
import net.sf.acegisecurity.ui.webapp.HttpSessionIntegrationFilter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -34,6 +36,7 @@ import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@ -42,15 +45,13 @@ import javax.servlet.http.HttpServletResponse;
/**
* Abstract processor of HTTP-based authentication requests, which places the
* resulting <code>Authentication</code> object into the
* <code>HttpSession</code>.
* Abstract processor of browser-based HTTP-based authentication requests.
*
* <p>
* This filter is responsible for processing authentication requests. If
* authentication is successful, the resulting {@link Authentication} object
* will be placed into the <code>HttpSession</code> with the attribute defined
* by {@link HttpSessionIntegrationFilter#ACEGI_SECURITY_AUTHENTICATION_KEY}.
* will be placed into the <code>ContextHolder</code>, which is guaranteed to
* have already been created by an earlier filter.
* </p>
*
* <p>
@ -307,6 +308,9 @@ public abstract class AbstractProcessingFilter implements Filter,
}
}
/**
* Does nothing. We use IoC container lifecycle services instead.
*/
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response,
@ -353,6 +357,15 @@ public abstract class AbstractProcessingFilter implements Filter,
chain.doFilter(request, response);
}
/**
* Does nothing. We use IoC container lifecycle services instead.
*
* @param arg0 ignored
*
* @throws ServletException ignored
*/
public void init(FilterConfig arg0) throws ServletException {}
protected void onPreAuthentication(HttpServletRequest request,
HttpServletResponse response) throws IOException {}
@ -390,8 +403,14 @@ public abstract class AbstractProcessingFilter implements Filter,
logger.debug("Authentication success: " + authResult.toString());
}
request.getSession().setAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY,
authResult);
SecureContext sc = SecureContextUtils.getSecureContext();
sc.setAuthentication(authResult);
if (logger.isDebugEnabled()) {
logger.debug(
"Updated ContextHolder to contain the following Authentication: '"
+ authResult + "'");
}
String targetUrl = (String) request.getSession().getAttribute(ACEGI_SECURITY_TARGET_URL_KEY);
request.getSession().removeAttribute(ACEGI_SECURITY_TARGET_URL_KEY);
@ -418,6 +437,14 @@ public abstract class AbstractProcessingFilter implements Filter,
protected void unsuccessfulAuthentication(HttpServletRequest request,
HttpServletResponse response, AuthenticationException failed)
throws IOException {
SecureContext sc = SecureContextUtils.getSecureContext();
sc.setAuthentication(null);
ContextHolder.setContext(sc);
if (logger.isDebugEnabled()) {
logger.debug("Updated ContextHolder to contain null Authentication");
}
String failureUrl = authenticationFailureUrl;
if (failed instanceof AuthenticationServiceException
@ -451,7 +478,6 @@ public abstract class AbstractProcessingFilter implements Filter,
request.getSession().setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY,
failed);
request.getSession().removeAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY);
onUnsuccessfulAuthentication(request, response);

View File

@ -18,10 +18,13 @@ package net.sf.acegisecurity.ui.basicauth;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.AuthenticationException;
import net.sf.acegisecurity.AuthenticationManager;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextUtils;
import net.sf.acegisecurity.intercept.web.AuthenticationEntryPoint;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import net.sf.acegisecurity.ui.WebAuthenticationDetails;
import net.sf.acegisecurity.ui.webapp.HttpSessionIntegrationFilter;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
@ -73,7 +76,8 @@ import javax.servlet.http.HttpServletResponse;
* <P>
* If authentication is successful, the resulting {@link Authentication} object
* will be placed into the <code>HttpSession</code> with the attribute defined
* by {@link HttpSessionIntegrationFilter#ACEGI_SECURITY_AUTHENTICATION_KEY}.
* by {@link
* HttpSessionContextIntegrationFilter#ACEGI_SECURITY_AUTHENTICATION_KEY}.
* </p>
*
* <p>
@ -172,6 +176,7 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
authRequest.setDetails(new WebAuthenticationDetails(httpRequest));
Authentication authResult;
SecureContext sc = SecureContextUtils.getSecureContext();
try {
authResult = authenticationManager.authenticate(authRequest);
@ -182,6 +187,8 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
+ " failed: " + failed.toString());
}
sc.setAuthentication(null);
ContextHolder.setContext(sc);
authenticationEntryPoint.commence(request, response, failed);
return;
@ -192,8 +199,8 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
logger.debug("Authentication success: " + authResult.toString());
}
httpRequest.getSession().setAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY,
authResult);
sc.setAuthentication(authResult);
ContextHolder.setContext(sc);
}
chain.doFilter(request, response);

View File

@ -1,6 +1,6 @@
<html>
<body>
Interfaces the system with various end-user authentication approaches, such
as container adapters and web applications.
Authentication processing mechanisms, which respond to the submission of authentication
credentials using various protocols (eg BASIC, CAS, form login etc).
</body>
</html>

View File

@ -1,158 +0,0 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.acegisecurity.ui.webapp;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.ui.AbstractIntegrationFilter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* Populates a {@link net.sf.acegisecurity.context.SecureContext} from the
* <code>HttpSession</code>.
*
* <P>
* The filter will inspect the <code>HttpSession</code> for an attribute with
* the name indicated by {@link #ACEGI_SECURITY_AUTHENTICATION_KEY}. If that
* attribute contains an instance of {@link Authentication}, it will be placed
* into the <code>ContextHolder</code>.
* </p>
*
* <P>
* This filter is normally used in conjunction with {@link
* AuthenticationProcessingFilter}, which populates the
* <code>HttpSession</code> with an <code>Authentication</code> object based
* on a form login. Similarly, the {@link
* net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter} will populate the
* <code>HttpSession</code> based on a BASIC authentication request.
* Alternatively, users may elect to use their own approach for populating the
* <code>HttpSession</code>.
* </p>
*
* <p>
* As with other <code>AbstractIntegrationFilter</code>s, this filter will
* ensure the <code>ContextHolder</code> is populated with the
* <code>Authentication</code> object for the duration of the HTTP request,
* and is unbound from the <code>ContextHolder</code> at the completion of the
* request.
* </p>
*
* <P>
* The filter can also copy the <code>Authentication</code> object to any
* number of additional <code>HttpSession</code> attributes. To use this
* capability, provide <code>String</code>s indicating the additional
* attribute name(s) to {@link #setAdditionalAttributes(List)}.
* </p>
*
* <p>
* See {@link AbstractIntegrationFilter} for further information.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class HttpSessionIntegrationFilter extends AbstractIntegrationFilter {
//~ Static fields/initializers =============================================
public static final String ACEGI_SECURITY_AUTHENTICATION_KEY = "ACEGI_SECURITY_AUTHENTICATION";
//~ Instance fields ========================================================
private List additionalAttributes = null;
//~ Methods ================================================================
public void setAdditionalAttributes(List additionalAttributes) {
validateList(additionalAttributes);
this.additionalAttributes = additionalAttributes;
}
public List getAdditionalAttributes() {
return additionalAttributes;
}
public void commitToContainer(ServletRequest request,
Authentication authentication) {
if (request instanceof HttpServletRequest
&& ((HttpServletRequest) request).isRequestedSessionIdValid()) {
HttpSession httpSession = ((HttpServletRequest) request).getSession(false);
if (httpSession != null) {
httpSession.setAttribute(ACEGI_SECURITY_AUTHENTICATION_KEY,
authentication);
updateOtherLocations(httpSession, authentication);
}
}
}
public Object extractFromContainer(ServletRequest request) {
if (request instanceof HttpServletRequest) {
HttpSession httpSession = null;
try {
httpSession = ((HttpServletRequest) request).getSession(false);
} catch (IllegalStateException ignored) {}
if (httpSession != null) {
Object authObject = httpSession.getAttribute(ACEGI_SECURITY_AUTHENTICATION_KEY);
if (authObject instanceof Authentication) {
updateOtherLocations(httpSession,
(Authentication) authObject);
return authObject;
}
}
}
return null;
}
private void updateOtherLocations(HttpSession session,
Authentication authentication) {
if (additionalAttributes == null) {
return;
}
Iterator iter = additionalAttributes.iterator();
while (iter.hasNext()) {
String attribute = (String) iter.next();
session.setAttribute(attribute, authentication);
}
}
private void validateList(List newAdditionalAttributes) {
if (newAdditionalAttributes != null) {
Iterator iter = newAdditionalAttributes.iterator();
while (iter.hasNext()) {
Object objectToTest = iter.next();
if (!(objectToTest instanceof String)) {
throw new IllegalArgumentException(
"List of additional attributes can only contains Strings!");
}
}
}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,7 +13,7 @@
* limitations under the License.
*/
package net.sf.acegisecurity.ui.wrapper;
package net.sf.acegisecurity.wrapper;
import java.io.IOException;

View File

@ -13,13 +13,13 @@
* limitations under the License.
*/
package net.sf.acegisecurity.ui.wrapper;
package net.sf.acegisecurity.wrapper;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.security.SecureContext;
import java.security.Principal;

View File

@ -15,6 +15,8 @@
package net.sf.acegisecurity;
import org.springframework.mock.web.MockHttpSession;
import java.io.BufferedReader;
import java.io.IOException;
@ -315,10 +317,20 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
public HttpSession getSession(boolean arg0) {
if (arg0) {
if (this.session == null) {
this.session = new MockHttpSession();
}
}
return this.session;
}
public HttpSession getSession() {
if (this.session == null) {
this.session = new MockHttpSession();
}
return this.session;
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,7 +17,7 @@ package net.sf.acegisecurity;
import net.sf.acegisecurity.context.Context;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.security.SecureContext;
/**

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,9 +17,14 @@ package net.sf.acegisecurity.adapters;
import junit.framework.TestCase;
import net.sf.acegisecurity.*;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContextUtils;
import net.sf.acegisecurity.util.MockFilterChain;
/**
@ -41,41 +46,62 @@ public class HttpRequestIntegrationFilterTests extends TestCase {
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
}
public static void main(String[] args) {
junit.textui.TestRunner.run(HttpRequestIntegrationFilterTests.class);
}
public void testCorrectOperation() {
public void testCorrectOperation() throws Exception {
HttpRequestIntegrationFilter filter = new HttpRequestIntegrationFilter();
PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")});
Object result = filter.extractFromContainer(new MockHttpServletRequest(
principal, null));
if (!(result instanceof PrincipalAcegiUserToken)) {
MockHttpServletRequest request = new MockHttpServletRequest(principal,
null);
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain(true);
filter.doFilter(request, response, chain);
if (!(SecureContextUtils.getSecureContext().getAuthentication() instanceof PrincipalAcegiUserToken)) {
fail("Should have returned PrincipalAcegiUserToken");
}
PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result;
assertEquals(principal, result);
filter.commitToContainer(new MockHttpServletRequest(principal, null),
principal);
PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) SecureContextUtils.getSecureContext()
.getAuthentication();
assertEquals(principal, castResult);
}
public void testHandlesIfHttpRequestIsNullForSomeReason() {
public void testHandlesIfHttpRequestIsNullForSomeReason()
throws Exception {
HttpRequestIntegrationFilter filter = new HttpRequestIntegrationFilter();
assertEquals(null, filter.extractFromContainer(null));
try {
filter.doFilter(null, null, null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testHandlesIfThereIsNoPrincipal() {
public void testHandlesIfThereIsNoPrincipal() throws Exception {
HttpRequestIntegrationFilter filter = new HttpRequestIntegrationFilter();
assertEquals(null,
filter.extractFromContainer(new MockHttpServletRequest(null, null)));
MockHttpServletRequest request = new MockHttpServletRequest("foo");
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain(true);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
filter.doFilter(request, response, chain);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
}
protected void setUp() throws Exception {
super.setUp();
ContextHolder.setContext(new SecureContextImpl());
}
protected void tearDown() throws Exception {
super.tearDown();
ContextHolder.setContext(null);
}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,8 @@ package net.sf.acegisecurity.context;
import junit.framework.TestCase;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;

View File

@ -0,0 +1,245 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.acegisecurity.context;
import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.MockFilterConfig;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse;
import net.sf.acegisecurity.MockHttpSession;
import net.sf.acegisecurity.adapters.PrincipalAcegiUserToken;
import net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContextUtils;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* Tests {@link HttpSessionContextIntegrationFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class HttpSessionContextIntegrationFilterTests extends TestCase {
//~ Constructors ===========================================================
public HttpSessionContextIntegrationFilterTests() {
super();
}
public HttpSessionContextIntegrationFilterTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(HttpSessionContextIntegrationFilterTests.class);
}
public void testDetectsMissingOrInvalidContext() throws Exception {
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
try {
filter.afterPropertiesSet();
fail("Shown have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
filter.setContext(Integer.class);
assertEquals(Integer.class, filter.getContext());
filter.afterPropertiesSet();
fail("Shown have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testExistingContextContentsCopiedIntoContextHolderFromSessionAndChangesToContextCopiedBackToSession()
throws Exception {
// Build an Authentication object we simulate came from HttpSession
PrincipalAcegiUserToken sessionPrincipal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")});
// Build an Authentication object we simulate our Authentication changed it to
PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_DIFFERENT_ROLE")});
// Build a Context to store in HttpSession (simulating prior request)
SecureContext sc = new SecureContextImpl();
sc.setAuthentication(sessionPrincipal);
// Build a mock request
MockHttpSession session = new MockHttpSession();
session.setAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY,
sc);
MockHttpServletRequest request = new MockHttpServletRequest(null,
session);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(sessionPrincipal,
updatedPrincipal);
// Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContext(SecureContextImpl.class);
filter.afterPropertiesSet();
// Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
// Obtain new/update Authentication from HttpSession
Context context = (Context) session.getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY);
assertEquals(updatedPrincipal,
((SecureContext) context).getAuthentication());
}
public void testHttpSessionCreatedWhenContextHolderChanges()
throws Exception {
// Build an Authentication object we simulate our Authentication changed it to
PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_DIFFERENT_ROLE")});
// Build a mock request
MockHttpSession session = null;
MockHttpServletRequest request = new MockHttpServletRequest(null,
session);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(null, updatedPrincipal);
// Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContext(SecureContextImpl.class);
filter.afterPropertiesSet();
// Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
// Obtain new/update Authentication from HttpSession
Context context = (Context) request.getSession().getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY);
assertEquals(updatedPrincipal,
((SecureContext) context).getAuthentication());
}
public void testHttpSessionNotCreatedUnlessContextHolderChanges()
throws Exception {
// Build a mock request
MockHttpServletRequest request = new MockHttpServletRequest(null, null);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(null, null);
// Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContext(SecureContextImpl.class);
filter.afterPropertiesSet();
// Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
// Obtain new/update Authentication from HttpSession
assertNull(request.getSession(false));
}
public void testHttpSessionWithNonContextInWellKnownLocationIsOverwritten()
throws Exception {
// Build an Authentication object we simulate our Authentication changed it to
PrincipalAcegiUserToken updatedPrincipal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_DIFFERENT_ROLE")});
// Build a mock request
MockHttpSession session = new MockHttpSession();
session.setAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY,
"NOT_A_CONTEXT_OBJECT");
MockHttpServletRequest request = new MockHttpServletRequest(null,
session);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(null, updatedPrincipal);
// Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContext(SecureContextImpl.class);
filter.afterPropertiesSet();
// Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
// Obtain new/update Authentication from HttpSession
Context context = (Context) session.getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY);
assertEquals(updatedPrincipal,
((SecureContext) context).getAuthentication());
}
private void executeFilterInContainerSimulator(FilterConfig filterConfig,
Filter filter, ServletRequest request, ServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
filter.init(filterConfig);
filter.doFilter(request, response, filterChain);
filter.destroy();
}
//~ Inner Classes ==========================================================
private class MockFilterChain extends TestCase implements FilterChain {
private Authentication changeContextHolder;
private Authentication expectedOnContextHolder;
public MockFilterChain(Authentication expectedOnContextHolder,
Authentication changeContextHolder) {
this.expectedOnContextHolder = expectedOnContextHolder;
this.changeContextHolder = changeContextHolder;
}
private MockFilterChain() {}
public void doFilter(ServletRequest arg0, ServletResponse arg1)
throws IOException, ServletException {
if (expectedOnContextHolder != null) {
assertEquals(expectedOnContextHolder,
SecureContextUtils.getSecureContext().getAuthentication());
}
if (changeContextHolder != null) {
SecureContext sc = SecureContextUtils.getSecureContext();
sc.setAuthentication(changeContextHolder);
ContextHolder.setContext(sc);
}
}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,6 +18,8 @@ package net.sf.acegisecurity.context;
import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,14 +13,15 @@
* limitations under the License.
*/
package net.sf.acegisecurity.ui.httpinvoker;
package net.sf.acegisecurity.context.httpinvoker;
import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import java.io.IOException;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,7 +13,7 @@
* limitations under the License.
*/
package net.sf.acegisecurity.ui.rmi;
package net.sf.acegisecurity.context.rmi;
import junit.framework.TestCase;
@ -21,8 +21,10 @@ import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.MockMethodInvocation;
import net.sf.acegisecurity.TargetObject;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.rmi.ContextPropagatingRemoteInvocation;
import net.sf.acegisecurity.context.rmi.ContextPropagatingRemoteInvocationFactory;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.aopalliance.intercept.MethodInvocation;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,8 +28,8 @@ import net.sf.acegisecurity.SecurityConfig;
import net.sf.acegisecurity.TargetObject;
import net.sf.acegisecurity.acl.basic.SomeDomain;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.springframework.context.ApplicationContext;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -35,8 +35,8 @@ import net.sf.acegisecurity.MockRunAsManager;
import net.sf.acegisecurity.RunAsManager;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.ContextImpl;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.intercept.method.AbstractMethodDefinitionSource;
import net.sf.acegisecurity.intercept.method.MockMethodDefinitionSource;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,8 +27,8 @@ import net.sf.acegisecurity.MockJoinPoint;
import net.sf.acegisecurity.MockRunAsManager;
import net.sf.acegisecurity.TargetObject;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.intercept.method.MethodDefinitionMap;
import net.sf.acegisecurity.intercept.method.MethodDefinitionSourceEditor;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -34,8 +34,8 @@ import net.sf.acegisecurity.MockRunAsManager;
import net.sf.acegisecurity.RunAsManager;
import net.sf.acegisecurity.SecurityConfig;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import java.io.IOException;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,8 +26,8 @@ import net.sf.acegisecurity.acl.AclManager;
import net.sf.acegisecurity.acl.basic.MockAclObjectIdentity;
import net.sf.acegisecurity.acl.basic.SimpleAclEntry;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.ApplicationContext;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,8 +20,8 @@ import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import net.sf.acegisecurity.providers.dao.User;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,7 +20,7 @@ import junit.framework.TestCase;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import javax.servlet.jsp.JspException;

View File

@ -1,16 +1,34 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.acegisecurity.taglibs.authz;
import junit.framework.TestCase;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.mock.web.MockPageContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
/**
* Test case to implement commons-el expression language expansion.
*/
@ -18,40 +36,37 @@ public class AuthorizeTagExpressionLanguageTests extends TestCase {
//~ Instance fields ========================================================
private final AuthorizeTag authorizeTag = new AuthorizeTag();
private MockPageContext pageContext;
private SecureContextImpl context;
private TestingAuthenticationToken currentUser;
private MockPageContext pageContext;
//~ Methods ================================================================
public void testAllGrantedUsesExpressionLanguageWhenExpressionIsEL()
throws JspException {
throws JspException {
pageContext.setAttribute("authority", "ROLE_TELLER");
authorizeTag.setIfAllGranted("${authority}");
assertEquals(
"allows body - authority var contains ROLE_TELLER",
Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
assertEquals("allows body - authority var contains ROLE_TELLER",
Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
}
public void testAnyGrantedUsesExpressionLanguageWhenExpressionIsEL()
throws JspException {
throws JspException {
pageContext.setAttribute("authority", "ROLE_TELLER");
authorizeTag.setIfAnyGranted("${authority}");
assertEquals(
"allows body - authority var contains ROLE_TELLER",
Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
assertEquals("allows body - authority var contains ROLE_TELLER",
Tag.EVAL_BODY_INCLUDE, authorizeTag.doStartTag());
}
public void testNotGrantedUsesExpressionLanguageWhenExpressionIsEL()
throws JspException {
throws JspException {
pageContext.setAttribute("authority", "ROLE_TELLER");
authorizeTag.setIfNotGranted("${authority}");
assertEquals(
"allows body - authority var contains ROLE_TELLER",
Tag.SKIP_BODY, authorizeTag.doStartTag());
assertEquals("allows body - authority var contains ROLE_TELLER",
Tag.SKIP_BODY, authorizeTag.doStartTag());
}
protected void setUp() throws Exception {
@ -60,11 +75,8 @@ public class AuthorizeTagExpressionLanguageTests extends TestCase {
pageContext = new MockPageContext();
authorizeTag.setPageContext(pageContext);
currentUser = new TestingAuthenticationToken(
"abc", "123",
new GrantedAuthority[]{
new GrantedAuthorityImpl("ROLE_TELLER"),
});
currentUser = new TestingAuthenticationToken("abc", "123",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_TELLER"),});
context = new SecureContextImpl();
context.setAuthentication(currentUser);

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,7 +20,7 @@ import junit.framework.TestCase;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import javax.servlet.jsp.JspException;

View File

@ -1,308 +0,0 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.acegisecurity.ui;
import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.adapters.MockPrincipal;
import net.sf.acegisecurity.adapters.PrincipalAcegiUserToken;
import net.sf.acegisecurity.context.Context;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* Tests {@link AbstractIntegrationFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class AbstractIntegrationFilterTests extends TestCase {
//~ Constructors ===========================================================
public AbstractIntegrationFilterTests() {
super();
}
public AbstractIntegrationFilterTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
}
public static void main(String[] args) {
junit.textui.TestRunner.run(AbstractIntegrationFilterTests.class);
}
public void testContextHolderContentsPreserved() throws Exception {
PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")});
MockAbstractIntegrationFilterImpl filter = new MockAbstractIntegrationFilterImpl(principal);
MockFilterChain chain = new MockFilterChain(true, principal);
MockSecureContextImpl secureContext = new MockSecureContextImpl(
"FOO_BAR");
ContextHolder.setContext(secureContext);
assertEquals(secureContext, ContextHolder.getContext());
executeFilterInContainerSimulator(filter, null, null, chain);
MockSecureContextImpl after = (MockSecureContextImpl) ContextHolder
.getContext();
assertEquals(secureContext.getInfo(), after.getInfo());
ContextHolder.setContext(null);
}
public void testContextHolderHasAuthenticationRemoved()
throws Exception {
PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")});
MockAbstractIntegrationFilterImpl filter = new MockAbstractIntegrationFilterImpl(principal);
MockFilterChain chain = new MockFilterChain(true, principal);
SecureContext secureContext = new SecureContextImpl();
secureContext.setAuthentication(principal);
ContextHolder.setContext(secureContext);
assertEquals(secureContext, ContextHolder.getContext());
executeFilterInContainerSimulator(filter, null, null, chain);
SecureContext after = (SecureContext) ContextHolder.getContext();
assertEquals(null, after.getAuthentication());
ContextHolder.setContext(null);
}
public void testIgnoredWhenConcreteClassReturnsANonAuthenticationObject()
throws Exception {
MockPrincipal principal = new MockPrincipal();
MockAbstractIntegrationFilterImpl filter = new MockAbstractIntegrationFilterImpl(principal);
MockFilterChain chain = new MockFilterChain(false, null);
Context before = ContextHolder.getContext();
if (before != null) {
if (before instanceof SecureContext) {
assertEquals(null, ((SecureContext) before).getAuthentication());
}
}
executeFilterInContainerSimulator(filter, null, null, chain);
Context after = ContextHolder.getContext();
if (after != null) {
if (after instanceof SecureContext) {
assertEquals(null, ((SecureContext) after).getAuthentication());
}
}
}
public void testIgnoredWhenConcreteClassReturnsNullAuthenticationObject()
throws Exception {
MockAbstractIntegrationFilterImpl filter = new MockAbstractIntegrationFilterImpl(null);
MockFilterChain chain = new MockFilterChain(false, null);
Context before = ContextHolder.getContext();
if (before != null) {
if (before instanceof SecureContext) {
assertEquals(null, ((SecureContext) before).getAuthentication());
}
}
executeFilterInContainerSimulator(filter, null, null, chain);
Context after = ContextHolder.getContext();
if (after != null) {
if (after instanceof SecureContext) {
assertEquals(null, ((SecureContext) after).getAuthentication());
}
}
}
public void testRejectsInvalidSecureContextClass()
throws Exception {
MockAbstractIntegrationFilterImpl filter = new MockAbstractIntegrationFilterImpl(null);
// Test rejects classes not implementing SecureContext
filter.setSecureContext(String.class);
try {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
// Test accepts classes implementing SecureContext
filter.setSecureContext(SecureContextImpl.class);
filter.afterPropertiesSet();
assertTrue(true);
// Test rejects null
filter.setSecureContext(null);
try {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testSecureContextSettersGetters() throws Exception {
MockAbstractIntegrationFilterImpl filter = new MockAbstractIntegrationFilterImpl(null);
// check the default
assertEquals(SecureContextImpl.class, filter.getSecureContext());
// check the setter
filter.setSecureContext(null);
assertNull(filter.getSecureContext());
}
public void testSuccessWhenConcreteClassReturnsValidAuthenticationObject()
throws Exception {
PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")});
MockAbstractIntegrationFilterImpl filter = new MockAbstractIntegrationFilterImpl(principal);
MockFilterChain chain = new MockFilterChain(true, principal);
Context before = ContextHolder.getContext();
if (before != null) {
if (before instanceof SecureContext) {
assertEquals(null, ((SecureContext) before).getAuthentication());
}
}
executeFilterInContainerSimulator(filter, null, null, chain);
Context after = ContextHolder.getContext();
if (after != null) {
if (after instanceof SecureContext) {
assertEquals(null, ((SecureContext) after).getAuthentication());
}
}
}
private void executeFilterInContainerSimulator(Filter filter,
ServletRequest request, ServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
filter.init(null);
filter.doFilter(request, response, filterChain);
filter.destroy();
}
//~ Inner Classes ==========================================================
private class MockAbstractIntegrationFilterImpl
extends AbstractIntegrationFilter {
private Object extractFromContainerResult;
public MockAbstractIntegrationFilterImpl(
Object extractFromContainerResult) {
this.extractFromContainerResult = extractFromContainerResult;
}
private MockAbstractIntegrationFilterImpl() {
super();
}
public void commitToContainer(ServletRequest request,
Authentication authentication) {
this.extractFromContainerResult = authentication;
}
public Object extractFromContainer(ServletRequest request) {
return this.extractFromContainerResult;
}
}
private class MockFilterChain implements FilterChain {
private Authentication expectedAuthenticationObjectInContextHolder;
private boolean expectContextHolderContainSecureContext = false;
public MockFilterChain(
boolean expectContextHolderContainSecureContext,
Authentication expectedAuthenticationObjectInContextHolder) {
if ((expectedAuthenticationObjectInContextHolder != null)
&& !expectContextHolderContainSecureContext) {
throw new IllegalArgumentException(
"If an Authentication object is expected, the ContextHolder should contain a SecureContext");
}
this.expectContextHolderContainSecureContext = expectContextHolderContainSecureContext;
this.expectedAuthenticationObjectInContextHolder = expectedAuthenticationObjectInContextHolder;
}
private MockFilterChain() {
super();
}
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (expectContextHolderContainSecureContext) {
Context context = ContextHolder.getContext();
if (!(context instanceof SecureContext)) {
fail("ContextHolder should have contained SecureContext");
}
} else {
if (ContextHolder.getContext() != null) {
fail("ContextHolder should have been null but wasn't");
}
}
}
}
private class MockSecureContextImpl extends SecureContextImpl {
private String info;
public MockSecureContextImpl(String info) {
this.info = info;
}
private MockSecureContextImpl() {
super();
}
public String getInfo() {
return this.info;
}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,8 +26,10 @@ import net.sf.acegisecurity.MockAuthenticationManager;
import net.sf.acegisecurity.MockFilterConfig;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContextUtils;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import net.sf.acegisecurity.ui.webapp.HttpSessionIntegrationFilter;
import java.io.IOException;
@ -59,10 +61,6 @@ public class AbstractProcessingFilterTests extends TestCase {
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
}
public static void main(String[] args) {
junit.textui.TestRunner.run(AbstractProcessingFilterTests.class);
}
@ -117,7 +115,7 @@ public class AbstractProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertEquals("/myApp/failed.jsp", response.getRedirect());
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
}
public void testFilterProcessesUrlVariationsRespected()
@ -144,10 +142,10 @@ public class AbstractProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertEquals("/logged_in.jsp", response.getRedirect());
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) != null);
assertNotNull(SecureContextUtils.getSecureContext().getAuthentication());
assertEquals("test",
((Authentication) request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY)).getPrincipal()
.toString());
SecureContextUtils.getSecureContext().getAuthentication()
.getPrincipal().toString());
}
public void testGettersSetters() {
@ -233,10 +231,10 @@ public class AbstractProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertEquals("/logged_in.jsp", response.getRedirect());
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) != null);
assertNotNull(SecureContextUtils.getSecureContext().getAuthentication());
assertEquals("test",
((Authentication) request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY)).getPrincipal()
.toString());
SecureContextUtils.getSecureContext().getAuthentication()
.getPrincipal().toString());
}
public void testStartupDetectsInvalidAuthenticationFailureUrl()
@ -327,10 +325,10 @@ public class AbstractProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertEquals("/logged_in.jsp", response.getRedirect());
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) != null);
assertNotNull(SecureContextUtils.getSecureContext().getAuthentication());
assertEquals("test",
((Authentication) request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY)).getPrincipal()
.toString());
SecureContextUtils.getSecureContext().getAuthentication()
.getPrincipal().toString());
// Now try again but this time have filter deny access
// Setup our HTTP request
@ -346,7 +344,7 @@ public class AbstractProcessingFilterTests extends TestCase {
// Test
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
}
public void testSuccessfulAuthenticationButWithAlwaysUseDefaultTargetUrlCausesRedirectToDefaultTargetUrl()
@ -377,7 +375,7 @@ public class AbstractProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertEquals("/foobar", response.getRedirect());
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) != null);
assertNotNull(SecureContextUtils.getSecureContext().getAuthentication());
}
public void testSuccessfulAuthenticationCausesRedirectToSessionSpecifiedUrl()
@ -404,7 +402,17 @@ public class AbstractProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertEquals("/my-destination", response.getRedirect());
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) != null);
assertNotNull(SecureContextUtils.getSecureContext().getAuthentication());
}
protected void setUp() throws Exception {
super.setUp();
ContextHolder.setContext(new SecureContextImpl());
}
protected void tearDown() throws Exception {
super.tearDown();
ContextHolder.setContext(null);
}
private void executeFilterInContainerSimulator(FilterConfig filterConfig,

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,7 +17,6 @@ package net.sf.acegisecurity.ui.basicauth;
import junit.framework.TestCase;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.MockAuthenticationEntryPoint;
import net.sf.acegisecurity.MockAuthenticationManager;
import net.sf.acegisecurity.MockFilterConfig;
@ -25,7 +24,9 @@ import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpServletResponse;
import net.sf.acegisecurity.MockHttpSession;
import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.ui.webapp.HttpSessionIntegrationFilter;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContextUtils;
import org.apache.commons.codec.binary.Base64;
@ -64,10 +65,6 @@ public class BasicProcessingFilterTests extends TestCase {
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
}
public static void main(String[] args) {
junit.textui.TestRunner.run(BasicProcessingFilterTests.class);
}
@ -125,7 +122,7 @@ public class BasicProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
}
public void testGettersSetters() {
@ -167,7 +164,7 @@ public class BasicProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
}
public void testNormalOperation() throws Exception {
@ -198,10 +195,11 @@ public class BasicProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) != null);
assertNotNull(SecureContextUtils.getSecureContext().getAuthentication());
assertEquals("marissa",
((UserDetails) ((Authentication) request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY))
.getPrincipal()).getUsername());
((UserDetails) SecureContextUtils.getSecureContext()
.getAuthentication().getPrincipal())
.getUsername());
}
public void testOtherAuthorizationSchemeIsIgnored()
@ -231,7 +229,7 @@ public class BasicProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
}
public void testStartupDetectsMissingAuthenticationEntryPoint()
@ -290,10 +288,11 @@ public class BasicProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) != null);
assertNotNull(SecureContextUtils.getSecureContext().getAuthentication());
assertEquals("marissa",
((UserDetails) ((Authentication) request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY))
.getPrincipal()).getUsername());
((UserDetails) SecureContextUtils.getSecureContext()
.getAuthentication().getPrincipal())
.getUsername());
// NOW PERFORM FAILED AUTHENTICATION
// Setup our HTTP request
@ -313,7 +312,7 @@ public class BasicProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
assertEquals(401, response.getError());
}
@ -345,10 +344,20 @@ public class BasicProcessingFilterTests extends TestCase {
executeFilterInContainerSimulator(config, filter, request, response,
chain);
assertTrue(request.getSession().getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY) == null);
assertNull(SecureContextUtils.getSecureContext().getAuthentication());
assertEquals(401, response.getError());
}
protected void setUp() throws Exception {
super.setUp();
ContextHolder.setContext(new SecureContextImpl());
}
protected void tearDown() throws Exception {
super.tearDown();
ContextHolder.setContext(null);
}
private void executeFilterInContainerSimulator(FilterConfig filterConfig,
Filter filter, ServletRequest request, ServletResponse response,
FilterChain filterChain) throws ServletException, IOException {

View File

@ -1,199 +0,0 @@
/* Copyright 2004 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.acegisecurity.ui.webapp;
import junit.framework.TestCase;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.MockHttpSession;
import net.sf.acegisecurity.adapters.PrincipalAcegiUserToken;
import java.util.List;
import java.util.Vector;
/**
* Tests {@link HttpSessionIntegrationFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class HttpSessionIntegrationFilterTests extends TestCase {
//~ Constructors ===========================================================
public HttpSessionIntegrationFilterTests() {
super();
}
public HttpSessionIntegrationFilterTests(String arg0) {
super(arg0);
}
//~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
}
public static void main(String[] args) {
junit.textui.TestRunner.run(HttpSessionIntegrationFilterTests.class);
}
public void testCommitFailSilentlyIfNullsProvided() {
HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter();
filter.commitToContainer(null, null);
assertTrue(true);
}
public void testCommitOperation() {
// Build an Authentication object we want returned
PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")});
// Build a mock request
MockHttpSession session = new MockHttpSession();
MockHttpServletRequest request = new MockHttpServletRequest(null,
session);
// Try to commit
HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter();
filter.commitToContainer(request, principal);
// Check it committed the object
Object result = session.getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY);
assertEquals(principal, result);
}
public void testCommitOperationGracefullyIgnoredIfSessionIsNull() {
PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")});
// Build a mock request
MockHttpSession session = null;
MockHttpServletRequest request = new MockHttpServletRequest(null,
session);
HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter();
filter.commitToContainer(request, principal);
assertTrue(true);
}
public void testCorrectOperation() {
// Build a mock session containing the authenticated user
PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")});
MockHttpSession session = new MockHttpSession();
session.setAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY,
principal);
// Confirm filter can extract required credentials from session
HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter();
Object result = filter.extractFromContainer(new MockHttpServletRequest(
null, session));
if (!(result instanceof PrincipalAcegiUserToken)) {
fail("Should have returned PrincipalAcegiUserToken");
}
PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result;
assertEquals(principal, result);
}
public void testDetectsInvalidAdditionalAttributes() {
HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter();
List list = new Vector();
list.add(new Integer(4));
try {
filter.setAdditionalAttributes(list);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testHandlesIfHttpRequestIsNullForSomeReason() {
HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter();
assertEquals(null, filter.extractFromContainer(null));
}
public void testHandlesIfHttpSessionIsNullForSomeReason() {
HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter();
assertEquals(null,
filter.extractFromContainer(new MockHttpServletRequest(null, null)));
}
public void testHandlesIfThereIsNoPrincipalInTheHttpSession() {
HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter();
assertEquals(null,
filter.extractFromContainer(
new MockHttpServletRequest(null, new MockHttpSession())));
}
public void testSettingEmptyListForAdditionalAttributesIsAcceptable() {
HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter();
filter.setAdditionalAttributes(new Vector());
assertTrue(filter.getAdditionalAttributes() != null);
}
public void testSettingNullForAdditionalAttributesIsAcceptable() {
HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter();
filter.setAdditionalAttributes(null);
assertNull(filter.getAdditionalAttributes());
}
public void testUpdatesAdditionalAttributes() {
// Build a mock session containing the authenticated user
PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key",
"someone", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")});
MockHttpSession session = new MockHttpSession();
session.setAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY,
principal);
// Check our attributes are not presently set
assertNull(session.getAttribute("SOME_EXTRA_ATTRIBUTE_1"));
assertNull(session.getAttribute("SOME_EXTRA_ATTRIBUTE_2"));
// Generate filter
HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter();
List list = new Vector();
list.add("SOME_EXTRA_ATTRIBUTE_1");
list.add("SOME_EXTRA_ATTRIBUTE_2");
filter.setAdditionalAttributes(list);
// Confirm filter can extract required credentials from session
Object result = filter.extractFromContainer(new MockHttpServletRequest(
null, session));
if (!(result instanceof PrincipalAcegiUserToken)) {
fail("Should have returned PrincipalAcegiUserToken");
}
PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result;
assertEquals(principal, result);
// Now double-check it updated our earlier set additionalAttributes
assertEquals(principal, session.getAttribute("SOME_EXTRA_ATTRIBUTE_1"));
assertEquals(principal, session.getAttribute("SOME_EXTRA_ATTRIBUTE_2"));
}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,12 +13,14 @@
* limitations under the License.
*/
package net.sf.acegisecurity.ui.wrapper;
package net.sf.acegisecurity.wrapper;
import junit.framework.TestCase;
import net.sf.acegisecurity.MockFilterConfig;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.wrapper.ContextHolderAwareRequestFilter;
import net.sf.acegisecurity.wrapper.ContextHolderAwareRequestWrapper;
import java.io.IOException;

View File

@ -13,7 +13,7 @@
* limitations under the License.
*/
package net.sf.acegisecurity.ui.wrapper;
package net.sf.acegisecurity.wrapper;
import junit.framework.TestCase;
@ -22,10 +22,11 @@ import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.MockHttpServletRequest;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import net.sf.acegisecurity.providers.dao.User;
import net.sf.acegisecurity.wrapper.ContextHolderAwareRequestWrapper;
/**

View File

@ -26,7 +26,7 @@
<subtitle>Reference Documentation</subtitle>
<releaseinfo>0.7.0</releaseinfo>
<releaseinfo>0.8.0</releaseinfo>
<authorgroup>
<author>
@ -399,6 +399,43 @@
custom request contexts implement the <literal>SecureContext</literal>
interface.</para>
</sect2>
<sect2 id="security-contexts-storage">
<title>Context Storage</title>
<para>Central to Acegi Security's design is that the contents of the
<literal>ContextHolder</literal> (ie the <literal>Context</literal>)
can be stored between web requests. This is so that a successfully
authenticated principal can be identified on subsequent requests
through the <literal>Authentication</literal> stored inside a
<literal>SecureContext</literal> implementation. The
<literal>HttpSessionContextIntegrationFilter</literal> exists to
automatically copy the contents of a well-defined
<literal>HttpSession</literal> attribute into the
<literal>ContextHolder</literal>, then at the end of each request,
copy the <literal>ContextHolder</literal> contents back into the
<literal>HttpSession</literal> ready for next request.</para>
<para>It is essential - and an extremely common error of end users -
that <literal>HttpSessionContextIntegrationFilter</literal> appears
before any other Acegi Security filter. This is because other Acegi
Security filters (along with all Acegi Security classes) expect the
<literal>ContextHolder</literal> to contain a valid
<literal>SecureContext</literal> by the time they are called. Acegi
Security filters also expect to be able to modify the
<literal>ContextHolder</literal> contents as they see fit, and
something else will store those between requests if necessary. This is
why <literal>HttpSessionContextIntegrationFilter</literal> must be the
first filter used.</para>
<para>The <literal>HttpSessionContextIntegrationFilter</literal> has
been designed to store all types of <literal>Context</literal> objects
- not merely Acegi Security related contexts. This means, for example,
that you can extend <literal>SecureContextImpl</literal> to store a
locale or some other parameter, and
<literal>HttpSessionContextIntegrationFilter</literal> will
automatically manage it between web requests.</para>
</sect2>
</sect1>
<sect1 id="security-interception">
@ -2264,44 +2301,42 @@ public boolean supports(Class clazz);</programlisting></para>
classes "authentication mechanisms".</para>
<para>The <literal>net.sf.acegisecurity.ui</literal> package provides
authentication mechanisms for web applications. There are two major
steps in doing this:</para>
what we call "authentication processing mechanisms". An authentication
processing mechanism is solely concerned with received an
authentication request from the principal, testing if it seems valid,
and if so, placing the authentication request token onto the
ContextHolder. Of course, if the authentication request is invalid,
the authentication processing mechanism is responsible for informing
the principal in whatever way is appropriate to the protocol.</para>
<para><itemizedlist spacing="compact">
<listitem>
<para>Actually authenticate the user and place the resulting
<literal>Authentication</literal> object in a "well-known
location".</para>
</listitem>
<para>Recall the HttpSessionContextIntegrationFilter (discussed in the
context section) is responsible for storing the ContextHolder contents
between invocations. This means no authentication processing mechanism
need ever interact directly with HttpSession. Indeed
HttpSessionContextIntegrationFilter has been designed to minimise the
unnecessary creation of HttpSessions, as might occur when using Basic
authentication for example.</para>
<listitem>
<para>Extract the <literal>Authentication</literal> object from
the "well-known location" and place in into the
<literal>ContextHolder</literal> for the duration of the secure
object invocation.</para>
</listitem>
</itemizedlist></para>
<para>There are several alternatives are available for the first step,
which will be briefly discussed in this chapter. The most popular (and
almost always recommended) approach is HTTP Session Authentication,
which uses the <literal>HttpSession</literal> object and filters to
authenticate the user. Another approach (commonly use with web
services) is HTTP Basic Authentication, which allows clients to use
HTTP headers to present authentication information to the Acegi
Security System for Spring. Alternatively, you can also use Yale
Central Authentication Service (CAS) for enterprise-wide single sign
on. The final (generally unrecommended) approach is via Container
Adapters, which allow supported web containers to perform the
authentication themselves. HTTP Session and Basic Authentication is
discussed below, whilst CAS and Container Adapters are discussed in
separate sections of this document.</para>
<para>There are several authentication processing mechanisms included
with Acegi Security, which will be briefly discussed in this chapter.
The most popular (and almost always recommended) approach is HTTP Form
Authentication, which uses a login form to authenticate the user.
Another approach (commonly use with web services) is HTTP Basic
Authentication, which allows clients to use HTTP headers to present
authentication information to the Acegi Security System for Spring.
Alternatively, you can also use Yale Central Authentication Service
(CAS) for enterprise-wide single sign on. The final (and generally
unrecommended) approach is via Container Adapters, which allow
supported web containers to perform the authentication themselves.
HTTP Form Authentication and Basic Authentication is discussed below,
whilst CAS and Container Adapters are discussed in separate sections
of this document.</para>
</sect2>
<sect2 id="security-ui-http-session">
<title>HTTP Session Authentication</title>
<sect2 id="security-ui-http-form">
<title>HTTP Form Authentication</title>
<para>HTTP Session Authentication involves using the
<para>HTTP Form Authentication involves using the
<literal>AuthenticationProcessingFilter</literal> to process a login
form. The login form simply contains <literal>j_username</literal> and
<literal>j_password</literal> input fields, and posts to a URL that is
@ -2346,12 +2381,9 @@ public boolean supports(Class clazz);</programlisting></para>
<para>If authentication is successful, the resulting
<literal>Authentication</literal> object will be placed into the
<literal>HttpSession</literal> attribute indicated by
<literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.
This becomes the "well-known location" from which the
<literal>Authentication</literal> object is later extracted.</para>
<literal>ContextHolder</literal>.</para>
<para>Once the <literal>HttpSession</literal> has been updated, the
<para>Once the <literal>ContextHolder</literal> has been updated, the
browser will need to be redirected to the target URL. The target URL
is usually indicated by the <literal>HttpSession</literal> attribute
specified by
@ -2365,8 +2397,8 @@ public boolean supports(Class clazz);</programlisting></para>
<literal>defaultTargetUrl</literal> property.</para>
<para>Because this authentication approach is fully contained within a
single web application, HTTP Session Authentication is recommended to
be used instead of Container Adapters.</para>
single web application, HTTP Form Authentication is recommended to be
used instead of Container Adapters.</para>
</sect2>
<sect2 id="security-ui-http-basic">
@ -2421,10 +2453,7 @@ public boolean supports(Class clazz);</programlisting></para>
401 response with a suitable header to retry HTTP Basic
authentication. If authentication is successful, the resulting
<literal>Authentication</literal> object will be placed into the
<literal>HttpSession</literal> attribute indicated by
<literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.
This becomes the "well-known location" from which the
<literal>Authentication</literal> object is later extracted.</para>
<literal>ContextHolder</literal>.</para>
<para>If the authentication event was successful, or authentication
was not attempted because the HTTP header did not contain a supported
@ -2434,94 +2463,32 @@ public boolean supports(Class clazz);</programlisting></para>
as discussed in the previous paragraph.</para>
<para>HTTP Basic Authentication is recommended to be used instead of
Container Adapters. It can be used in conjunction with HTTP Session
Container Adapters. It can be used in conjunction with HTTP Form
Authentication, as demonstrated in the Contacts sample application.
You can also use it instead of HTTP Session Authentication if you
You can also use it instead of HTTP Form Authentication if you
wish.</para>
</sect2>
<sect2 id="security-ui-well-known">
<title>Well-Known Location Integration</title>
<title>Well-Known Locations</title>
<para>Once a web application has used either HTTP Session
Authentication, HTTP Basic Authentication, or a Container Adapter, an
<literal>Authentication</literal> object will exist in a well-known
location. The final step in automatically integrating the user
interface with the backend security interceptor is to extract this
<literal>Authentication</literal> object from the well-known location
and place it into a <literal>SecureContext</literal> in the
<literal>ContextHolder</literal>.</para>
<para>The <literal>AbstractIntegrationFilter</literal> and its
subclasses provide this well-known location integration. These classes
are standard filters, and at the start of each request they will
attempt to extract the <literal>Authentication</literal> object from a
well-known location. The <literal>Authentication</literal> object will
then be added to a <literal>SecureContext</literal>, the
<literal>SecureContext</literal> associated with the
<literal>ContextHolder</literal> for the duration of the request, and
the <literal>ContextHolder</literal> be cleared when the request is
finished. Four concrete subclasses of
<literal>AbstractIntegrationFilter</literal> are provided with the
Acegi Security System for Spring:</para>
<para><itemizedlist>
<listitem>
<para><literal>HttpSessionIntegrationFilter</literal> is used
with HTTP Session Authentication, HTTP Basic Authentication, or
any other approach that populates the
<literal>HttpSession</literal> accordingly. It extracts the
<literal>Authentication</literal> object from the
<literal>HttpSession</literal> attribute indicated by
<literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.</para>
</listitem>
<listitem>
<para><literal>HttpRequestIntegrationFilter</literal> is used
with Catalina, Jetty and Resin Container Adapters. It extracts
the authentication information from
<literal>HttpServletRequest.getUserPrincipal()</literal>.</para>
</listitem>
<listitem>
<para><literal>JbossIntegrationFilter</literal> is used with the
JBoss Container Adapter. It extracts the authentication from
<literal>java:comp/env/security/subject</literal>.</para>
</listitem>
</itemizedlist></para>
<para>To define the <literal>HttpSessionIntegrationFilter</literal>
(recommended), simply add the following to your web.xml:</para>
<para><programlisting>&lt;filter&gt;
&lt;filter-name&gt;Acegi Security System for Spring HttpSession Integration Filter&lt;/filter-name&gt;
&lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;targetClass&lt;/param-name&gt;
&lt;param-value&gt;net.sf.acegisecurity.ui.webapp.HttpSessionIntegrationFilter&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;Acegi Security System for Spring HttpSession Integration Filter&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</programlisting></para>
<para>You will also need to add the following line to your application
context:</para>
<para><programlisting>&lt;bean id="httpSessionIntegrationFilter" class="net.sf.acegisecurity.ui.webapp.HttpSessionIntegrationFilter" /&gt;</programlisting></para>
<para>Once in the <literal>ContextHolder</literal>, the standard Acegi
Security System for Spring classes can be used. Because
<literal>ContextHolder</literal> is a standard object which is
populated using a filter at the container level, JSPs and Servlets do
not need to use Spring's MVC packages. This enables those applications
that use other MVC frameworks to still leverage Spring's other
capabilities, with full authentication and authorization support. The
<literal>debug.jsp</literal> page provided with the sample application
demonstrates accessing the <literal>ContextHolder</literal>
independent of Spring's MVC packages.</para>
<para>Prior to release 0.8.0, Acegi Security referred to "well-known
locations" in discussions about storing the
<literal>Authentication</literal>. This approach did not explicitly
separate the function of <literal>HttpSession</literal> storage of
<literal>ContextHolder</literal> contents from the processing of
authentication requests received through various protocols. In
addition, the previous approach did not facilitate storage of
non-<literal>Authentication</literal> objects between requests, which
was limiting usefulness of the <literal>ContextHolder</literal> system
to member of the community. For these reasons, the notion of
well-known locations was abandoned, the
<literal>HttpSessionContextIntegrationFilter</literal> was
established, and the purpose of authentication processing mechanisms
was explicitly defined and limited to interaction with the
<literal>ContextHolder</literal> only. There is no need to refer to
well-known locations any more and we hope this clearer separation of
responsibilities enhances understanding of the project.</para>
</sect2>
</sect1>
@ -2531,13 +2498,14 @@ public boolean supports(Class clazz);</programlisting></para>
<sect2 id="security-container-adapters-overview">
<title>Overview</title>
<para>Early versions of the Acegi Security System for Spring
<para>Very early versions of the Acegi Security System for Spring
exclusively used Container Adapters for interfacing authentication
with end users. Whilst this worked well, it required considerable time
to support multiple container versions and the configuration itself
was relatively time-consuming for developers. For this reason the HTTP
Session Authentication and HTTP Basic Authentication approaches were
developed, and are today recommended for most applications.</para>
Form Authentication and HTTP Basic Authentication approaches were
developed, and are today recommended for almost all
applications.</para>
<para>Container Adapters enable the Acegi Security System for Spring
to integrate directly with the containers used to host end user
@ -2546,7 +2514,10 @@ public boolean supports(Class clazz);</programlisting></para>
containers (such as <literal>isUserInRole()</literal> and form-based
or basic authentication), whilst benefiting from the enhanced security
interception capabilities provided by the Acegi Security System for
Spring.</para>
Spring (it should be noted that Acegi Security also offers
<literal>ContextHolderAwareRequestWrapper</literal> to deliver
<literal>isUserInRole()</literal> and similar Servlet Specification
compatibility methods).</para>
<para>The integration between a container and the Acegi Security
System for Spring is achieved through an adapter. The adapter provides
@ -4208,8 +4179,8 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
&lt;value&gt;
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/webServices/**=basicProcessingFilter,httpSessionIntegrationFilter,securityEnforcementFilter
/**=authenticationProcessingFilter,httpSessionIntegrationFilter,securityEnforcementFilter
/webServices/**=httpSessionContextIntegrationFilterWithASCFalse,basicProcessingFilter,securityEnforcementFilter
/**=httpSessionContextIntegrationFilterWithASCTrue,authenticationProcessingFilter,securityEnforcementFilter
&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>
@ -4228,8 +4199,8 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
<para>As you can see, <literal>FitlerChainProxy</literal> requires the
duplication of filter names for different request patterns (in the
above example, <literal>httpSessionIntegrationFilter</literal> and
<literal>securityEnforcementFilter</literal> are duplicated). This
above example, <literal>httpSessionContextIntegrationFilter</literal>
and <literal>securityEnforcementFilter</literal> are duplicated). This
design decision was made to enable <literal>FilterChainProxy</literal>
to specify different <literal>Filter</literal> invocation orders for
different URI patterns, and also to improve both the expressiveness
@ -4238,6 +4209,20 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
and clarity of which <literal>Filter</literal>s should be
invoked.</para>
<para>You may have noticed we have declared two
<literal>HttpSessionContextIntegrationFilter</literal>s in the filter
chain (<literal>ASC</literal> is short for
<literal>allowSessionCreation</literal>, a property of
<literal>HttpSessionContextIntegrationFilter</literal>). As web
services will never present a <literal>jsessionid</literal> on future
requests, creating <literal>HttpSession</literal>s for such user
agents would be wasteful. If you had a high-volume application which
required maximum scalability, we recommend you use the approach shown
above. For smaller applications, using a single
<literal>HttpSessionContextIntegrationFilter</literal> (with its
default <literal>allowSessionCreation</literal> as
<literal>true</literal>) would likely be sufficient.</para>
<para>In relation to lifecycle issues, the
<literal>FilterChainProxy</literal> will always delegate
<literal>init(FilterConfig)</literal> and <literal>destroy()</literal>
@ -4259,7 +4244,7 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
<title>Filter Ordering</title>
<para>The order that filters are defined in <literal>web.xml</literal>
is important.</para>
is important. NB: THE FILTER ORDER CHANGED FROM VERSION 0.8.0.</para>
<para>Irrespective of which filters you are actually using, the order
of the <literal>&lt;filter-mapping&gt;</literal>s should be as
@ -4267,33 +4252,41 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
<orderedlist>
<listitem>
<para>Acegi Channel Processing Filter
(<literal>ChannelProcessingFilter</literal>)</para>
<para><literal>ChannelProcessingFilter</literal>, because it might
need to redirect to a different protocol</para>
</listitem>
<listitem>
<para>Acegi Authentication Processing Filter
(<literal>AuthenticationProcessingFilter</literal>)</para>
<para><literal>HttpSessionContextIntegrationFilter</literal>, so a
<literal>Context</literal> can be setup in the
<literal>ContextHolder</literal> at the beginning of a web
request, and any changes to the Context can be copied to the
<literal>HttpSession</literal> when the web request ends (ready
for use with the next web request)</para>
</listitem>
<listitem>
<para>Acegi CAS Processing Filter
(<literal>CasProcessingFilter</literal>)</para>
<para>Authentication processing mechanisms -
<literal>AuthenticationProcessingFilter</literal>,
<literal>CasProcessingFilter</literal>,
<literal>BasicProcessingFilter, HttpRequestIntegrationFilter,
JbossIntegrationFilter</literal> etc - so that the
<literal>ContextHolder</literal> can be modified to contain a
valid <literal>Authentication</literal> request token</para>
</listitem>
<listitem>
<para>Acegi HTTP BASIC Authorization Filter
(<literal>BasicProcessingFilter</literal>)</para>
<para>The <literal>ContextHolderAwareRequestFilter</literal>, if
you are using it to install an Acegi Security aware
<literal>HttpServletRequestWrapper</literal> into your servlet
container</para>
</listitem>
<listitem>
<para>Acegi Security System for Spring HTTP Session Integration
Filter (<literal>HttpSessionIntegrationFilter</literal>)</para>
</listitem>
<listitem>
<para>Acegi HTTP Request Security Filter
(<literal>SecurityEnforcementFilter</literal>)</para>
<para><literal>SecurityEnforcementFilter</literal>, to protect web
URIs and catch any Acegi Security exceptions so that an
appropriate <literal>AuthenticationEntryPoint</literal> can be
launched</para>
</listitem>
</orderedlist>
@ -4353,7 +4346,7 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
<blockquote>
<para>Context on ContextHolder is of type:
net.sf.acegisecurity.context.SecureContextImpl</para>
net.sf.acegisecurity.context.secure.SecureContextImpl</para>
<para>The Context implements SecureContext.</para>

View File

@ -45,6 +45,7 @@
<action dev="benalex" type="add">Additional debug-level logging</action>
<action dev="benalex" type="add">AuthenticationProcessingFilter now provides hook for extra credentials (eg postcodes)</action>
<action dev="benalex" type="add">New WebAuthenticationDetails class now used by processing filters for Authentication.setDetails()</action>
<action dev="benalex" type="update">Significantly refactor "well-known location model" to authentication processing mechanism and HttpSessionContextIntegrationFilter model</action>
</release>
<release version="0.7.0" date="2005-01-16">
<action dev="carlossg" type="add">Major CVS repository restructure to support Maven and eliminate libraries</action>

View File

@ -0,0 +1,38 @@
<html>
<head>
<title>Acegi Security - Upgrading from version 0.7.0 to 0.8.0</title>
</head>
<body>
<h1>Upgrading from 0.7.0 to 0.8.0</h1>
<p>
The following should help most casual users of the project update their
applications:
<ul>
<li>HttpSessionIntegrationFilter has been removed. Use net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter instead.
Note you will need to set the mandatory "context" property to something like "net.sf.acegisecurity.context.security.SecureContextImpl".
It's not the default because we want no dependencies between the context package and the rest of Acegi Security.<br><br></li>
<li>Filter ordering has changed. See the reference guide for confirmation of the correct ordering. Basically you should have
HttpSessionContextIntegrationFilter appear before any of your authentication mechanisms.<br><br></li>
<li>IoC container hosted filter chains can now be used instead of lengthy web.xml declarations. See the reference guide or the
Contacts Sample for further information.<br><br></li>
<li>Certain classes have been moved to new packages: ContextHolderAwareRequestWrapper (and its filter),
AuthenticationSimpleHttpInvokerRequestExecutor, ContextPropagatingRemoteInvocation,
SecureContext (and its implementation). These classes were moved as part of refactorings aimed at
improving the simplicity of the project's design.<br><br></li>
<li>The JaasAuthenticationCallbackHandler interface has had it's setAuthentication method removed. The handle method now takes both the Callback and Authentication objects as arguments.<br><br></li>
<li>Added AuthenticationException to the AutenticationEntryPoint.commence method signature.<br><br></li>
<li>Added AccessDeniedException to the SecurityEncorcementFilter.sendAccessDeniedError method signature.<br><br></li>
</ul>
</body>
</html>

View File

@ -1,22 +0,0 @@
<html>
<head>
<title>Acegi Security - Upgrading from version 0.7.0 to 1.0.0</title>
</head>
<body>
<h1>Upgrading from 0.7.0 to 1.0.0</h1>
<p>
The following should help most casual users of the project update their
applications:
<ul>
<li>The JaasAuthenticationCallbackHandler interface has had it's setAuthentication method removed.
The handle method now takes both the Callback and Authentication objects as arguments.</li>
<li>Added AuthenticationException to the AutenticationEntryPoint.commence method signature.</li>
<li>Added AccessDeniedException to the SecurityEncorcementFilter.sendAccessDeniedError method signature.</li>
</ul>
</body>
</html>

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,7 +19,7 @@ import net.sf.acegisecurity.AccessDeniedException;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.ClassPathXmlApplicationContext;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,7 +21,7 @@ import net.sf.acegisecurity.AccessDeniedException;
import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.ClassPathXmlApplicationContext;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,8 +17,8 @@ package sample.contact;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.SecureContextImpl;
import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.springframework.beans.factory.ListableBeanFactory;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited
/* Copyright 2004, 2005 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,7 +20,7 @@ import net.sf.acegisecurity.acl.basic.BasicAclExtendedDao;
import net.sf.acegisecurity.acl.basic.NamedEntityObjectIdentity;
import net.sf.acegisecurity.acl.basic.SimpleAclEntry;
import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.SecureContext;
import net.sf.acegisecurity.context.security.SecureContext;
import org.springframework.beans.factory.InitializingBean;

View File

@ -21,7 +21,7 @@
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpRequestIntegrationFilter
/**=httpSessionContextIntegrationFilter,httpRequestIntegrationFilter
</value>
</property>
</bean>
@ -46,6 +46,10 @@
<bean id="httpRequestIntegrationFilter" class="net.sf.acegisecurity.adapters.HttpRequestIntegrationFilter"/>
<bean id="httpSessionContextIntegrationFilter" class="net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter">
<property name="context"><value>net.sf.acegisecurity.context.security.SecureContextImpl</value></property>
</bean>
<!-- ===================== HTTP CHANNEL REQUIREMENTS ==================== -->
<!-- Implement by servlet specification -->

View File

@ -19,7 +19,7 @@
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=channelProcessingFilter,casProcessingFilter,basicProcessingFilter,httpSessionIntegrationFilter,securityEnforcementFilter
/**=channelProcessingFilter,httpSessionContextIntegrationFilter,casProcessingFilter,basicProcessingFilter,securityEnforcementFilter
</value>
</property>
</bean>
@ -47,7 +47,9 @@
<property name="realmName"><value>Contacts Realm</value></property>
</bean>
<bean id="httpSessionIntegrationFilter" class="net.sf.acegisecurity.ui.webapp.HttpSessionIntegrationFilter"/>
<bean id="httpSessionContextIntegrationFilter" class="net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter">
<property name="context"><value>net.sf.acegisecurity.context.security.SecureContextImpl</value></property>
</bean>
<bean id="casAuthenticationProvider" class="net.sf.acegisecurity.providers.cas.CasAuthenticationProvider">
<property name="casAuthoritiesPopulator"><ref local="casAuthoritiesPopulator"/></property>

View File

@ -1,6 +1,6 @@
<%@ page import="net.sf.acegisecurity.context.Context" %>
<%@ page import="net.sf.acegisecurity.context.ContextHolder" %>
<%@ page import="net.sf.acegisecurity.context.SecureContext" %>
<%@ page import="net.sf.acegisecurity.context.security.SecureContext" %>
<%@ page import="net.sf.acegisecurity.Authentication" %>
<%@ page import="net.sf.acegisecurity.GrantedAuthority" %>
<%@ page import="net.sf.acegisecurity.adapters.AuthByAdapter" %>

View File

@ -15,13 +15,13 @@
<!-- ======================== FILTER CHAIN ======================= -->
<!-- if you wish to use channel security, add "channelProcessingFilter," in front
of "authenticationProcessingFilter" in the list below -->
of "httpSessionContextIntegrationFilter" in the list below -->
<bean id="filterChainProxy" class="net.sf.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=authenticationProcessingFilter,basicProcessingFilter,httpSessionIntegrationFilter,securityEnforcementFilter
/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,basicProcessingFilter,securityEnforcementFilter
</value>
</property>
</bean>
@ -75,7 +75,9 @@
<property name="realmName"><value>Contacts Realm</value></property>
</bean>
<bean id="httpSessionIntegrationFilter" class="net.sf.acegisecurity.ui.webapp.HttpSessionIntegrationFilter"/>
<bean id="httpSessionContextIntegrationFilter" class="net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter">
<property name="context"><value>net.sf.acegisecurity.context.security.SecureContextImpl</value></property>
</bean>
<!-- ===================== HTTP CHANNEL REQUIREMENTS ==================== -->