SEC-234: Allow pluggable AuthenticationDetailsSource strategy interface.

This commit is contained in:
Ben Alex 2006-04-26 05:24:49 +00:00
parent b1becf9277
commit a47a342ce6
13 changed files with 683 additions and 521 deletions

View File

@ -19,7 +19,8 @@ import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.ui.WebAuthenticationDetails;
import org.acegisecurity.ui.AuthenticationDetailsSource;
import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
import org.acegisecurity.userdetails.memory.UserAttribute;
@ -61,6 +62,7 @@ public class AnonymousProcessingFilter implements Filter, InitializingBean {
//~ Instance fields ========================================================
private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
private String key;
private UserAttribute userAttribute;
private boolean removeAfterRequest = true;
@ -96,8 +98,8 @@ public class AnonymousProcessingFilter implements Filter, InitializingBean {
AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken(key,
userAttribute.getPassword(), userAttribute.getAuthorities());
auth.setDetails(new WebAuthenticationDetails(
(HttpServletRequest) request, false));
auth.setDetails(authenticationDetailsSource.buildDetails(
(HttpServletRequest) request));
return auth;
}
@ -167,6 +169,13 @@ public class AnonymousProcessingFilter implements Filter, InitializingBean {
return removeAfterRequest;
}
public void setAuthenticationDetailsSource(
AuthenticationDetailsSource authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource,
"AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
public void setKey(String key) {
this.key = key;
}

View File

@ -143,6 +143,7 @@ public abstract class AbstractProcessingFilter implements Filter,
//~ Instance fields ========================================================
protected ApplicationEventPublisher eventPublisher;
protected AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
private AuthenticationManager authenticationManager;
protected final Log logger = LogFactory.getLog(this.getClass());
protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
@ -371,6 +372,13 @@ public abstract class AbstractProcessingFilter implements Filter,
this.eventPublisher = eventPublisher;
}
public void setAuthenticationDetailsSource(
AuthenticationDetailsSource authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource,
"AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
this.authenticationFailureUrl = authenticationFailureUrl;
}

View File

@ -0,0 +1,41 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.ui;
import javax.servlet.http.HttpServletRequest;
/**
* Provides a {@link org.acegisecurity.Authentication#getDetails()} object for
* a given web request.
*
* @author Ben Alex
* @version $Id$
*/
public interface AuthenticationDetailsSource {
//~ Methods ================================================================
/**
* Called by a class when it wishes a new authentication details instance
* to be created.
*
* @param request the request object, which may be used by the
* authentication details object
*
* @return a fully-configured authentication details instance
*/
public Object buildDetails(HttpServletRequest request);
}

View File

@ -0,0 +1,69 @@
/* Copyright 2004, 2005, 2006 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 org.acegisecurity.ui;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import javax.servlet.http.HttpServletRequest;
/**
* Base implementation of {@link AuthenticationDetailsSource}.
*
* <P>
* By default will create an instance of <code>WebAuthenticationDetails</code>.
* Any object that accepts a <code>HttpServletRequest</code> as its sole
* constructor can be used instead of this default.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public class AuthenticationDetailsSourceImpl
implements AuthenticationDetailsSource {
//~ Instance fields ========================================================
private Class clazz = WebAuthenticationDetails.class;
//~ Methods ================================================================
public Object buildDetails(HttpServletRequest request) {
try {
Constructor constructor = clazz.getConstructor(new Class[] {HttpServletRequest.class});
return constructor.newInstance(new Object[] {request});
} catch (NoSuchMethodException ex) {
ReflectionUtils.handleReflectionException(ex);
} catch (InvocationTargetException ex) {
ReflectionUtils.handleReflectionException(ex);
} catch (InstantiationException ex) {
ReflectionUtils.handleReflectionException(ex);
} catch (IllegalAccessException ex) {
ReflectionUtils.handleReflectionException(ex);
}
return null;
}
public void setClazz(Class clazz) {
Assert.notNull(clazz, "Class required");
this.clazz = clazz;
}
}

View File

@ -52,15 +52,8 @@ public class WebAuthenticationDetails implements SessionIdentifierAware,
*/
public WebAuthenticationDetails(HttpServletRequest request) {
this.remoteAddress = request.getRemoteAddr();
this.sessionId = request.getSession(true).getId();
doPopulateAdditionalInformation(request);
}
public WebAuthenticationDetails(HttpServletRequest request,
boolean forceSessionCreation) {
this.remoteAddress = request.getRemoteAddr();
HttpSession session = request.getSession(forceSessionCreation);
HttpSession session = request.getSession(false);
this.sessionId = (session != null) ? session.getId() : null;
doPopulateAdditionalInformation(request);

View File

@ -23,8 +23,9 @@ import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.AuthenticationDetailsSource;
import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
import org.acegisecurity.ui.AuthenticationEntryPoint;
import org.acegisecurity.ui.WebAuthenticationDetails;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
@ -115,9 +116,15 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
private AuthenticationEntryPoint authenticationEntryPoint;
private AuthenticationManager authenticationManager;
private boolean ignoreFailure = false;
private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
//~ Methods ================================================================
public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(this.authenticationManager,
"An AuthenticationManager is required");
@ -168,8 +175,7 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
|| !existingAuth.isAuthenticated()) {
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username,
password);
authRequest.setDetails(new WebAuthenticationDetails(
httpRequest, false));
authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request));
Authentication authResult;

