当匿名用户尝试经过身份验证的操作时更改 spring 安全登录重定向

Change spring security login redirect when anonymous user tries authenticated action

默认情况下 spring 当用户未通过身份验证并尝试访问需要角色的 url 时,安全性会将我的用户重定向到 /login。我怎样才能改变这个?我为 accessDenied 页面添加了一个处理程序,但这只会在我的用户已经登录时执行。我如何对匿名用户也做同样的事情? 这是我的 spring 安全配置:

 @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.sessionManagement()
            .and().authorizeRequests()
            //session routes
            .antMatchers("/login", "/register").anonymous()
            .antMatchers(HttpMethod.POST, "/user/verifyAccount/resend").hasRole("NOT_VERIFIED")
            .antMatchers("/user/verifyAccount/resendConfirmation").hasRole("NOT_VERIFIED")
            .antMatchers("/user/verifyAccount").hasRole("USER")
            .antMatchers("/logout").authenticated()

            //profile routes
            .antMatchers("/user/account").hasRole("USER")
            .antMatchers("/user/account/search", "/user/account/update",
                "/user/account/updateCoverImage", "/user/account/updateInfo",
                "/user/account/updateProfileImage").hasRole("VERIFIED")

            //jobs routes
            .antMatchers("/jobs/{id:[\d]+}/contact").hasRole("VERIFIED")
            .antMatchers("/jobs/new").hasRole("PROVIDER")
            .antMatchers(HttpMethod.GET, "/jobs/{id:[\d]+}").permitAll()
            .antMatchers(HttpMethod.POST, "/jobs/{id:[\d]+}").hasRole("VERIFIED")

            //provider routes
            .antMatchers("/user/dashboard", "/user/dashboard/search").hasRole("PROVIDER")
            .antMatchers("/user/join", "/user/join/chooseCity").hasRole("VERIFIED")

            //else
            .antMatchers("/**").permitAll()

            .and().formLogin()
            .loginPage("/login")
            .usernameParameter("email")
            .passwordParameter("password")
            .successHandler(authenticationSuccessHandler())
            .defaultSuccessUrl("/user/account", false)
            .failureUrl("/login?error=true")

            .and().rememberMe()
            .rememberMeParameter("rememberMe")
            .userDetailsService(userDetailService)
            .key(FileCopyUtils.copyToString(new InputStreamReader(authKey.getInputStream())))
            .tokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(30))

            .and().logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login")

            .and().exceptionHandling()
            .accessDeniedHandler(accessDeniedHandler())
            .and().csrf().disable();
    }

这是我的 accessDeniedHandler:

public class CustomAccessDeniedHandler implements AccessDeniedHandler {

    public static final Logger LOGGER = LoggerFactory.getLogger(CustomAccessDeniedHandler.class);

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

        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null) {
            LOGGER.warn("User: " + auth.getName()
                + " attempted to access the protected URL: "
                + request.getRequestURI());
            Collection<SimpleGrantedAuthority> authorities = createAuthorities(Arrays.asList("VERIFIED"));
            if (!auth.getAuthorities().containsAll(authorities)) {
                response.sendRedirect(request.getContextPath() + "/user/account");
                return;
            }
        }

        response.sendRedirect(request.getContextPath() + "/");
    }

    private Collection<SimpleGrantedAuthority> createAuthorities(Collection<String> roles){
        return roles.
            stream()
            .map((role) -> new SimpleGrantedAuthority("ROLE_" + role))
            .collect(Collectors.toList());
    }

}

您正在使用 .loginPage("/login") 指定重定向 url。您可以在那里更改路线。匿名用户应该有权访问您未指定需要具有 .hasRole().

角色的所有其他路由