使用的版本是Springsecurity的4.2.x版本。java
業務場景是這樣的,系統中存在不少用戶,超級管理員要有個功能,就是能夠切換用戶,好比超級管理員,能夠切換爲系統中的任何一個用戶。Spingsecurity提供了一個SwitchUserFilter,咱們就用這個來實現功能。web
List-1.1spring
<bean id="switchUserFilter" class="org.springframework.security.web.authentication.switchuser.SwitchUserFilter"> <property name="userDetailsService" ref="userService"/> <property name="usernameParameter" value="userNo"/> <property name="switchUserUrl" value="/switch/user"/> </bean>
List-1.1以後,將SwitchUserFilter放在FILTER_SECURITY_INTERCEPTOR以後,爲何呢?由於accessDecisionManager在FILTER_SECURITY_INTERCEPTOR中,即判斷是否有訪問資源的權限是在FILTER_SECURITY_INTERCEPTOR中,判斷過權限以後纔到SwitchUserFilter。ui
List-1.2this
<security:http > ... <security:custom-filter ref="switchUserFilter" after="FILTER_SECURITY_INTERCEPTOR"/> ... </security:http>
圖2.1url
如2.1所示,SwitchUserFilter繼承了GenericFilterBean,它是Springframework中的類。SwitchUserFilter的doFilte方法以下List-2.1所示spa
List-2.1debug
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; // check for switch or exit request if (requiresSwitchUser(request)) { // if set, attempt switch and store original try { Authentication targetUser = attemptSwitchUser(request); // update the current context to the new target user SecurityContextHolder.getContext().setAuthentication(targetUser); // redirect to target url this.successHandler.onAuthenticationSuccess(request, response, targetUser); } catch (AuthenticationException e) { this.logger.debug("Switch User failed", e); this.failureHandler.onAuthenticationFailure(request, response, e); } return; } ...