Использование httpBasic с AuthenticationEntryPoint

Я слежу за этот учебник при использовании аутентификации JWT с весенней загрузкой. Я могу войти в систему и получить доступ к API от почтальона, как показано в руководстве. Однако, когда я пытаюсь сделать то же самое в браузере по адресу localhost: 8080, я получаю ошибку 401 Unauthorized.

В учебнике используется следующий метод настройки:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable()
      .authorizeRequests().antMatchers("/api/auth/**").permitAll().anyRequest()
      .authenticated().and().exceptionHandling()
      .authenticationEntryPoint(unauthorizedHandler).and()
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}

Когда я удаляю authenticationEntryPoint и добавляю httpbasic, в браузере отображается диалоговое окно входа в систему при доступе к localhost: 8080.

@Override
protected void configure(HttpSecurity http) throws Exception { 
    http.cors().and().csrf().disable()
      .authorizeRequests().antMatchers("/api/auth/**").permitAll().anyRequest()
      .authenticated().and().exceptionHandling()
      .and().httpBasic().and().sessionManagement()
      .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

Но когда я пытаюсь добавить httpBasic с authenticationEntryPoint, диалоговое окно входа в систему не отображается.

@Override
protected void configure(HttpSecurity http) throws Exception {
      http.cors().and().csrf().disable()
        .authorizeRequests().antMatchers("/api/auth/**").permitAll().anyRequest()
        .authenticated().and().exceptionHandling()
        .authenticationEntryPoint(unauthorizedHandler)
        .and().httpBasic().and().sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

  http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}

Обновлено

unauthorizedHandler - это реализация AuthenticationEntryPoint.

@Component
public class UnauthorizedHandler implements AuthenticationEntryPoint {

    private static final Logger logger = LoggerFactory.getLogger(UnauthorizedHandler.class);

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

        logger.error("Unauthorized error. Message - {}", e.getMessage());
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error -> Unauthorized");
}

}

Как я могу отобразить диалоговое окно входа в систему при использовании AuthenticationEntryPoint?

Зачем вам нужна настраиваемая точка входа для аутентификации? Что такое unauthorizedHandler? Покажи свой код. httpBasic уже добавляет точку входа для аутентификации, чего должно быть достаточно.

dur 10.01.2019 11:00

Я следую этот учебник, чтобы реализовать безопасность Spring с помощью jwt. Я обновил код в исходном вопросе, чтобы включить unauthorizedHandler.

Kshitij Bajracharya 10.01.2019 11:30

Ваша точка аутентификации ничего не делает (просто ведет журнал). Убери это.

dur 10.01.2019 20:45
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
1 371
2

Ответы 2

По умолчанию exceptionHandling включен, и он использует точку входа по умолчанию, которая является Http403ForbiddenEntryPoint, когда вы настраиваете httpBasic(), он устанавливает новую точку входа по умолчанию в exceptionHandling, которая является BasicAuthenticationEntryPoint - это все по умолчанию, когда точка входа не определена явно.

Когда вы явно определяете новую точку входа .exceptionHandling().authenticationEntryPoint(some entry point), вся конфигурация по умолчанию больше не используется и будет использоваться вместо нее some entry point.

Обратите внимание, что httpBasic все еще работает, но он должен каким-то образом сообщить вашему браузеру, что аутентификация не удалась, и сообщить браузеру, чтобы он запрашивал учетные данные для http basic, и это то, что делает BasicAuthenticationEntryPoint, установив соответствующий заголовок WWW-Authenticate: Basic realm = "User Visible Realm".

В вашем UnauthorizedHandler в commence добавьте строки String realmName = "some text"; и response.addHeader("WWW-Authenticate", "Basic realm=\"" + realmName + "\"");

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

Это немного старовато, но я надеюсь, что мой ответ все равно кому-то поможет.

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

@Component
public class AuthEntryPointJwt implements AuthenticationEntryPoint {

    private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class);

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException) throws IOException {
        // Requested URL contains "swagger" since it is the only page where I wanted to display login dialog when set header to display dialog and send back the response
        if (request.getRequestURL().toString().contains("swagger")) {
            response.setHeader("WWW-Authenticate", "BASIC");
            response.sendError(response.SC_UNAUTHORIZED);
        } else {
            // if not, just send unauthorized error
            logger.error("Unauthorized error: {}", authException.getMessage());
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error: Unauthorized");
        }

    }
}

Другие вопросы по теме