PermitAll () не работает, неавторизованный 401. Конфигурация безопасности Spring

У меня несколько точек входа. Один из них должен быть защищен фильтром, остальные полностью открыты.

/data/** - filter protected
/callback/** - permitAll
/save/**     - permitAll
/oauth/**    - permitAll

В моем приложении отсутствуют пользователи, роли и база данных. Мне нужно только проверить JWT, что он подписан с правильным закрытым ключом. Итак, я использую:

@SpringBootApplication(exclude= {UserDetailsServiceAutoConfiguration.class})

Перепробовал множество комбинаций, либо требует от всех проверять JWT на все входные точки с помощью фильтра, либо 401 ошибка. Установлена ​​анонимная роль, поскольку при установке .authenticated() возникла ошибка 403.

Пожалуйста помогите мне..

Мой адаптер конфигурации:

@EnableWebSecurity
public class DataSecurity extends WebSecurityConfigurerAdapter {

    @Bean
    public JwtAuthFilter jwtAuthenticationFilter() {
        return new JwtAuthFilter();
    }

  @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()
             
                .csrf().disable()
                .httpBasic().disable()
                .logout().disable()
                .formLogin().disable()
               
                .authorizeRequests().antMatchers("/data/**").hasAuthority("ROLE_ANONYMOUS")
                .and()
                .addFilterBefore(jwtAuthenticationFilter(), AuthorizationFilter.class)
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
               
                .authorizeRequests()
                .anyRequest().permitAll();
    }

@Override
    public void configure(WebSecurity web){
        web.ignoring().antMatchers("/oauth/**","/callback/**","/save/**");
    }
}

Мой фильтр:

@Order(Ordered.HIGHEST_PRECEDENCE)
public class JwtAuthFilter extends OncePerRequestFilter {
    @Value("${auth-service.secret-key}")
    private String jwtSecret;
    private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthFilter.class);

    @Override
    protected void doFilterInternal(
            @Nullable HttpServletRequest request,
            @Nullable HttpServletResponse response,
            @Nullable FilterChain filterChain
    )
            throws IOException, ServletException {
        assert request != null;

        String jwt = parseJwt(request);
        if (jwt!=null && validateToken(jwt) ) {
            assert filterChain != null;
            filterChain.doFilter(request, response);
        } else {
            assert response != null;
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        }
    }
    private String parseJwt(HttpServletRequest request) {
        String headerAuth = request.getHeader("Authorization");

        if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
            return headerAuth.substring(7);
        }
        return null;
    }

    private boolean validateToken(String authToken) {
        try {
            Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
            return true;
        } catch (SignatureException e) {
            LOGGER.error("Error: {}", e.getMessage());
        } catch (MalformedJwtException e) {
            LOGGER.error("Error: {}", e.getMessage());
        } catch (ExpiredJwtException e) {
            LOGGER.error("Error: {}", e.getMessage());
        } catch (UnsupportedJwtException e) {
            LOGGER.error("Error: {}", e.getMessage());
        } catch (IllegalArgumentException e) {
            LOGGER.error("Error: {}", e.getMessage());
        }
        return false;
    }
}

Позвоните http://localhost:9088/oauth/test

Ответ:

{
    "timestamp": "2023-03-30T07:52:22.692+00:00",
    "status": 401,
    "error": "Unauthorized",
    "path": "/oauth/test"
}

СЛЕД:

2023-03-30 11:52:22.662 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=Ant [pattern='/oauth/**'], Filters=[]] (1/3)
2023-03-30 11:52:22.662 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=Ant [pattern='/callback/**'], Filters=[]] (2/3)
2023-03-30 11:52:22.663 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=any request, Filters=[org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@6e807e2, org.springframework.security.web.context.SecurityContextPersistenceFilter@7767bd4e, org.springframework.security.web.header.HeaderWriterFilter@1537e43, org.springframework.web.filter.CorsFilter@6c995c5d, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@433ef204, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@165614f5, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@203b953c, org.springframework.security.web.session.SessionManagementFilter@1304e0d7, org.springframework.security.web.access.ExceptionTranslationFilter@9a9aa68, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@389a5022, com.test.authorization.configuration.security.JwtAuthFilter@1fdca564]] (3/3)
2023-03-30 11:52:22.663 DEBUG 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Securing GET /error
2023-03-30 11:52:22.664 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Invoking WebAsyncManagerIntegrationFilter (1/11)
2023-03-30 11:52:22.664 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Invoking SecurityContextPersistenceFilter (2/11)
2023-03-30 11:52:22.665 DEBUG 6744 --- [nio-9092-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2023-03-30 11:52:22.665 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Invoking HeaderWriterFilter (3/11)
2023-03-30 11:52:22.665 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Invoking CorsFilter (4/11)
2023-03-30 11:52:22.665 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Invoking RequestCacheAwareFilter (5/11)
2023-03-30 11:52:22.665 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Invoking SecurityContextHolderAwareRequestFilter (6/11)
2023-03-30 11:52:22.666 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Invoking AnonymousAuthenticationFilter (7/11)
2023-03-30 11:52:22.667 TRACE 6744 --- [nio-9092-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[ROLE_ANONYMOUS]]
2023-03-30 11:52:22.667 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Invoking SessionManagementFilter (8/11)
2023-03-30 11:52:22.667 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Invoking ExceptionTranslationFilter (9/11)
2023-03-30 11:52:22.667 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Invoking FilterSecurityInterceptor (10/11)
2023-03-30 11:52:22.668 TRACE 6744 --- [nio-9092-exec-2] edFilterInvocationSecurityMetadataSource : Did not match request to Ant [pattern='/data/**'] - [hasAuthority('ROLE_ANONYMOUS')] (1/2)
2023-03-30 11:52:22.668 TRACE 6744 --- [nio-9092-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor    : Did not re-authenticate AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[ROLE_ANONYMOUS]] before authorizing
2023-03-30 11:52:22.668 TRACE 6744 --- [nio-9092-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorizing filter invocation [GET /error] with attributes [permitAll]
2023-03-30 11:52:22.672 DEBUG 6744 --- [nio-9092-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorized filter invocation [GET /error] with attributes [permitAll]
2023-03-30 11:52:22.672 TRACE 6744 --- [nio-9092-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor    : Did not switch RunAs authentication since RunAsManager returned null
2023-03-30 11:52:22.672 TRACE 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Invoking JwtAuthFilter (11/11)
2023-03-30 11:52:22.673 DEBUG 6744 --- [nio-9092-exec-2] o.s.security.web.FilterChainProxy        : Secured GET /error
2023-03-30 11:52:22.676 TRACE 6744 --- [nio-9092-exec-2] edFilterInvocationSecurityMetadataSource : Did not match request to Ant [pattern='/data/**'] - [hasAuthority('ROLE_ANONYMOUS')] (1/2)
2023-03-30 11:52:22.732 DEBUG 6744 --- [nio-9092-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request

мне просто нужно закрыть /data/** , остальные открыты.

Вы можете добавить разрешение на конкретный адрес, например .antMatchers("/api/public").permitAll(), или попытаться отключить csrf для HttpSecurity, например .csrf().disable();

Yeras_QazaQ 30.03.2023 10:53

@Yeras_QazaQ У меня все открыто для определенных конечных точек. И csrf отключен

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

Ответы 1

Ответ принят как подходящий

В настоящее время ваш фильтр всегда выполняется, даже до неаутентифицированных вызовов.

Чтобы решить эту проблему, вы должны указать, какой запрос обрабатывать вашим фильтром. Для этого у вас есть два варианта:

  1. добавьте метод shouldNotFilter в свой JwtAuthFilter

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
      return !request.getRequestURI().startsWith("/data/");
    }
    
  2. просто добавьте следующее условие if в начало вашего JwtAuthFilter.doFilterInternal:

    if (!request.getRequestURI().startsWith("/data/")) {
        filterChain.doFilter(request, response);
        return;
    }
    

Точно такая же проблема обсуждалась в следующем видео с отметкой времени 1:11:11: Безопасность Spring, демистифицированная Даниэлем Гарнье Муару

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