使用的版本是Springsecurity的4.2.x版本。
业务场景是这样的,系统中存在很多用户,超级管理员要有个功能,就是可以切换用户,比如超级管理员,可以切换为系统中的任何一个用户。Spingsecurity提供了一个SwitchUserFilter,我们就用这个来实现功能。
List-1.1
<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。
List-1.2
<security:http >
...
<security:custom-filter ref="switchUserFilter" after="FILTER_SECURITY_INTERCEPTOR"/>
...
</security:http>
图2.1
如2.1所示,SwitchUserFilter继承了GenericFilterBean,它是Springframework中的类。SwitchUserFilter的doFilte方法如下List-2.1所示
List-2.1
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;
}
...
(adsbygoogle = window.adsbygoogle || []).push({});