AccessDeniedHandler 重定向到登录页面

oli*_*mir 3 spring spring-mvc spring-security

当(在 Spring Security / MVC 中)对页面的访问被拒绝时,由于用户没有足够的权限(尽管他已通过身份验证),我需要通过显示登录页面(而不是标准行为)提供以另一个用户身份登录显示 403 访问被拒绝页面)。
我可以编写一个AccessDeniedHandler, 重定向到登录页面。但是,当 Spring Security 发现已经有另一个用户登录时,它会如何反应?当新用户成功通过身份验证后,我可以以某种方式注销旧用户吗?

oli*_*mir 5

当已经有另一个用户登录时,我尝试登录新用户。它可以工作 - 无需注销第一个用户。他的授权被新的授权所取代。这是我自己的问题的简单答案。

如果有人感兴趣,如何在访问被拒绝的情况下转发到登录页面 - 这是我的解决方案:

首先定义一个自定义的RequestCache:

@Component("myRequestCache")
public class MyRequestCache extends HttpSessionRequestCache {
    public MyRequestCache() {
        super();
    }
}
Run Code Online (Sandbox Code Playgroud)

其次定义一个自定义的AccessDeniedHandler:

@Component("myAccessDeniedHandler")
public class MyAccessDeniedHandler implements AccessDeniedHandler {

    @Autowired
    @Qualifier("myRequestCache")
    private RequestCache myRequestCache;

    public MyAccessDeniedHandler() {
    }

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exc)
        throws IOException, ServletException {
        
        if (!response.isCommitted()) {

            //Save Target-Request
            myRequestCache.saveRequest(request, response);
        
            //Forward to the login page
            request.getRequestDispatcher("/loginPage").forward(request, response);
        }
    }   
}
Run Code Online (Sandbox Code Playgroud)

第三步将这两个配置到 Spring Security 中:

@Configuration
@EnableWebSecurity
public class myConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("myRequestCache")
    RequestCache myRequestCache;

    @Autowired
    @Qualifier("myAccessDeniedHandler")
    AccessDeniedHandler myAccessDeniedHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
        http
        .requestCache()
            .requestCache(myRequestCache)
            .and()
        .exceptionHandling()
            .accessDeniedHandler(myAccessDeniedHandler)
    }
}
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?在登录页面的情况下转发
。由于此转发是由这个自编程类调用的,而不是由过滤器链中的 Spring 调用的,因此我们必须告诉 spring,目标请求是什么 - 在成功身份验证后它必须重定向到哪里。我们通过.MyAccessDeniedHandlerAccessDeniedExceptionRequestCache