Многочисленные успешные и неудачные обработчики Spring Security не работают - PullRequest
0 голосов
/ 16 марта 2020

У меня есть конфигурация безопасности, которая реализует несколько входов в систему, и для каждого процесса входа есть обработчики успеха и ошибок.

Это моя конфигурация безопасности:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @NoArgsConstructor
    @Configuration
    @Order(1)
    public static class AdminConfigurationAdapter extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .antMatcher("/admin/**")
                    .authorizeRequests().anyRequest().hasRole("ADMIN")
                    .and().formLogin().loginPage("/admin/login").failureHandler(adminFailureHandler()).defaultSuccessUrl("/admin").permitAll()
                    .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/").invalidateHttpSession(true)
                    .and().csrf().disable();
                    /*.exceptionHandling()
                    .defaultAuthenticationEntryPointFor(adminAuthenticationEntryPoint(), new AntPathRequestMatcher("/admin/**"));*/
        }

        /*@Bean
        public AuthenticationEntryPoint adminAuthenticationEntryPoint() {
            return new LoginUrlAuthenticationEntryPoint("/admin/login");
        }*/

        @Bean
        public AuthenticationFailureHandler adminFailureHandler() {
            return new CustomLoginFailureHandler("/admin/login?error=true");
        }
    }

    @AllArgsConstructor
    @Configuration
    public static class NormalConfigurationAdapter extends WebSecurityConfigurerAdapter {
        private UsersServiceImpl usersService;

        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }

        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(usersService).passwordEncoder(passwordEncoder());
        }

        @Override
        public void configure(WebSecurity web) {
            web.ignoring().antMatchers(
                    "/css/**",
                    "/js/**",
                    "/img/**",
                    "/font/**",
                    "/html/**",
                    "/jusoPopup",
                    "favicon.ico"
            );
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .antMatchers("/Ticketing/**", "**/write").hasRole("MEMBER")
                    .anyRequest().permitAll()
                    .and().formLogin().loginPage("/login").failureHandler(failureHandler()).successHandler(successHandler()).permitAll()
                    .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/").invalidateHttpSession(true)
                    .and().csrf().disable();
                    /*.exceptionHandling()
                    .defaultAuthenticationEntryPointFor(authenticationEntryPoint(), new AntPathRequestMatcher("/login"));*/
        }

        /*@Bean
        public AuthenticationEntryPoint authenticationEntryPoint() {
            return new LoginUrlAuthenticationEntryPoint("/login");
        }*/

        @Bean
        public AuthenticationSuccessHandler successHandler() {
            return new CustomLoginSuccessHandler("/");
        }

        @Bean
        public AuthenticationFailureHandler failureHandler() {
            return new CustomLoginFailureHandler("/login?error=true");
        }
    }

}

class CustomLoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
    public CustomLoginSuccessHandler(String defaultTargetUrl) {
        setDefaultTargetUrl(defaultTargetUrl);
    }

    @Override
    public void onAuthenticationSuccess(
            HttpServletRequest request,
            HttpServletResponse response,
            Authentication authentication
    ) throws ServletException, IOException {
        HttpSession session = request.getSession();
        if (session != null) {
            String redirectUrl = (String) session.getAttribute("prevPage");
            if (redirectUrl != null) {
                session.removeAttribute("prevPage");
                getRedirectStrategy().sendRedirect(request, response, redirectUrl);
            } else {
                super.onAuthenticationSuccess(request, response, authentication);
            }
        } else {
            super.onAuthenticationSuccess(request, response, authentication);
        }
    }
}

class CustomLoginFailureHandler implements AuthenticationFailureHandler {
    private String defaultFailureUrl;
    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    public CustomLoginFailureHandler(String defaultFailureUrl){
        this.defaultFailureUrl = defaultFailureUrl;
    }

    @Override
    public void onAuthenticationFailure(
            HttpServletRequest request,
            HttpServletResponse response,
            AuthenticationException exception
    ) throws IOException, ServletException {
        String errorMessage = "Some error message";
        request.setAttribute("errorMessage", errorMessage);
        request.getRequestDispatcher(defaultFailureUrl).forward(request, response);
    }
}

Как вы можете видеть обработчики, объявленные как bean-компоненты в каждой конфигурации, так что я ожидал, что они должны работать в своей конфигурации. но обработчик в AdminConfigurationAdapter не работает, работают только обработчики NormalConfigurationAdapter независимо от того, какой URL я запрашиваю.

Если я получаю доступ к /admin/**, тогда загружается правильная форма входа в систему, но запускается обработчик успеха в NormalConfigurationAdapter, который не должен t быть запущенным.

Согласно официальному документу должна работать только одна конфигурация, если я реализую несколько конфигураций, но почему обработчики успеха и сбоев в другой конфигурации сработали ??

Я пытался реализовать точку входа множественной аутентификации как кто-то сказал, но это не похоже на работу.

1 Ответ

0 голосов
/ 16 марта 2020

Лучшей практикой было бы иметь только одну конфигурацию безопасности, иначе было бы намного сложнее понять базовые правила:

Ваша проблема заключается в том, что у вас есть: .anyRequest().permitAll(), которая вызовет ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...