Конфигурация Spring Security HttpSecurity - PullRequest
2 голосов
/ 07 ноября 2019

Я пытаюсь понять, как работают RequestMatcher, AntMatcher и так далее. Я читаю некоторые посты и понимаю основы. На самом деле у меня есть этот простой базовый конфиг:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.requestMatchers() //1
        .antMatchers("/login", "/oauth/authorize") //2
        .and() //3
        .authorizeRequests() //4
        .anyRequest() //5
        .authenticated() //6;

Я действительно не понимаю пункты 1,2 и 3. Насколько я понимаю, это означает, что запросы /login и /oauth/authorize отображаются и должны быть авторизованными запросами. ,Все остальные запросы требуют аутентификации.

Средства для конечной точки /user/me Я должен быть аутентифицирован, потому что он управляется пунктами 5 и 6? Звонок на эту конечную точку работает для меня.

В моем другом конфиге я использую другой подход:

@Override
protected void configure(HttpSecurity http) throws Exception { // @formatter:off
      http
       .authorizeRequests() //1
        .antMatchers("/login", "/oauth/authorize", "/img/**").permitAll() //2
        .anyRequest() //3
        .authenticated() //4

С моей точки зрения, это должна быть та же логика, что и в первомконфигурации. Но на самом деле конечная точка /user/me больше недоступна.

Я был бы очень признателен за разъяснения


Обновление 1:

Это моя конфигурация сейчас:

@Override
protected void configure(HttpSecurity http) throws Exception { // @formatter:off
    http
        .requestMatchers()
           .antMatchers("/", "/login", "/oauth/authorize", 
               "/main", "/logout-success", "/single-logout",
               "/password_forgotten", "/enter_new_password", "/img/**",
               "/logout", "/access_denied")
            .and().authorizeRequests()
                .antMatchers("/img/**", "/logout-success", "/password_forgotten",
                    "/enter_new_password", "/access_denied").permitAll()
            .requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll()
            .and()
            .authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .failureUrl("/login?error")
            .defaultSuccessUrl("/main")
            .permitAll()
            .and()
            .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/logout-success")
            .deleteCookies("JSESSIONID")
            .invalidateHttpSession(true)
            .and()
            .exceptionHandling()
            .accessDeniedPage("/access_denied")
            .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
            .and().csrf().disable();

и если я ввожу URL \user\me как не прошедший проверку подлинности пользователя, я получаю 401 и это сообщение:

<oauth>
<error_description>
Vollständige Authentifikation wird benötigt um auf diese Resource zuzugreifen
</error_description>
<error>unauthorized</error>
</oauth>

Что в порядке, но означает, что для этого URL имеет место любая другая опция SecurityFilterChain, верно?

Ответы [ 2 ]

3 голосов
/ 08 ноября 2019

requestMatchers() определяет, будет ли URL обрабатываться этим SecurityFilterChain. Таким образом, если URL-адрес не соответствует ему, весь SecurityFilterChain будет пропущен, что означает, что Spring Security не будет обрабатывать этот URL-адрес после этого. Если вы не настроите его, по умолчанию будут совпадать все URL-адреса.

authorizeRequests() настраивает средства авторизации для URL-адреса, такие как, например, если требуется аутентификация или доступ к нему имеют только определенные роли. и т. д. Он действует только для тех URL-адресов, которые обрабатываются этим SecurityFilterChain (т. е. для тех URL-адресов, которые соответствуют requestMatchers())

Итак, вернемся к первому примеру:

  http.requestMatchers() //1
        .antMatchers("/login", "/oauth/authorize") //2
        .and() //3
        .authorizeRequests() //4
        .anyRequest() //5
        .authenticated() //6;

Это означает, что SecurityFilterChain будет действовать только на /login и /oauth/authorize. Оба URL-адреса должны быть аутентифицированы. Все остальные URL не будут обрабатываться этой SecurityFilterChain. То, требуется ли аутентификация /user/me или нет, не имеет никакого отношения к Spring Security.

http
       .authorizeRequests() //1
        .antMatchers("/login", "/oauth/authorize", "/img/**").permitAll() //2
        .anyRequest() //3
        .authenticated() //4

Это означает, что все URL-адреса будут обрабатываться SecurityFilterChain (значение по умолчанию requestMatchers()). /login, /oauth/authorize и /img/** не требуют авторизации. Другие URL-адреса должны быть аутентифицированы.

2 голосов
/ 07 ноября 2019

Ваша первая конфигурация
.requestMtchers () // 1

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.requestMatchers() //1
        .antMatchers("/login", "/oauth/authorize") //2
        .and() //3
        .authorizeRequests() //4
        .anyRequest() //5
        .authenticated() //6;

Позвольте мне объяснить ваши .authorizeRequests() // 4

http.authorizeRequests() Это подстановочный знак (/**) (точно так же, как фильтр разрешает каждый запрос)
Конфигурация HttpSecurity будет рассматривать только запросы с этим шаблоном, вы можете сказать

http.authorizeRequests()
//is nothing but equals to
http.antMatcher("/**").authorizeRequests();
//and also equals to
http.requestMatchers()
            .antMatchers("/**")
            .and()
            .authorizeRequests()

если вы сконфигурируете, как показано ниже

http.antMatcher("/api/**").authorizeRequests();

Остальная часть конфигурации (.hasRole(), .hasAnyRole, .authenticated() или .authenticated()) будет рассматриваться только в том случае, если входящий запрос uri соответствует сконфигурированномуantmatcher (/api/**)

Предположим, вам нужно настроить несколько URL (другой шаблон), тогда вы не можете использовать просто один antMatcher. Вам нужно несколько, тогда вы должны использовать requestMatcher, как показано ниже

http.requestMatchers()
            .antMatchers("/api/**", "employee/**", "/customer/**")
            .and()
            .authorizeRequests()

.antMatchers () // 2
Используется для настройки RequestMatcherConfigurer тип возвращаемого значения .requestMatchers()
или также
Используется для настройки ExpressionInterceptUrlRegistry тип возврата .authorizeRequests()

.and () // 3

Возвращает HttpSecurity для дальнейших настроек

.anyRequest () // 5

Объект, который объединен в цепочку после создания RequestMatcher

Все запросы соответствуют настроенному шаблону сопоставления запросов

.authenticated () // 6
Ниже конфигурация не требует пояснений

.antMatchers("/app/admin/**").hasRole("ADMIN")
//or
.antMatchers("/app/admin/**").hasAnyRole("ADMIN", "USER")
//or
.antMatchers("/app/admin/**").authenticated()
//or
.antMatchers("/app/admin/**").permitAll()

Это грубое представление о antMatchers, authorizeRequests и аутентификации. Вы можете сослаться на мой ответ в этой ссылке для последовательности выполнения в безопасности весны

...