Процесс многократного входа в систему Spring Spring не работает, как должен - PullRequest
0 голосов
/ 10 марта 2020

Я страдаю за обработку нескольких входов.

Я много об этом искал, и ни один из ответов там не работает.

Я написал две обработки входа: одну для администратора, а другую для обычного пользователя.

И также написал каждый обработчик успеха и неудачи, но обработчики всегда работают с последним в конфигурации @order(2), хотя я запрашиваю /admin.

Мои проблемы:

  1. Я могу войти, но обработчик успеха всегда запускается как последний в @order(2).

  2. Обработчик ошибки запускается, но также и как последний, независимо от того, что URL, который я запрашиваю, и он выдает ошибку 404 (я вижу, что он идет на правильном контроллере во время отладки). Может быть, плитки не работают при сбое?

Вот мой конфиг безопасности:

@Configuration
@EnableWebSecurity
@AllArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private UsersServiceImpl usersService;

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

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

    @Configuration
    @Order(1)
    @NoArgsConstructor
    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")
                    .defaultSuccessUrl("/admin")
                    .failureHandler(adminFailureHandler())
                    .permitAll()
                    .and()
                .logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/")
                    .invalidateHttpSession(true)
                    .and()
                .csrf().disable();
        }

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

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

    @Configuration
    @Order(2)
    @NoArgsConstructor
    public static class NormalConfigurationAdapter extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .antMatchers("/Ticketing/**", "/**/write").hasRole("MEMBER")
                    .anyRequest().permitAll()
                    .and()
                .formLogin()
                    .loginPage("/login")
                    .successHandler(successHandler())
                    .failureHandler(failureHandler())
                    .permitAll()
                    .and()
                .logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/")
                    .invalidateHttpSession(true)
                    .and()
                .headers()
                    .frameOptions().sameOrigin()
                    .and()
                .csrf().disable();
        }

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

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

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

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);
        }
    }
}

@Getter
@Setter
@AllArgsConstructor
class CustomLoginFailureHandler implements AuthenticationFailureHandler {
    private String 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);
    }
}

Трудно найти работающий ресурс для обработки нескольких входов. если вы, ребята, знаете хороший ресурс об этом, пожалуйста, дайте мне знать.

Я надеюсь, что это ошибка моего кода, чтобы мне не пришлось менять структуру приложения.

Я прочитал какое-то руководство по Baeldung и весенние документы по безопасности Вот моя отредактированная конфигурация:

@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")
                    .defaultSuccessUrl("/admin")
                    .failureHandler(adminFailureHandler())
                    .permitAll()
                    .and()
                    .logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/")
                    .invalidateHttpSession(true)
                    .and()
                    .csrf().disable();
        }

        @Bean
        public AuthenticationEntryPoint authenticationEntryPoint(){
            BasicAuthenticationEntryPoint entryPoint =
                    new BasicAuthenticationEntryPoint();
            entryPoint.setRealmName("admin realm");
            return entryPoint;
        }

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

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

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

        @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")
                    .successHandler(successHandler())
                    .failureHandler(failureHandler())
                    .permitAll()
                    .and()
                    .logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/")
                    .invalidateHttpSession(true)
                    .and()
                    .headers().frameOptions().sameOrigin()
                    .and()
                    .csrf().disable();
        }

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

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

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

}

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);
        }
    }
}

@Getter
@Setter
@AllArgsConstructor
class CustomLoginFailureHandler implements AuthenticationFailureHandler {
    private String defaultFailureUrl;

    @Override
    public void onAuthenticationFailure(
            HttpServletRequest request,
            HttpServletResponse response,
            AuthenticationException exception
    ) throws IOException, ServletException {
        String errorMessage = "Error";

        request.setAttribute("errorMessage", errorMessage);

        request.getRequestDispatcher(defaultFailureUrl).forward(request, response);
    }
}

Это выглядит более организованно, чем раньше, я думаю, но все еще имеет ту же проблему ... также читайте о AuthenticationEntryPoint, но не уверен, что это подходит в моем случае

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