Проблема с отображением пользовательских ошибок входа в систему Spring - PullRequest
0 голосов
/ 02 октября 2018

Контекст Этот пример взят из учебника «Предотвращение попыток проверки подлинности с помощью грубой силы» в Spring Security, но у меня возникла проблема, поскольку я не вижу сообщений об ошибках.Проблема заключается в CustomAuthenticationFailureHandler, который перезаписывает failHandler.Я буду благодарен за вашу помощь.

SecurityConfiguration

@Configuration
@EnableWebSecurity 
public class MyWebSecurity extends WebSecurityConfigurerAdapter {

private MyUserDetailsService myUserDetailsService;
@Autowired
private AuthenticationFailureHandler authenticationFailureHandler;

public MyWebSecurity(MyUserDetailsService myUserDetailsService) {
    this.myUserDetailsService = myUserDetailsService;
}


@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(myUserDetailsService).passwordEncoder(bCryptPasswordEncoder());
}

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

@Bean
public static ServletListenerRegistrationBean httpSessionEventPublisher() {
    return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
}

private static final String[] PUBLIC_MATCHERS = { "/css/**", "/js/**", "/fonts/**", "/img`enter code here`/**", "/vendor/**","/pdf/**",
        "/webjars/**", "/rest/**","/user/rememberPassword**","/user/createNewPassword**","/user/accountActivation**","/user/registrationConfirm**"};

@Override
public void configure(WebSecurity web) throws Exception {
  web.ignoring().antMatchers(PUBLIC_MATCHERS);
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    /*http
    .authorizeRequests()
    .anyRequest().permitAll();}*/

    http
     .authorizeRequests()
        .antMatchers("/user/create").hasAnyRole("SUPER")
        .antMatchers("/user/**").hasAnyRole("ADMIN","SUPER")
        .antMatchers("publications/**").hasAnyRole("ADMIN","SUPER")
        .anyRequest().authenticated()
        .and()
        .formLogin()
            .loginPage("/login").permitAll()
            .loginProcessingUrl("/app-login")
            .usernameParameter("username") 
            .passwordParameter("password")
            .defaultSuccessUrl("/home", true) 
            .failureUrl("/login?error=true")
             .failureHandler(authenticationFailureHandler)
            .and()
            .logout()
            .logoutUrl("/app-logout")
                .clearAuthentication(true)
                .logoutSuccessUrl("/login")
                .permitAll().
                and().exceptionHandling() 
             .accessDeniedHandler(accessDeniedHandler())
             .and().httpBasic();
    http
      .sessionManagement()
      .invalidSessionUrl("/login")
      .maximumSessions(1).sessionRegistry(sessionRegistry()).expiredUrl("/login");  
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
    return new BCryptPasswordEncoder();
}

@Bean
public AccessDeniedHandler accessDeniedHandler() {
    return new AccessDeniedHandler() {
        @Override
        public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                AccessDeniedException e) throws IOException, ServletException {
            httpServletResponse.sendRedirect("/cites5/accessDenied");

        }
    };
}

}

Класс AuthenticationFailureHandler:

@Component("authenticationFailureHandler")
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    @Autowired
    private MessageSource messages;

    @Autowired
    private LocaleResolver localeResolver;

    @Override
    public void onAuthenticationFailure(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException exception) throws IOException, ServletException {
        setDefaultFailureUrl("/login?error=true");

        super.onAuthenticationFailure(request, response, exception);

        final Locale locale = localeResolver.resolveLocale(request);

        String errorMessage = messages.getMessage("message.badCredentials", null, locale);

        if (exception.getMessage().equalsIgnoreCase("User is disabled")) {
            errorMessage = messages.getMessage("auth.message.disabled", null, locale);
        } else if (exception.getMessage().equalsIgnoreCase("User account has expired")) {
            errorMessage = messages.getMessage("auth.message.expired", null, locale);
        } else if (exception.getMessage().equalsIgnoreCase("blocked")) {
            errorMessage = messages.getMessage("auth.message.blocked", null, locale);
        }

        request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, errorMessage);
    }
}

Страница входа:

<div class="card card-login mx-auto form-transparent">
                <div th:if="${param.error != null}" class="alert alert-danger" th:text="${session[SPRING_SECURITY_LAST_EXCEPTION]}">error</div>

                    <div class="card-body ">
                        <form id="myForm" novalidate="" th:action="@{/app-login}"
                            th:method="post" th:object="${user}">
                            <div th:if="${msg}" id="info">
                                <div id="alert" class="alert alert-info">
                                    <button type="button" class="close" data-dismiss="alert"
                                        aria-hidden="true">×</button>
                                    <span class="glyphicon glyphicon-info-sign"></span> <strong>Informacja!</strong>
                                    <hr class="message-inner-separator">
                                    <p th:text="${msg}"></p>
                                </div>
                            </div>

1 Ответ

0 голосов
/ 02 октября 2018

Нам пришлось сделать аналогичную реализацию CustomAuthenticationFailureHandler.В отличие от вашей, мы добавили следующую строку в ваш метод onAuthenticationFailure , чтобы перенаправить на страницу со сбоями при входе в систему.

response.sendRedirect("/login/loginFailed/"+errorMessage);

Теперь, когда мы перенаправили пользователяна адрес loginFailed нам нужно сопоставить его с контроллером.В нашем случае мы создали контроллер входа в систему.

@RequestMapping(value = "/loginFailed/{errorMessage}")
public String errorLogin(Model model,
                         @PathVariable("errorMessage") String errorMessage) {
    model.addAttribute("errorMessage", errorMessage);
    return "/login";
}

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

<div th:if="${errorMessage}" class="alert alert-error">
      <label th:text="${errorMessage}" class="error"></label>
</div>

Надеюсь, это поможет.

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