View File

@ -19,7 +19,6 @@ import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.AbstractProcessingFilter;
import org.acegisecurity.ui.WebAuthenticationDetails;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
@ -105,7 +104,7 @@ public class CasProcessingFilter extends AbstractProcessingFilter {
UsernamePasswordAuthenticationToken authRequest =
new UsernamePasswordAuthenticationToken(username, password);
authRequest.setDetails(new WebAuthenticationDetails(request, false));
authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request));
return this.getAuthenticationManager().authenticate(authRequest);
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
/* Copyright 2004, 2005, 2006 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.
@ -15,7 +15,42 @@
package org.acegisecurity.ui.digestauth;
import org.acegisecurity.AcegiMessageSource;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationServiceException;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.dao.UserCache;
import org.acegisecurity.providers.dao.cache.NullUserCache;
import org.acegisecurity.ui.AuthenticationDetailsSource;
import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.acegisecurity.util.StringSplitUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter;
@ -27,30 +62,6 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.acegisecurity.AcegiMessageSource;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationServiceException;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.dao.UserCache;
import org.acegisecurity.providers.dao.cache.NullUserCache;
import org.acegisecurity.ui.WebAuthenticationDetails;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.acegisecurity.util.StringSplitUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Processes a HTTP request's Digest authorization headers, putting the result
@ -84,9 +95,9 @@ import org.springframework.util.StringUtils;
*
* <p>
* If authentication fails, an {@link
* org.acegisecurity.ui.AuthenticationEntryPoint
* AuthenticationEntryPoint} implementation is called. This must always be
* {@link DigestProcessingFilterEntryPoint}, which will prompt the user to
* org.acegisecurity.ui.AuthenticationEntryPoint AuthenticationEntryPoint}
* implementation is called. This must always be {@link
* DigestProcessingFilterEntryPoint}, which will prompt the user to
* authenticate again via Digest authentication.
* </p>
*
@ -112,10 +123,11 @@ public class DigestProcessingFilter implements Filter, InitializingBean,
//~ Instance fields ========================================================
private UserDetailsService userDetailsService;
private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
private DigestProcessingFilterEntryPoint authenticationEntryPoint;
protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
private UserCache userCache = new NullUserCache();
private UserDetailsService userDetailsService;
private boolean passwordAlreadyEncoded = false;
//~ Methods ================================================================
@ -369,10 +381,11 @@ public class DigestProcessingFilter implements Filter, InitializingBean,
+ "' with response: '" + responseDigest + "'");
}
UsernamePasswordAuthenticationToken authRequest =
new UsernamePasswordAuthenticationToken(user, user.getPassword());
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(user,
user.getPassword());
authRequest.setDetails(new WebAuthenticationDetails(httpRequest, false));
authRequest.setDetails(authenticationDetailsSource.buildDetails(
(HttpServletRequest) request));
SecurityContextHolder.getContext().setAuthentication(authRequest);
}
@ -405,8 +418,8 @@ public class DigestProcessingFilter implements Filter, InitializingBean,
* <code>response</code> independently. Provided as a static method to
* simplify the coding of user agents.
*
* @param passwordAlreadyEncoded true if the password argument is already encoded in
* the correct format. False if it is plain text.
* @param passwordAlreadyEncoded true if the password argument is already
* encoded in the correct format. False if it is plain text.
* @param username the user's login name.
* @param realm the name of the realm.
* @param password the user's password in plaintext or ready-encoded.
@ -419,7 +432,8 @@ public class DigestProcessingFilter implements Filter, InitializingBean,
*
* @return the MD5 of the digest authentication response, encoded in hex
*
* @throws IllegalArgumentException if the supplied qop value is unsupported.
* @throws IllegalArgumentException if the supplied qop value is
* unsupported.
*/
public static String generateDigest(boolean passwordAlreadyEncoded,
String username, String realm, String password, String httpMethod,
@ -454,10 +468,6 @@ public class DigestProcessingFilter implements Filter, InitializingBean,
return digestMd5;
}
public UserDetailsService getUserDetailsService() {
return userDetailsService;
}
public DigestProcessingFilterEntryPoint getAuthenticationEntryPoint() {
return authenticationEntryPoint;
}
@ -466,10 +476,17 @@ public class DigestProcessingFilter implements Filter, InitializingBean,
return userCache;
}
public UserDetailsService getUserDetailsService() {
return userDetailsService;
}
public void init(FilterConfig ignored) throws ServletException {}
public void setUserDetailsService(UserDetailsService authenticationDao) {
this.userDetailsService = authenticationDao;
public void setAuthenticationDetailsSource(
AuthenticationDetailsSource authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource,
"AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
public void setAuthenticationEntryPoint(
@ -488,4 +505,8 @@ public class DigestProcessingFilter implements Filter, InitializingBean,
public void setUserCache(UserCache userCache) {
this.userCache = userCache;
}
public void setUserDetailsService(UserDetailsService authenticationDao) {
this.userDetailsService = authenticationDao;
}
}

View File

@ -19,7 +19,8 @@ import org.acegisecurity.Authentication;
import org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken;
import org.acegisecurity.ui.WebAuthenticationDetails;
import org.acegisecurity.ui.AuthenticationDetailsSource;
import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
@ -116,6 +117,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices,
//~ Instance fields ========================================================
private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
private String key;
private String parameter = DEFAULT_PARAMETER;
private UserDetailsService userDetailsService;
@ -232,8 +234,8 @@ public class TokenBasedRememberMeServices implements RememberMeServices,
RememberMeAuthenticationToken auth = new RememberMeAuthenticationToken(this.key,
userDetails, userDetails.getAuthorities());
auth.setDetails(new WebAuthenticationDetails(request,
false));
auth.setDetails(authenticationDetailsSource.buildDetails(
(HttpServletRequest) request));
return auth;
} else {
@ -347,15 +349,23 @@ public class TokenBasedRememberMeServices implements RememberMeServices,
return cookie;
}
protected Cookie makeValidCookie(long expiryTime, String tokenValueBase64, HttpServletRequest request) {
protected Cookie makeValidCookie(long expiryTime, String tokenValueBase64,
HttpServletRequest request) {
Cookie cookie = new Cookie(ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY,
tokenValueBase64);
cookie.setMaxAge(60 * 60 * 24 * 365 * 5); // 5 years
cookie.setPath(request.getContextPath());
return cookie;
}
public void setAuthenticationDetailsSource(
AuthenticationDetailsSource authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource,
"AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
public void setKey(String key) {
this.key = key;
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
/* Copyright 2004, 2005, 2006 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.
@ -15,7 +15,45 @@
package org.acegisecurity.ui.switchuser;
import org.acegisecurity.AccountExpiredException;
import org.acegisecurity.AcegiMessageSource;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationCredentialsNotFoundException;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.CredentialsExpiredException;
import org.acegisecurity.DisabledException;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.LockedException;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.event.authentication.AuthenticationSwitchUserEvent;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.AuthenticationDetailsSource;
import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -29,33 +67,6 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.acegisecurity.AccountExpiredException;
import org.acegisecurity.AcegiMessageSource;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationCredentialsNotFoundException;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.CredentialsExpiredException;
import org.acegisecurity.DisabledException;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.LockedException;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.event.authentication.AuthenticationSwitchUserEvent;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.WebAuthenticationDetails;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert;
/**
* Switch User processing filter responsible for user context switching.
@ -104,7 +115,6 @@ import org.springframework.util.Assert;
* </pre>
* </p>
*
*
* @author Mark St.Godard
* @version $Id$
*
@ -124,15 +134,16 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
//~ Instance fields ========================================================
private ApplicationEventPublisher eventPublisher;
// ~ Instance fields
// ========================================================
private UserDetailsService userDetailsService;
private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
private String exitUserUrl = "/j_acegi_exit_user";
private String switchUserUrl = "/j_acegi_switch_user";
private String targetUrl;
// ~ Instance fields
// ========================================================
private UserDetailsService userDetailsService;
//~ Methods ================================================================
public void afterPropertiesSet() throws Exception {
@ -160,369 +171,344 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
Authentication current = SecurityContextHolder.getContext()
.getAuthentication();
if (null == current) {
throw new AuthenticationCredentialsNotFoundException(messages
.getMessage("SwitchUserProcessingFilter.noCurrentUser",
"No current user associated with this request"));
}
// check to see if the current user did actual switch to another user
// if so, get the original source user so we can switch back
Authentication original = getSourceAuthentication(current);
if (original == null) {
logger.error(
"Could not find original user Authentication object!");
throw new AuthenticationCredentialsNotFoundException(messages
.getMessage(
"SwitchUserProcessingFilter.noOriginalAuthentication",
"Could not find original Authentication object"));
}
// get the source user details
UserDetails originalUser = null;
Object obj = original.getPrincipal();
if ((obj != null) && obj instanceof UserDetails) {
originalUser = (UserDetails) obj;
}
// publish event
if (this.eventPublisher != null) {
eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
current, originalUser));
}
return original;
if (null == current) {
throw new AuthenticationCredentialsNotFoundException(messages
.getMessage("SwitchUserProcessingFilter.noCurrentUser",
"No current user associated with this request"));
}
/**
* Attempt to switch to another user. If the user does not exist or
* is not active, return null.
*
* @param request The http request
*
* @return The new <code>Authentication</code> request if
* successfully switched to another user,
* <code>null</code> otherwise.
*
* @throws AuthenticationException
* @throws UsernameNotFoundException If the target user is not
* found.
* @throws LockedException DOCUMENT ME!
* @throws DisabledException If the target user is disabled.
* @throws AccountExpiredException If the target user account is
* expired.
* @throws CredentialsExpiredException If the target user
* credentials are expired.
*/
protected Authentication attemptSwitchUser(
HttpServletRequest request) throws AuthenticationException {
UsernamePasswordAuthenticationToken targetUserRequest = null;
// check to see if the current user did actual switch to another user
// if so, get the original source user so we can switch back
Authentication original = getSourceAuthentication(current);
String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY);
if (original == null) {
logger.error("Could not find original user Authentication object!");
throw new AuthenticationCredentialsNotFoundException(messages
.getMessage("SwitchUserProcessingFilter.noOriginalAuthentication",
"Could not find original Authentication object"));
}
if (username == null) {
username = "";
// get the source user details
UserDetails originalUser = null;
Object obj = original.getPrincipal();
if ((obj != null) && obj instanceof UserDetails) {
originalUser = (UserDetails) obj;
}
// publish event
if (this.eventPublisher != null) {
eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
current, originalUser));
}
return original;
}
/**
* Attempt to switch to another user. If the user does not exist or is not
* active, return null.
*
* @param request The http request
*
* @return The new <code>Authentication</code> request if successfully
* switched to another user, <code>null</code> otherwise.
*
* @throws AuthenticationException
* @throws UsernameNotFoundException If the target user is not found.
* @throws LockedException DOCUMENT ME!
* @throws DisabledException If the target user is disabled.
* @throws AccountExpiredException If the target user account is expired.
* @throws CredentialsExpiredException If the target user credentials are
* expired.
*/
protected Authentication attemptSwitchUser(HttpServletRequest request)
throws AuthenticationException {
UsernamePasswordAuthenticationToken targetUserRequest = null;
String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY);
if (username == null) {
username = "";
}
if (logger.isDebugEnabled()) {
logger.debug("Attempt to switch to user [" + username + "]");
}
// load the user by name
UserDetails targetUser = this.userDetailsService.loadUserByUsername(username);
// user not found
if (targetUser == null) {
throw new UsernameNotFoundException(messages.getMessage(
"SwitchUserProcessingFilter.usernameNotFound",
new Object[] {username}, "Username {0} not found"));
}
// account is expired
if (!targetUser.isAccountNonLocked()) {
throw new LockedException(messages.getMessage(
"SwitchUserProcessingFilter.locked",
"User account is locked"));
}
// user is disabled
if (!targetUser.isEnabled()) {
throw new DisabledException(messages.getMessage(
"SwitchUserProcessingFilter.disabled", "User is disabled"));
}
// account is expired
if (!targetUser.isAccountNonExpired()) {
throw new AccountExpiredException(messages.getMessage(
"SwitchUserProcessingFilter.expired",
"User account has expired"));
}
// credentials expired
if (!targetUser.isCredentialsNonExpired()) {
throw new CredentialsExpiredException(messages.getMessage(
"SwitchUserProcessingFilter.credentialsExpired",
"User credentials have expired"));
}
// ok, create the switch user token
targetUserRequest = createSwitchUserToken(request, username, targetUser);
if (logger.isDebugEnabled()) {
logger.debug("Switch User Token [" + targetUserRequest + "]");
}
// publish event
if (this.eventPublisher != null) {
eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
SecurityContextHolder.getContext().getAuthentication(),
targetUser));
}
return targetUserRequest;
}
/**
* Create a switch user token that contains an additional
* <tt>GrantedAuthority</tt> that contains the original
* <code>Authentication</code> object.
*
* @param request The http servlet request.
* @param username The username of target user
* @param targetUser The target user
*
* @return The authentication token
*
* @see SwitchUserGrantedAuthority
*/
private UsernamePasswordAuthenticationToken createSwitchUserToken(
HttpServletRequest request, String username, UserDetails targetUser) {
UsernamePasswordAuthenticationToken targetUserRequest;
// grant an additional authority that contains the original Authentication object
// which will be used to 'exit' from the current switched user.
Authentication currentAuth = SecurityContextHolder.getContext()
.getAuthentication();
GrantedAuthority switchAuthority = new SwitchUserGrantedAuthority(ROLE_PREVIOUS_ADMINISTRATOR,
currentAuth);
// get the original authorities
List orig = Arrays.asList(targetUser.getAuthorities());
// add the new switch user authority
List newAuths = new ArrayList(orig);
newAuths.add(switchAuthority);
GrantedAuthority[] authorities = {};
authorities = (GrantedAuthority[]) newAuths.toArray(authorities);
// create the new authentication token
targetUserRequest = new UsernamePasswordAuthenticationToken(targetUser,
targetUser.getPassword(), authorities);
// set details
targetUserRequest.setDetails(authenticationDetailsSource.buildDetails(
(HttpServletRequest) request));
return targetUserRequest;
}
public void destroy() {}
/**
* @see javax.servlet.Filter#doFilter
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
Assert.isInstanceOf(HttpServletRequest.class, request);
Assert.isInstanceOf(HttpServletResponse.class, response);
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// check for switch or exit request
if (requiresSwitchUser(httpRequest)) {
// if set, attempt switch and store original
Authentication targetUser = attemptSwitchUser(httpRequest);
// update the current context to the new target user
SecurityContextHolder.getContext().setAuthentication(targetUser);
// redirect to target url
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest
.getContextPath() + targetUrl));
return;
} else if (requiresExitUser(httpRequest)) {
// get the original authentication object (if exists)
Authentication originalUser = attemptExitUser(httpRequest);
// update the current context back to the original user
SecurityContextHolder.getContext().setAuthentication(originalUser);
// redirect to target url
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest
.getContextPath() + targetUrl));
return;
}
chain.doFilter(request, response);
}
/**
* Find the original <code>Authentication</code> object from the current
* user's granted authorities. A successfully switched user should have a
* <code>SwitchUserGrantedAuthority</code> that contains the original
* source user <code>Authentication</code> object.
*
* @param current The current <code>Authentication</code> object
*
* @return The source user <code>Authentication</code> object or
* <code>null</code> otherwise.
*/
private Authentication getSourceAuthentication(Authentication current) {
Authentication original = null;
// iterate over granted authorities and find the 'switch user' authority
GrantedAuthority[] authorities = current.getAuthorities();
for (int i = 0; i < authorities.length; i++) {
// check for switch user type of authority
if (authorities[i] instanceof SwitchUserGrantedAuthority) {
original = ((SwitchUserGrantedAuthority) authorities[i])
.getSource();
logger.debug("Found original switch user granted authority ["
+ original + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Attempt to switch to user [" + username + "]");
}
// load the user by name
UserDetails targetUser = this.userDetailsService
.loadUserByUsername(username);
// user not found
if (targetUser == null) {
throw new UsernameNotFoundException(messages.getMessage(
"SwitchUserProcessingFilter.usernameNotFound",
new Object[] {username},
"Username {0} not found"));
}
// account is expired
if (!targetUser.isAccountNonLocked()) {
throw new LockedException(messages.getMessage(
"SwitchUserProcessingFilter.locked",
"User account is locked"));
}
// user is disabled
if (!targetUser.isEnabled()) {
throw new DisabledException(messages.getMessage(
"SwitchUserProcessingFilter.disabled",
"User is disabled"));
}
// account is expired
if (!targetUser.isAccountNonExpired()) {
throw new AccountExpiredException(messages.getMessage(
"SwitchUserProcessingFilter.expired",
"User account has expired"));
}
// credentials expired
if (!targetUser.isCredentialsNonExpired()) {
throw new CredentialsExpiredException(messages
.getMessage(
"SwitchUserProcessingFilter.credentialsExpired",
"User credentials have expired"));
}
// ok, create the switch user token
targetUserRequest = createSwitchUserToken(request,
username, targetUser);
if (logger.isDebugEnabled()) {
logger.debug("Switch User Token [" + targetUserRequest + "]");
}
// publish event
if (this.eventPublisher != null) {
eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
SecurityContextHolder.getContext().getAuthentication(),
targetUser));
}
return targetUserRequest;
}
/**
* Create a switch user token that contains an additional
* <tt>GrantedAuthority</tt> that contains the original
* <code>Authentication</code> object.
*
* @param request The http servlet request.
* @param username The username of target user
* @param targetUser The target user
*
* @return The authentication token
*
* @see SwitchUserGrantedAuthority
*/
private UsernamePasswordAuthenticationToken createSwitchUserToken(
HttpServletRequest request, String username,
UserDetails targetUser) {
UsernamePasswordAuthenticationToken targetUserRequest;
return original;
}
// grant an additional authority that contains the original Authentication object
// which will be used to 'exit' from the current switched user.
Authentication currentAuth = SecurityContextHolder.getContext()
.getAuthentication();
GrantedAuthority switchAuthority = new SwitchUserGrantedAuthority(ROLE_PREVIOUS_ADMINISTRATOR,
currentAuth);
public void init(FilterConfig ignored) throws ServletException {}
// get the original authorities
List orig = Arrays.asList(targetUser.getAuthorities());
/**
* Checks the request URI for the presence of <tt>exitUserUrl</tt>.
*
* @param request The http servlet request
*
* @return <code>true</code> if the request requires a exit user,
* <code>false</code> otherwise.
*
* @see SwitchUserProcessingFilter#exitUserUrl
*/
protected boolean requiresExitUser(HttpServletRequest request) {
String uri = stripUri(request);
// add the new switch user authority
List newAuths = new ArrayList(orig);
newAuths.add(switchAuthority);
return uri.endsWith(request.getContextPath() + exitUserUrl);
}
GrantedAuthority[] authorities = {};
authorities = (GrantedAuthority[]) newAuths.toArray(authorities);
/**
* Checks the request URI for the presence of <tt>switchUserUrl</tt>.
*
* @param request The http servlet request
*
* @return <code>true</code> if the request requires a switch,
* <code>false</code> otherwise.
*
* @see SwitchUserProcessingFilter#switchUserUrl
*/
protected boolean requiresSwitchUser(HttpServletRequest request) {
String uri = stripUri(request);
// create the new authentication token
targetUserRequest = new UsernamePasswordAuthenticationToken(targetUser,
targetUser.getPassword(), authorities);
return uri.endsWith(request.getContextPath() + switchUserUrl);
}
// set details
targetUserRequest.setDetails(new WebAuthenticationDetails(
request, false));
public void setApplicationEventPublisher(
ApplicationEventPublisher eventPublisher) throws BeansException {
this.eventPublisher = eventPublisher;
}
return targetUserRequest;
public void setAuthenticationDetailsSource(
AuthenticationDetailsSource authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource,
"AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
/**
* Set the URL to respond to exit user processing.
*
* @param exitUserUrl The exit user URL.
*/
public void setExitUserUrl(String exitUserUrl) {
this.exitUserUrl = exitUserUrl;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
/**
* Set the URL to respond to switch user processing.
*
* @param switchUserUrl The switch user URL.
*/
public void setSwitchUserUrl(String switchUserUrl) {
this.switchUserUrl = switchUserUrl;
}
/**
* Sets the URL to go to after a successful switch / exit user request.
*
* @param targetUrl The target url.
*/
public void setTargetUrl(String targetUrl) {
this.targetUrl = targetUrl;
}
/**
* Sets the authentication data access object.
*
* @param authenticationDao The authentication dao
*/
public void setUserDetailsService(UserDetailsService authenticationDao) {
this.userDetailsService = authenticationDao;
}
/**
* Strips any content after the ';' in the request URI
*
* @param request The http request
*
* @return The stripped uri
*/
private static String stripUri(HttpServletRequest request) {
String uri = request.getRequestURI();
int idx = uri.indexOf(';');
if (idx > 0) {
uri = uri.substring(0, idx);
}
public void destroy() {}
/**
* @see javax.servlet.Filter#doFilter
*/
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
Assert.isInstanceOf(HttpServletRequest.class, request);
Assert.isInstanceOf(HttpServletResponse.class, response);
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// check for switch or exit request
if (requiresSwitchUser(httpRequest)) {
// if set, attempt switch and store original
Authentication targetUser = attemptSwitchUser(httpRequest);
// update the current context to the new target user
SecurityContextHolder.getContext()
.setAuthentication(targetUser);
// redirect to target url
httpResponse.sendRedirect(httpResponse
.encodeRedirectURL(httpRequest
.getContextPath() + targetUrl));
return;
} else if (requiresExitUser(httpRequest)) {
// get the original authentication object (if exists)
Authentication originalUser = attemptExitUser(httpRequest);
// update the current context back to the original user
SecurityContextHolder.getContext()
.setAuthentication(originalUser);
// redirect to target url
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(
httpRequest.getContextPath() + targetUrl));
return;
}
chain.doFilter(request, response);
}
/**
* Find the original <code>Authentication</code> object from
* the current user's granted authorities. A successfully switched
* user should have a <code>SwitchUserGrantedAuthority</code>
* that contains the original source user <code>Authentication</code>
* object.
*
* @param current The current <code>Authentication</code>
* object
*
* @return The source user <code>Authentication</code>
* object or <code>null</code> otherwise.
*/
private Authentication getSourceAuthentication(
Authentication current) {
Authentication original = null;
// iterate over granted authorities and find the 'switch user' authority
GrantedAuthority[] authorities = current
.getAuthorities();
for (int i = 0; i < authorities.length; i++) {
// check for switch user type of authority
if (authorities[i] instanceof SwitchUserGrantedAuthority) {
original = ((SwitchUserGrantedAuthority) authorities[i])
.getSource();
logger.debug(
"Found original switch user granted authority ["
+ original + "]");
}
}
return original;
}
public void init(FilterConfig ignored)
throws ServletException {}
/**
* Checks the request URI for the presence
* of <tt>exitUserUrl</tt>.
*
* @param request The http servlet request
*
* @return <code>true</code> if the request requires a exit user,
* <code>false</code> otherwise.
*
* @see SwitchUserProcessingFilter#exitUserUrl
*/
protected boolean requiresExitUser(
HttpServletRequest request) {
String uri = stripUri(request);
return uri.endsWith(request
.getContextPath() + exitUserUrl);
}
/**
* Checks the request URI for the presence of <tt>switchUserUrl</tt>.
*
* @param request The http servlet request
*
* @return <code>true</code> if the request requires a switch,
* <code>false</code> otherwise.
*
* @see SwitchUserProcessingFilter#switchUserUrl
*/
protected boolean requiresSwitchUser(
HttpServletRequest request) {
String uri = stripUri(request);
return uri.endsWith(request.getContextPath() + switchUserUrl);
}
public void setApplicationEventPublisher(
ApplicationEventPublisher eventPublisher)
throws BeansException {
this.eventPublisher = eventPublisher;
}
/**
* Sets the authentication data access object.
*
* @param authenticationDao The authentication dao
*/
public void setUserDetailsService(
UserDetailsService authenticationDao) {
this.userDetailsService = authenticationDao;
}
/**
* Set the URL to respond to exit user processing.
*
* @param exitUserUrl The exit user URL.
*/
public void setExitUserUrl(
String exitUserUrl) {
this.exitUserUrl = exitUserUrl;
}
public void setMessageSource(
MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
/**
* Set the URL to respond to switch user processing.
*
* @param switchUserUrl The switch user URL.
*/
public void setSwitchUserUrl(String switchUserUrl) {
this.switchUserUrl = switchUserUrl;
}
/**
* Sets the URL to go to after a successful switch / exit user
* request.
*
* @param targetUrl The target url.
*/
public void setTargetUrl(
String targetUrl) {
this.targetUrl = targetUrl;
}
/**
* Strips any content after the ';' in the request URI
*
* @param request The http request
*
* @return The stripped uri
*/
private static String stripUri(HttpServletRequest request) {
String uri = request.getRequestURI();
int idx = uri.indexOf(';');
if (idx > 0) {
uri = uri.substring(0,
idx);
}
return uri;
}
return uri;
}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
/* Copyright 2004, 2005, 2006 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,10 @@ package org.acegisecurity.ui.webapp;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.AbstractProcessingFilter;
import org.acegisecurity.ui.WebAuthenticationDetails;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
@ -55,15 +56,6 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter {
//~ Methods ================================================================
/**
* This filter by default responds to <code>/j_acegi_security_check</code>.
*
* @return the default
*/
public String getDefaultFilterProcessesUrl() {
return "/j_acegi_security_check";
}
public Authentication attemptAuthentication(HttpServletRequest request)
throws AuthenticationException {
String username = obtainUsername(request);
@ -84,28 +76,23 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter {
setDetails(request, authRequest);
// Place the last username attempted into HttpSession for views
request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY,
username);
request.getSession()
.setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username);
return this.getAuthenticationManager().authenticate(authRequest);
}
public void init(FilterConfig filterConfig) throws ServletException {}
/**
* Provided so that subclasses may configure what is put into the
* authentication request's details property. The default implementation
* simply constructs {@link WebAuthenticationDetails}.
* This filter by default responds to <code>/j_acegi_security_check</code>.
*
* @param request that an authentication request is being created for
* @param authRequest the authentication request object that should have
* its details set
* @return the default
*/
protected void setDetails(HttpServletRequest request,
UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(new WebAuthenticationDetails(request, false));
public String getDefaultFilterProcessesUrl() {
return "/j_acegi_security_check";
}
public void init(FilterConfig filterConfig) throws ServletException {}
/**
* Enables subclasses to override the composition of the password, such as
* by including additional values and a separator.
@ -141,4 +128,17 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter {
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(ACEGI_SECURITY_FORM_USERNAME_KEY);
}
/**
* Provided so that subclasses may configure what is put into the
* authentication request's details property.
*
* @param request that an authentication request is being created for
* @param authRequest the authentication request object that should have
* its details set
*/
protected void setDetails(HttpServletRequest request,
UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
/* Copyright 2004, 2005, 2006 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,19 +18,24 @@ package org.acegisecurity.ui.x509;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationManager;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent;
import org.acegisecurity.providers.x509.X509AuthenticationToken;
import org.acegisecurity.ui.AbstractProcessingFilter;
import org.acegisecurity.ui.WebAuthenticationDetails;
import org.acegisecurity.ui.AuthenticationDetailsSource;
import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.util.Assert;
@ -60,10 +65,11 @@ import javax.servlet.http.HttpServletResponse;
*
* <p>
* If authentication is successful, an {@link
* org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} will be
* published to the application context. No events will be published if
* authentication was unsuccessful, because this would generally be recorded
* via an <code>AuthenticationManager</code>-specific application event.
* org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent}
* will be published to the application context. No events will be published
* if authentication was unsuccessful, because this would generally be
* recorded via an <code>AuthenticationManager</code>-specific application
* event.
* </p>
*
* <p>
@ -76,7 +82,7 @@ import javax.servlet.http.HttpServletResponse;
* @version $Id$
*/
public class X509ProcessingFilter implements Filter, InitializingBean,
ApplicationEventPublisherAware {
ApplicationEventPublisherAware {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(X509ProcessingFilter.class);
@ -84,19 +90,11 @@ public class X509ProcessingFilter implements Filter, InitializingBean,
//~ Instance fields ========================================================
private ApplicationEventPublisher eventPublisher;
private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
private AuthenticationManager authenticationManager;
//~ Methods ================================================================
public void setApplicationEventPublisher(ApplicationEventPublisher context) {
this.eventPublisher = context;
}
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(authenticationManager,
"An AuthenticationManager must be set");
@ -154,7 +152,8 @@ public class X509ProcessingFilter implements Filter, InitializingBean,
try {
X509AuthenticationToken authRequest = new X509AuthenticationToken(clientCertificate);
authRequest.setDetails(new WebAuthenticationDetails(httpRequest));
authRequest.setDetails(authenticationDetailsSource.buildDetails(
(HttpServletRequest) request));
authResult = authenticationManager.authenticate(authRequest);
successfulAuthentication(httpRequest, httpResponse, authResult);
} catch (AuthenticationException failed) {
@ -165,8 +164,39 @@ public class X509ProcessingFilter implements Filter, InitializingBean,
filterChain.doFilter(request, response);
}
private X509Certificate extractClientCertificate(HttpServletRequest request) {
X509Certificate[] certs = (X509Certificate[]) request.getAttribute(
"javax.servlet.request.X509Certificate");
if ((certs != null) && (certs.length > 0)) {
return certs[0];
}
if (logger.isDebugEnabled()) {
logger.debug("No client certificate found in request.");
}
return null;
}
public void init(FilterConfig ignored) throws ServletException {}
public void setApplicationEventPublisher(ApplicationEventPublisher context) {
this.eventPublisher = context;
}
public void setAuthenticationDetailsSource(
AuthenticationDetailsSource authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource,
"AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
/**
* Puts the <code>Authentication</code> instance returned by the
* authentication manager into the secure context.
@ -206,25 +236,12 @@ public class X509ProcessingFilter implements Filter, InitializingBean,
SecurityContextHolder.getContext().setAuthentication(null);
if (logger.isDebugEnabled()) {
logger.debug("Updated SecurityContextHolder to contain null Authentication");
logger.debug(
"Updated SecurityContextHolder to contain null Authentication");
}
request.getSession().setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY,
request.getSession()
.setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY,
failed);
}
private X509Certificate extractClientCertificate(HttpServletRequest request) {
X509Certificate[] certs = (X509Certificate[]) request.getAttribute(
"javax.servlet.request.X509Certificate");
if ((certs != null) && (certs.length > 0)) {
return certs[0];
}
if (logger.isDebugEnabled()) {
logger.debug("No client certificate found in request.");
}
return null;
}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004, 2005 Acegi Technology Pty Limited
/* Copyright 2004, 2005, 2006 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,8 +18,11 @@ package org.acegisecurity.concurrent;
import junit.framework.TestCase;
import org.acegisecurity.Authentication;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.WebAuthenticationDetails;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
@ -33,6 +36,23 @@ import org.springframework.mock.web.MockHttpSession;
public class ConcurrentSessionControllerImplTests extends TestCase {
//~ Methods ================================================================
private Authentication createAuthentication(String user, String password) {
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user,
password);
auth.setDetails(createWebDetails(auth));
return auth;
}
private WebAuthenticationDetails createWebDetails(Authentication auth) {
MockHttpSession session = new MockHttpSession();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setSession(session);
request.setUserPrincipal(auth);
return new WebAuthenticationDetails(request);
}
public void testLifecycle() throws Exception {
// Build a test fixture
ConcurrentSessionControllerImpl sc = new ConcurrentSessionControllerImpl();
@ -103,21 +123,4 @@ public class ConcurrentSessionControllerImplTests extends TestCase {
assertTrue(true);
}
}
private Authentication createAuthentication(String user, String password) {
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user,
password);
auth.setDetails(createWebDetails(auth));
return auth;
}
private WebAuthenticationDetails createWebDetails(Authentication auth) {
MockHttpSession session = new MockHttpSession();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setSession(session);
request.setUserPrincipal(auth);
return new WebAuthenticationDetails(request, false);
}
}