|
@@ -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,20 +15,6 @@
|
|
|
|
|
|
package org.acegisecurity.ui.switchuser;
|
|
|
|
|
|
-import java.io.IOException;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Arrays;
|
|
|
-import java.util.List;
|
|
|
-
|
|
|
-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.HttpServletResponse;
|
|
|
-
|
|
|
import org.acegisecurity.AccountExpiredException;
|
|
|
import org.acegisecurity.AcegiMessageSource;
|
|
|
import org.acegisecurity.Authentication;
|
|
@@ -38,24 +24,49 @@ 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.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;
|
|
|
+
|
|
|
+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.HttpServletResponse;
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* 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"));
|
|
|
- }
|
|
|
+ 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"));
|
|
|
- }
|
|
|
+ // 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);
|
|
|
|
|
|
- // get the source user details
|
|
|
- UserDetails originalUser = null;
|
|
|
- Object obj = original.getPrincipal();
|
|
|
+ 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 ((obj != null) && obj instanceof UserDetails) {
|
|
|
- originalUser = (UserDetails) obj;
|
|
|
- }
|
|
|
+ // get the source user details
|
|
|
+ UserDetails originalUser = null;
|
|
|
+ Object obj = original.getPrincipal();
|
|
|
|
|
|
- // publish event
|
|
|
- if (this.eventPublisher != null) {
|
|
|
- eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
|
|
|
- current, originalUser));
|
|
|
- }
|
|
|
+ if ((obj != null) && obj instanceof UserDetails) {
|
|
|
+ originalUser = (UserDetails) obj;
|
|
|
+ }
|
|
|
|
|
|
- return original;
|
|
|
+ // publish event
|
|
|
+ if (this.eventPublisher != null) {
|
|
|
+ eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
|
|
|
+ current, originalUser));
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 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 = "";
|
|
|
- }
|
|
|
+ return original;
|
|
|
+ }
|
|
|
|
|
|
- if (logger.isDebugEnabled()) {
|
|
|
- logger.debug("Attempt to switch to user [" + username + "]");
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 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;
|
|
|
|
|
|
- // load the user by name
|
|
|
- UserDetails targetUser = this.userDetailsService
|
|
|
- .loadUserByUsername(username);
|
|
|
+ String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY);
|
|
|
|
|
|
- // user not found
|
|
|
- if (targetUser == null) {
|
|
|
- throw new UsernameNotFoundException(messages.getMessage(
|
|
|
- "SwitchUserProcessingFilter.usernameNotFound",
|
|
|
- new Object[] {username},
|
|
|
- "Username {0} not found"));
|
|
|
- }
|
|
|
+ if (username == null) {
|
|
|
+ username = "";
|
|
|
+ }
|
|
|
|
|
|
- // account is expired
|
|
|
- if (!targetUser.isAccountNonLocked()) {
|
|
|
- throw new LockedException(messages.getMessage(
|
|
|
- "SwitchUserProcessingFilter.locked",
|
|
|
- "User account is locked"));
|
|
|
- }
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.debug("Attempt to switch to user [" + username + "]");
|
|
|
+ }
|
|
|
|
|
|
- // user is disabled
|
|
|
- if (!targetUser.isEnabled()) {
|
|
|
- throw new DisabledException(messages.getMessage(
|
|
|
- "SwitchUserProcessingFilter.disabled",
|
|
|
- "User is disabled"));
|
|
|
- }
|
|
|
+ // load the user by name
|
|
|
+ UserDetails targetUser = this.userDetailsService.loadUserByUsername(username);
|
|
|
|
|
|
- // account is expired
|
|
|
- if (!targetUser.isAccountNonExpired()) {
|
|
|
- throw new AccountExpiredException(messages.getMessage(
|
|
|
- "SwitchUserProcessingFilter.expired",
|
|
|
- "User account has expired"));
|
|
|
- }
|
|
|
+ // user not found
|
|
|
+ if (targetUser == null) {
|
|
|
+ throw new UsernameNotFoundException(messages.getMessage(
|
|
|
+ "SwitchUserProcessingFilter.usernameNotFound",
|
|
|
+ new Object[] {username}, "Username {0} not found"));
|
|
|
+ }
|
|
|
|
|
|
- // credentials expired
|
|
|
- if (!targetUser.isCredentialsNonExpired()) {
|
|
|
- throw new CredentialsExpiredException(messages
|
|
|
- .getMessage(
|
|
|
- "SwitchUserProcessingFilter.credentialsExpired",
|
|
|
- "User credentials have expired"));
|
|
|
- }
|
|
|
+ // account is expired
|
|
|
+ if (!targetUser.isAccountNonLocked()) {
|
|
|
+ throw new LockedException(messages.getMessage(
|
|
|
+ "SwitchUserProcessingFilter.locked",
|
|
|
+ "User account is locked"));
|
|
|
+ }
|
|
|
|
|
|
- // ok, create the switch user token
|
|
|
- targetUserRequest = createSwitchUserToken(request,
|
|
|
- username, targetUser);
|
|
|
+ // user is disabled
|
|
|
+ if (!targetUser.isEnabled()) {
|
|
|
+ throw new DisabledException(messages.getMessage(
|
|
|
+ "SwitchUserProcessingFilter.disabled", "User is disabled"));
|
|
|
+ }
|
|
|
|
|
|
- if (logger.isDebugEnabled()) {
|
|
|
- logger.debug("Switch User Token [" + targetUserRequest + "]");
|
|
|
- }
|
|
|
+ // account is expired
|
|
|
+ if (!targetUser.isAccountNonExpired()) {
|
|
|
+ throw new AccountExpiredException(messages.getMessage(
|
|
|
+ "SwitchUserProcessingFilter.expired",
|
|
|
+ "User account has expired"));
|
|
|
+ }
|
|
|
|
|
|
- // publish event
|
|
|
- if (this.eventPublisher != null) {
|
|
|
- eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
|
|
|
- SecurityContextHolder.getContext().getAuthentication(),
|
|
|
- targetUser));
|
|
|
- }
|
|
|
+ // 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);
|
|
|
|
|
|
- return targetUserRequest;
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.debug("Switch User Token [" + 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;
|
|
|
+ // publish event
|
|
|
+ if (this.eventPublisher != null) {
|
|
|
+ eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
|
|
|
+ SecurityContextHolder.getContext().getAuthentication(),
|
|
|
+ targetUser));
|
|
|
}
|
|
|
|
|
|
- public void destroy() {}
|
|
|
+ return targetUserRequest;
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * @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);
|
|
|
+ /**
|
|
|
+ * 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;
|
|
|
|
|
|
- HttpServletRequest httpRequest = (HttpServletRequest) request;
|
|
|
- HttpServletResponse httpResponse = (HttpServletResponse) response;
|
|
|
+ // 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);
|
|
|
|
|
|
- // check for switch or exit request
|
|
|
- if (requiresSwitchUser(httpRequest)) {
|
|
|
- // if set, attempt switch and store original
|
|
|
- Authentication targetUser = attemptSwitchUser(httpRequest);
|
|
|
+ // get the original authorities
|
|
|
+ List orig = Arrays.asList(targetUser.getAuthorities());
|
|
|
|
|
|
- // update the current context to the new target user
|
|
|
- SecurityContextHolder.getContext()
|
|
|
- .setAuthentication(targetUser);
|
|
|
+ // add the new switch user authority
|
|
|
+ List newAuths = new ArrayList(orig);
|
|
|
+ newAuths.add(switchAuthority);
|
|
|
|
|
|
- // redirect to target url
|
|
|
- httpResponse.sendRedirect(httpResponse
|
|
|
- .encodeRedirectURL(httpRequest
|
|
|
- .getContextPath() + targetUrl));
|
|
|
+ GrantedAuthority[] authorities = {};
|
|
|
+ authorities = (GrantedAuthority[]) newAuths.toArray(authorities);
|
|
|
|
|
|
- return;
|
|
|
- } else if (requiresExitUser(httpRequest)) {
|
|
|
- // get the original authentication object (if exists)
|
|
|
- Authentication originalUser = attemptExitUser(httpRequest);
|
|
|
+ // create the new authentication token
|
|
|
+ targetUserRequest = new UsernamePasswordAuthenticationToken(targetUser,
|
|
|
+ targetUser.getPassword(), authorities);
|
|
|
|
|
|
- // update the current context back to the original user
|
|
|
- SecurityContextHolder.getContext()
|
|
|
- .setAuthentication(originalUser);
|
|
|
+ // set details
|
|
|
+ targetUserRequest.setDetails(authenticationDetailsSource.buildDetails(
|
|
|
+ (HttpServletRequest) request));
|
|
|
|
|
|
- // redirect to target url
|
|
|
- httpResponse.sendRedirect(httpResponse.encodeRedirectURL(
|
|
|
- httpRequest.getContextPath() + targetUrl));
|
|
|
+ return targetUserRequest;
|
|
|
+ }
|
|
|
|
|
|
- return;
|
|
|
- }
|
|
|
+ public void destroy() {}
|
|
|
|
|
|
- chain.doFilter(request, response);
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * @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);
|
|
|
|
|
|
- /**
|
|
|
- * 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 + "]");
|
|
|
- }
|
|
|
- }
|
|
|
+ HttpServletRequest httpRequest = (HttpServletRequest) request;
|
|
|
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
|
|
|
|
|
|
- return original;
|
|
|
- }
|
|
|
+ // check for switch or exit request
|
|
|
+ if (requiresSwitchUser(httpRequest)) {
|
|
|
+ // if set, attempt switch and store original
|
|
|
+ Authentication targetUser = attemptSwitchUser(httpRequest);
|
|
|
|
|
|
- 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);
|
|
|
- }
|
|
|
+ // update the current context to the new target user
|
|
|
+ SecurityContextHolder.getContext().setAuthentication(targetUser);
|
|
|
|
|
|
- /**
|
|
|
- * 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);
|
|
|
- }
|
|
|
+ // redirect to target url
|
|
|
+ httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest
|
|
|
+ .getContextPath() + targetUrl));
|
|
|
|
|
|
- public void setApplicationEventPublisher(
|
|
|
- ApplicationEventPublisher eventPublisher)
|
|
|
- throws BeansException {
|
|
|
- this.eventPublisher = eventPublisher;
|
|
|
- }
|
|
|
+ return;
|
|
|
+ } else if (requiresExitUser(httpRequest)) {
|
|
|
+ // get the original authentication object (if exists)
|
|
|
+ Authentication originalUser = attemptExitUser(httpRequest);
|
|
|
|
|
|
- /**
|
|
|
- * Sets the authentication data access object.
|
|
|
- *
|
|
|
- * @param authenticationDao The authentication dao
|
|
|
- */
|
|
|
- public void setUserDetailsService(
|
|
|
- UserDetailsService authenticationDao) {
|
|
|
- this.userDetailsService = authenticationDao;
|
|
|
- }
|
|
|
+ // update the current context back to the original user
|
|
|
+ SecurityContextHolder.getContext().setAuthentication(originalUser);
|
|
|
|
|
|
- /**
|
|
|
- * Set the URL to respond to exit user processing.
|
|
|
- *
|
|
|
- * @param exitUserUrl The exit user URL.
|
|
|
- */
|
|
|
- public void setExitUserUrl(
|
|
|
- String exitUserUrl) {
|
|
|
- this.exitUserUrl = exitUserUrl;
|
|
|
- }
|
|
|
+ // redirect to target url
|
|
|
+ httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest
|
|
|
+ .getContextPath() + targetUrl));
|
|
|
|
|
|
- public void setMessageSource(
|
|
|
- MessageSource messageSource) {
|
|
|
- this.messages = new MessageSourceAccessor(messageSource);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Set the URL to respond to switch user processing.
|
|
|
- *
|
|
|
- * @param switchUserUrl The switch user URL.
|
|
|
- */
|
|
|
- public void setSwitchUserUrl(String switchUserUrl) {
|
|
|
- this.switchUserUrl = switchUserUrl;
|
|
|
- }
|
|
|
+ chain.doFilter(request, response);
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * 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;
|
|
|
+ /**
|
|
|
+ * 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 + "]");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 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 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setAuthenticationDetailsSource(
|
|
|
+ AuthenticationDetailsSource authenticationDetailsSource) {
|
|
|
+ Assert.notNull(authenticationDetailsSource,
|
|
|
+ "AuthenticationDetailsSource required");
|
|
|
+ this.authenticationDetailsSource = authenticationDetailsSource;
|
|
|
+ }
|
|
|
|
|
|
- return uri;
|
|
|
+ /**
|
|
|
+ * 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);
|
|
|
}
|
|
|
+
|
|
|
+ return uri;
|
|
|
+ }
|
|
|
}
|