mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-08 19:42:48 +00:00
Additional changes related to SEC-192 (avoiding session creation when creating WebAuthenticationDetails). Also fixed Jalopy chaos in SwitchUserProcessingFilter.
This commit is contained in:
parent
52a212e609
commit
6abceb7ab0
@ -102,9 +102,10 @@ public class CasProcessingFilter extends AbstractProcessingFilter {
|
|||||||
password = "";
|
password = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username,
|
UsernamePasswordAuthenticationToken authRequest =
|
||||||
password);
|
new UsernamePasswordAuthenticationToken(username, password);
|
||||||
authRequest.setDetails(new WebAuthenticationDetails(request));
|
|
||||||
|
authRequest.setDetails(new WebAuthenticationDetails(request, false));
|
||||||
|
|
||||||
return this.getAuthenticationManager().authenticate(authRequest);
|
return this.getAuthenticationManager().authenticate(authRequest);
|
||||||
}
|
}
|
||||||
|
@ -369,9 +369,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean,
|
|||||||
+ "' with response: '" + responseDigest + "'");
|
+ "' with response: '" + responseDigest + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(user,
|
UsernamePasswordAuthenticationToken authRequest =
|
||||||
user.getPassword());
|
new UsernamePasswordAuthenticationToken(user, user.getPassword());
|
||||||
authRequest.setDetails(new WebAuthenticationDetails(httpRequest));
|
|
||||||
|
authRequest.setDetails(new WebAuthenticationDetails(httpRequest, false));
|
||||||
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(authRequest);
|
SecurityContextHolder.getContext().setAuthentication(authRequest);
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,10 @@ import org.springframework.util.Assert;
|
|||||||
* </pre>
|
* </pre>
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* @author Mark St.Godard
|
||||||
|
* @version $Id$
|
||||||
|
*
|
||||||
* @see org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority
|
* @see org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority
|
||||||
*/
|
*/
|
||||||
public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
||||||
@ -156,10 +160,10 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
|||||||
Authentication current = SecurityContextHolder.getContext()
|
Authentication current = SecurityContextHolder.getContext()
|
||||||
.getAuthentication();
|
.getAuthentication();
|
||||||
|
|
||||||
if (null == current) {
|
if (null == current) {
|
||||||
throw new AuthenticationCredentialsNotFoundException(messages
|
throw new AuthenticationCredentialsNotFoundException(messages
|
||||||
.getMessage("SwitchUserProcessingFilter.noCurrentUser",
|
.getMessage("SwitchUserProcessingFilter.noCurrentUser",
|
||||||
"No current user associated with this request"));
|
"No current user associated with this request"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if the current user did actual switch to another user
|
// check to see if the current user did actual switch to another user
|
||||||
@ -173,381 +177,352 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
|||||||
.getMessage(
|
.getMessage(
|
||||||
"SwitchUserProcessingFilter.noOriginalAuthentication",
|
"SwitchUserProcessingFilter.noOriginalAuthentication",
|
||||||
"Could not find original Authentication object"));
|
"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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// get the source user details
|
||||||
* Attempt to switch to another user. If the user does not exist or
|
UserDetails originalUser = null;
|
||||||
* is not active, return null.
|
Object obj = original.getPrincipal();
|
||||||
*
|
|
||||||
* @param request The http request
|
if ((obj != null) && obj instanceof UserDetails) {
|
||||||
*
|
originalUser = (UserDetails) obj;
|
||||||
* @return The new <code>Authentication</code> request if
|
}
|
||||||
* successfully switched to another user,
|
|
||||||
* <code>null</code> otherwise.
|
// publish event
|
||||||
*
|
if (this.eventPublisher != null) {
|
||||||
* @throws AuthenticationException
|
eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
|
||||||
* @throws UsernameNotFoundException If the target user is not
|
current, originalUser));
|
||||||
* found.
|
}
|
||||||
* @throws LockedException DOCUMENT ME!
|
|
||||||
* @throws DisabledException If the target user is disabled.
|
return original;
|
||||||
* @throws AccountExpiredException If the target user account is
|
}
|
||||||
* expired.
|
|
||||||
* @throws CredentialsExpiredException If the target user
|
/**
|
||||||
* credentials are expired.
|
* Attempt to switch to another user. If the user does not exist or
|
||||||
*/
|
* is not active, return null.
|
||||||
protected Authentication attemptSwitchUser(
|
*
|
||||||
|
* @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 {
|
HttpServletRequest request) throws AuthenticationException {
|
||||||
UsernamePasswordAuthenticationToken targetUserRequest = null;
|
UsernamePasswordAuthenticationToken targetUserRequest = null;
|
||||||
|
|
||||||
String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY);
|
String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY);
|
||||||
|
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
username = "";
|
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(new WebAuthenticationDetails(
|
||||||
|
request, false));
|
||||||
|
|
||||||
|
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()) {
|
return original;
|
||||||
logger.debug("Attempt to switch to user [" + username + "]");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// load the user by name
|
public void init(FilterConfig ignored)
|
||||||
UserDetails targetUser = this.userDetailsService
|
throws ServletException {}
|
||||||
.loadUserByUsername(username);
|
|
||||||
|
|
||||||
// user not found
|
/**
|
||||||
if (targetUser == null) {
|
* Checks the request URI for the presence
|
||||||
throw new UsernameNotFoundException(messages.getMessage(
|
* of <tt>exitUserUrl</tt>.
|
||||||
"SwitchUserProcessingFilter.usernameNotFound",
|
*
|
||||||
new Object[] {username},
|
* @param request The http servlet request
|
||||||
"Username {0} not found"));
|
*
|
||||||
}
|
* @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);
|
||||||
|
|
||||||
// account is expired
|
return uri.endsWith(request
|
||||||
if (!targetUser.isAccountNonLocked()) {
|
.getContextPath() + exitUserUrl);
|
||||||
throw new LockedException(messages.getMessage(
|
}
|
||||||
"SwitchUserProcessingFilter.locked",
|
|
||||||
"User account is locked"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// user is disabled
|
/**
|
||||||
if (!targetUser.isEnabled()) {
|
* Checks the request URI for the presence of <tt>switchUserUrl</tt>.
|
||||||
throw new DisabledException(messages.getMessage(
|
*
|
||||||
"SwitchUserProcessingFilter.disabled",
|
* @param request The http servlet request
|
||||||
"User is disabled"));
|
*
|
||||||
}
|
* @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);
|
||||||
|
|
||||||
// account is expired
|
return uri.endsWith(request.getContextPath() + switchUserUrl);
|
||||||
if (!targetUser.isAccountNonExpired()) {
|
}
|
||||||
throw new AccountExpiredException(messages.getMessage(
|
|
||||||
"SwitchUserProcessingFilter.expired",
|
|
||||||
"User account has expired"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// credentials expired
|
public void setApplicationEventPublisher(
|
||||||
if (!targetUser.isCredentialsNonExpired()) {
|
ApplicationEventPublisher eventPublisher)
|
||||||
throw new CredentialsExpiredException(messages
|
throws BeansException {
|
||||||
.getMessage(
|
this.eventPublisher = eventPublisher;
|
||||||
"SwitchUserProcessingFilter.credentialsExpired",
|
}
|
||||||
"User credentials have expired"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ok, create the switch user token
|
/**
|
||||||
targetUserRequest = createSwitchUserToken(request,
|
* Sets the authentication data access object.
|
||||||
username, targetUser);
|
*
|
||||||
|
* @param authenticationDao The authentication dao
|
||||||
|
*/
|
||||||
|
public void setUserDetailsService(
|
||||||
|
UserDetailsService authenticationDao) {
|
||||||
|
this.userDetailsService = authenticationDao;
|
||||||
|
}
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
/**
|
||||||
logger.debug("Switch User Token ["
|
* Set the URL to respond to exit user processing.
|
||||||
+ targetUserRequest + "]");
|
*
|
||||||
}
|
* @param exitUserUrl The exit user URL.
|
||||||
|
*/
|
||||||
|
public void setExitUserUrl(
|
||||||
|
String exitUserUrl) {
|
||||||
|
this.exitUserUrl = exitUserUrl;
|
||||||
|
}
|
||||||
|
|
||||||
// publish event
|
public void setMessageSource(
|
||||||
if (this.eventPublisher != null) {
|
MessageSource messageSource) {
|
||||||
eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
SecurityContextHolder.getContext()
|
}
|
||||||
.getAuthentication(),
|
|
||||||
targetUser));
|
|
||||||
}
|
|
||||||
|
|
||||||
return targetUserRequest;
|
/**
|
||||||
}
|
* Set the URL to respond to switch user processing.
|
||||||
|
*
|
||||||
|
* @param switchUserUrl The switch user URL.
|
||||||
|
*/
|
||||||
|
public void setSwitchUserUrl(String switchUserUrl) {
|
||||||
|
this.switchUserUrl = switchUserUrl;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a switch user token that contains an additional
|
* Sets the URL to go to after a successful switch / exit user
|
||||||
* <tt>GrantedAuthority</tt> that contains the original
|
* request.
|
||||||
* <code>Authentication</code> object.
|
*
|
||||||
*
|
* @param targetUrl The target url.
|
||||||
* @param request The http servlet request.
|
*/
|
||||||
* @param username The username of target user
|
public void setTargetUrl(
|
||||||
* @param targetUser The target user
|
String targetUrl) {
|
||||||
*
|
this.targetUrl = targetUrl;
|
||||||
* @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.
|
* Strips any content after the ';' in the request URI
|
||||||
Authentication currentAuth = SecurityContextHolder.getContext()
|
*
|
||||||
.getAuthentication();
|
* @param request The http request
|
||||||
GrantedAuthority switchAuthority = new SwitchUserGrantedAuthority(ROLE_PREVIOUS_ADMINISTRATOR,
|
*
|
||||||
currentAuth);
|
* @return The stripped uri
|
||||||
|
*/
|
||||||
|
private static String stripUri(HttpServletRequest request) {
|
||||||
|
String uri = request.getRequestURI();
|
||||||
|
int idx = uri.indexOf(';');
|
||||||
|
|
||||||
// get the original authorities
|
if (idx > 0) {
|
||||||
List orig = Arrays.asList(targetUser.getAuthorities());
|
uri = uri.substring(0,
|
||||||
|
idx);
|
||||||
|
}
|
||||||
|
|
||||||
// add the new switch user authority
|
return uri;
|
||||||
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(new WebAuthenticationDetails(
|
|
||||||
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 + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -103,7 +103,7 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter {
|
|||||||
*/
|
*/
|
||||||
protected void setDetails(HttpServletRequest request,
|
protected void setDetails(HttpServletRequest request,
|
||||||
UsernamePasswordAuthenticationToken authRequest) {
|
UsernamePasswordAuthenticationToken authRequest) {
|
||||||
authRequest.setDetails(new WebAuthenticationDetails(request));
|
authRequest.setDetails(new WebAuthenticationDetails(request, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -240,7 +240,7 @@ public class SiteminderAuthenticationProcessingFilter
|
|||||||
*/
|
*/
|
||||||
protected void setDetails(HttpServletRequest request,
|
protected void setDetails(HttpServletRequest request,
|
||||||
UsernamePasswordAuthenticationToken authRequest) {
|
UsernamePasswordAuthenticationToken authRequest) {
|
||||||
authRequest.setDetails(new WebAuthenticationDetails(request));
|
authRequest.setDetails(new WebAuthenticationDetails(request, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,6 +118,6 @@ public class ConcurrentSessionControllerImplTests extends TestCase {
|
|||||||
request.setSession(session);
|
request.setSession(session);
|
||||||
request.setUserPrincipal(auth);
|
request.setUserPrincipal(auth);
|
||||||
|
|
||||||
return new WebAuthenticationDetails(request);
|
return new WebAuthenticationDetails(request, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user