|
@@ -104,6 +104,10 @@ import org.springframework.util.Assert;
|
|
|
* </pre>
|
|
|
* </p>
|
|
|
*
|
|
|
+ *
|
|
|
+ * @author Mark St.Godard
|
|
|
+ * @version $Id$
|
|
|
+ *
|
|
|
* @see org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority
|
|
|
*/
|
|
|
public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
|
@@ -156,10 +160,10 @@ 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
|
|
@@ -173,381 +177,352 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
|
|
.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;
|
|
|
- }
|
|
|
+ // 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(
|
|
|
+ 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;
|
|
|
+ UsernamePasswordAuthenticationToken targetUserRequest = null;
|
|
|
|
|
|
- String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY);
|
|
|
+ String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY);
|
|
|
|
|
|
- if (username == null) {
|
|
|
- username = "";
|
|
|
- }
|
|
|
+ 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"));
|
|
|
+ }
|
|
|
|
|
|
- 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"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 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 + "]");
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ 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);
|
|
|
+ }
|
|
|
|
|
|
- // 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));
|
|
|
-
|
|
|
- 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;
|
|
|
- }
|
|
|
- }
|
|
|
+ return uri;
|
|
|
+ }
|
|
|
+}
|