Spring Security中自定义的HTTP 403页面无法工作

4

我想替换默认的访问被拒绝页面:

HTTP 403

使用我的自定义页面和我的方法是这样的:

@Configuration
@EnableWebSecurity
public class SecurityContextConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
private UserDetailsService userDetailsService;

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/resources/**");
}

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.sessionManagement().maximumSessions(1)
            .sessionRegistry(sessionRegistry()).expiredUrl("/");
    http.authorizeRequests().antMatchers("/").permitAll()
            .antMatchers("/register").permitAll()
            .antMatchers("/security/checkpoint/for/admin/**").hasRole("ADMIN")
            .antMatchers("/rest/users/**").hasRole("ADMIN").anyRequest()
            .authenticated().and().formLogin().loginPage("/")
            .defaultSuccessUrl("/welcome").permitAll().and().logout()
            .logoutUrl("/logout");
}

@Bean
public SessionRegistry sessionRegistry() {
    return new SessionRegistryImpl();
}

@Bean
public AuthenticationProvider daoAuthenticationProvider() {
    DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
    daoAuthenticationProvider.setUserDetailsService(userDetailsService);

    return daoAuthenticationProvider;

}

@Bean
public ProviderManager providerManager() {

    List<AuthenticationProvider> arg0 = new CopyOnWriteArrayList<AuthenticationProvider>();
    arg0.add(daoAuthenticationProvider());

    return  new ProviderManager(arg0);

}

@Bean(name = "myAuthenticationManagerBean")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

@Override
protected AuthenticationManager authenticationManager() throws Exception {
    return providerManager();
}

    @Bean
    public ExceptionTranslationFilter exceptionTranslationFilter() {
        ExceptionTranslationFilter exceptionTranslationFilter = 
                new ExceptionTranslationFilter(new CustomAuthenticationEntryPoint());
        exceptionTranslationFilter.setAccessDeniedHandler(accessDeniedHandler());

        return exceptionTranslationFilter;
    }
    @Bean
    public AccessDeniedHandlerImpl accessDeniedHandler() {
        AccessDeniedHandlerImpl accessDeniedHandlerImpl = new 
                AccessDeniedHandlerImpl();
        accessDeniedHandlerImpl.setErrorPage("/page_403.jsp");
        System.out.println("ACCESS DENIED IS CALLED......");
        return accessDeniedHandlerImpl;
    }

    private class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint{

        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response,
                AuthenticationException authenticationException) throws IOException,
                ServletException {

            response.sendError(HttpServletResponse.SC_FORBIDDEN,
                    "Access denied.");
        }

    }   

}

但是使用上述配置后,我仍然无法完成工作并看到相同的问题。

HTTP 403

这个目的是否还需要注入更多的Bean?


1
这更清楚地表明您除了几个bean之外什么都没有配置。仅添加bean是不够的,而且您让它变得过于复杂,可以更轻松地完成(请参阅答案和参考指南)。 - M. Deinum
2个回答

4

免责声明:这不仅仅是一个解决方案,而是一个可行的方案。

在这种情况下,我的方法尽可能简单,只需要在您的SecurityContext中添加此方法即可。

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.sessionManagement().maximumSessions(1)
            .sessionRegistry(sessionRegistry()).expiredUrl("/");
    http.authorizeRequests().antMatchers("/").permitAll()
            .antMatchers("/register").permitAll()
            .antMatchers("/security/checkpoint/for/admin/**").hasRole("ADMIN")
            .antMatchers("/rest/users/**").hasRole("ADMIN").anyRequest()
            .authenticated().and().formLogin().loginPage("/")
            .defaultSuccessUrl("/welcome").permitAll().and().logout()
            .logoutUrl("/logout").and()
            .exceptionHandling().accessDeniedPage("/page_403");//this is what you have to do here to get job done.
}

参考: 在Spring Security中自定义HTTP 403访问被拒绝页面.


1
正如@M. Deinum指出的那样,您应该告诉Spring Security如何整合这些bean。无论如何,对于您想要实现的内容,有一种更简单的方法:
@Configuration
@EnableWebSecurity
public class SecurityContextConfigurer extends WebSecurityConfigurerAdapter {
    // Rest omitted

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                // The usual stuff
                .exceptionHandling()
                    .accessDeniedPage("/page_403.jsp")
                    .authenticationEntryPoint((request, response, authException) -> {
                        response.sendError(HttpServletResponse.SC_FORBIDDEN);
                    });
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接