Разрешить цепочку фильтров безопасности SpringBootAll не работает должным образом.JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Разрешить цепочку фильтров безопасности SpringBootAll не работает должным образом.

Сообщение Anonymous »

У меня есть проект в университете, и у меня просто проблема: PermitAll не работает должным образом в цепочке фильтров безопасности.
У меня есть две цепочки фильтров: первая — для пользовательского интерфейса с keycloak, а вторая — для публичного доступа для «клиентских» конечных точек с помощью apiKey, а некоторые из них должны быть доступны всем, например, для проверки электронной почты.
Я сижу над этой проблемой несколько дней и не могу' Я действительно не нашел решения и надеюсь, что кто-нибудь сможет мне помочь.
Версия Spring Boot: 3.0.5
Зависимости Spring Boot Security:

Код: Выделить всё

        
org.springframework.security
spring-security-core
6.1.3


org.springframework.boot
spring-boot-starter-security


org.springframework.boot
spring-boot-starter-oauth2-resource-server

Мои конечные точки, проверенные с помощью apiKey, работают должным образом, но я не знаю, является ли это лучшим решением.
ApiFilter:< /p>

Код: Выделить всё

    @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
logger.info("ApiKeyFilter invoked for request: " + request.getRequestURI());
if (ApiContext.isApi()) {
String requestApiKey = request.getHeader("X-API-KEY");
String requestApiSecret = request.getHeader("X-SECRET-KEY");

if (requestApiKey == null || requestApiSecret == null) {
throw new BadCredentialsException("BadCredentials");
}

Optional apiInformationOptional = this.apiInformationRepository.findByApiKey(requestApiKey);

if (!apiInformationOptional.isPresent()) {
throw new BadCredentialsException("BadCredentials");
}

ApiInformation apiInformation = apiInformationOptional.get();

if (!apiInformation.getApiKey().equals(requestApiKey) || !apiInformation.getSecretKey().equals(requestApiSecret)) {
throw new BadCredentialsException("BadCredentials");
}

Optional  tenantInformationOptional = this.tenantInformationRepository.findByOrganization(apiInformation.getOrganization());

if (!tenantInformationOptional.isPresent()) {
throw new BadCredentialsException("BadCredentials");
}

TenantInformation tenantInformation = tenantInformationOptional.get();

Authentication authentication = new UsernamePasswordAuthenticationToken(apiInformation.getApiKey(), null, new ArrayList());
SecurityContextHolder.getContext().setAuthentication(authentication);
TenantContext.setCurrentTenant(tenantInformation.getTenantId());
} else if (ApiContext.isActuator()) {
Authentication authentication = new UsernamePasswordAuthenticationToken("GenericUser", null, new ArrayList());
SecurityContextHolder.getContext().setAuthentication(authentication);
}

filterChain.doFilter(request, response);
}
Цепочки фильтров:

Код: Выделить всё

    @Bean
@Order(1)
@DependsOn("corsConfigurationSource")
public SecurityFilterChain apiServerFilterChain(
HttpSecurity http,
@Qualifier("corsConfigurationSource") CorsConfigurationSource corsConfigurationSource
) throws Exception {
http.authorizeHttpRequests((authorize) ->
authorize.requestMatchers(
GenericAbstractControllerInterface.PUBLIC_API_DOC_BASE_URI + "/**",
GenericAbstractControllerInterface.API_PUBLIC_URI + "/**",
).permitAll()
.anyRequest().authenticated()
)
.addFilterBefore(apiFilter, ChannelProcessingFilter.class)
.addFilterBefore(apiKeyFilter, UsernamePasswordAuthenticationFilter.class)
.sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.httpBasic(withDefaults())
.cors(cors -> {
cors.configurationSource(corsConfigurationSource);
})
.csrf(AbstractHttpConfigurer::disable);

return http.build();
}

@Bean
@Order(0)
public SecurityFilterChain resourceServerFilterChain(
HttpSecurity http,
@Qualifier("corsConfigurationSource") CorsConfigurationSource corsConfigurationSource
) throws Exception {
List subscriptions = subscriptionRepository.findAll();
List allRoles = subscriptions.stream()
.map(subscription -> subscription.getRoles().split(","))
.flatMap(Arrays::stream)
.collect(Collectors.toList());
allRoles.add("ORGANIZATION_ADMIN");
allRoles.add("ORGANIZATION_USER");

http.authorizeHttpRequests(
authorizeRequests -> {
try {
authorizeRequests.requestMatchers(
GenericAbstractControllerInterface.API_PUBLIC_URI + "/**"
).permitAll()
.anyRequest().authenticated().and().oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthConverter);
} catch (Exception e) {
throw new RuntimeException(e);
}

}
);
http.csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler()).disable());
http.sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
http.httpBasic(withDefaults());
http.cors(cors ->  cors.configurationSource(corsConfigurationSource));

return http.build();
}

@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.addAllowedOriginPattern("*");
configuration.setAllowedMethods(Arrays.asList(
HttpMethod.GET.name(),
HttpMethod.POST.name(),
HttpMethod.PUT.name(),
HttpMethod.DELETE.name(),
HttpMethod.OPTIONS.name()
));
configuration.setAllowedHeaders(Arrays.asList("Content-Type", "Authorization", "Access-Control-Allow-Methods", "X-TENANT-ID", "X-API-KEY", "X-ACTUATOR", "X-GUI"));

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
ApiFilter просто проверяет, откуда поступает запрос, и устанавливает глобальную переменную для проверки и проверки других процессов.
Он устанавливает, например. если запрос поступает к общедоступному API к PUBLIC_API, GUI или API
Мои конечные точки, которые проверяются через apiKey, работают как положено, но я не знаю, является ли это лучшим решением.
ApiFilter:

Код: Выделить всё

    @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
logger.info("ApiKeyFilter invoked for request: " + request.getRequestURI());
if (ApiContext.isApi()) {
String requestApiKey = request.getHeader("X-API-KEY");
String requestApiSecret = request.getHeader("X-SECRET-KEY");

if (requestApiKey == null || requestApiSecret == null) {
throw new BadCredentialsException("BadCredentials");
}

Optional apiInformationOptional = this.apiInformationRepository.findByApiKey(requestApiKey);

if (!apiInformationOptional.isPresent()) {
throw new BadCredentialsException("BadCredentials");
}

ApiInformation apiInformation = apiInformationOptional.get();

if (!apiInformation.getApiKey().equals(requestApiKey) || !apiInformation.getSecretKey().equals(requestApiSecret)) {
throw new BadCredentialsException("BadCredentials");
}

Optional tenantInformationOptional = this.tenantInformationRepository.findByOrganization(apiInformation.getOrganization());

if (!tenantInformationOptional.isPresent()) {
throw new BadCredentialsException("BadCredentials");
}

TenantInformation tenantInformation = tenantInformationOptional.get();

Authentication authentication = new UsernamePasswordAuthenticationToken(apiInformation.getApiKey(), null, new ArrayList());
SecurityContextHolder.getContext().setAuthentication(authentication);
TenantContext.setCurrentTenant(tenantInformation.getTenantId());
} else if (ApiContext.isActuator()) {
Authentication authentication = new UsernamePasswordAuthenticationToken("GenericUser", null, new ArrayList());
SecurityContextHolder.getContext().setAuthentication(authentication);
}

filterChain.doFilter(request, response);
}
Цепочки фильтров:

Код: Выделить всё

    @Bean
@Order(1)
@DependsOn("corsConfigurationSource")
public SecurityFilterChain apiServerFilterChain(
HttpSecurity http,
@Qualifier("corsConfigurationSource") CorsConfigurationSource corsConfigurationSource
) throws Exception {
http.authorizeHttpRequests((authorize) ->
authorize.requestMatchers(
GenericAbstractControllerInterface.PUBLIC_API_DOC_BASE_URI + "/**",
GenericAbstractControllerInterface.API_PUBLIC_URI + "/**",
).permitAll()
.anyRequest().authenticated()
)
.addFilterBefore(apiFilter, ChannelProcessingFilter.class)
.addFilterBefore(apiKeyFilter, UsernamePasswordAuthenticationFilter.class)
.sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.httpBasic(withDefaults())
.cors(cors -> {
cors.configurationSource(corsConfigurationSource);
})
.csrf(AbstractHttpConfigurer::disable);

return http.build();
}

@Bean
@Order(0)
public SecurityFilterChain resourceServerFilterChain(
HttpSecurity http,
@Qualifier("corsConfigurationSource") CorsConfigurationSource corsConfigurationSource
) throws Exception {
List subscriptions = subscriptionRepository.findAll();
List allRoles = subscriptions.stream()
.map(subscription -> subscription.getRoles().split(","))
.flatMap(Arrays::stream)
.collect(Collectors.toList());
allRoles.add("ORGANIZATION_ADMIN");
allRoles.add("ORGANIZATION_USER");

http.authorizeHttpRequests(
authorizeRequests ->  {
try {
authorizeRequests.requestMatchers(
GenericAbstractControllerInterface.API_PUBLIC_URI + "/**"
).permitAll()
.anyRequest().authenticated().and().oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthConverter);
} catch (Exception e) {
throw new RuntimeException(e);
}

}
);
http.csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler()).disable());
http.sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
http.httpBasic(withDefaults());
http.cors(cors -> cors.configurationSource(corsConfigurationSource));

return http.build();
}

@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.addAllowedOriginPattern("*");
configuration.setAllowedMethods(Arrays.asList(
HttpMethod.GET.name(),
HttpMethod.POST.name(),
HttpMethod.PUT.name(),
HttpMethod.DELETE.name(),
HttpMethod.OPTIONS.name()
));
configuration.setAllowedHeaders(Arrays.asList("Content-Type", "Authorization", "Access-Control-Allow-Methods", "X-TENANT-ID", "X-API-KEY", "X-ACTUATOR", "X-GUI"));

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
ApiFilter просто проверяет, откуда поступает запрос, и устанавливает глобальную переменную для проверки и проверки других процессов.
Он устанавливает, например. если запрос поступает от общедоступного API к PUBLIC_API, GUI или API

Подробнее здесь: https://stackoverflow.com/questions/786 ... s-expected
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»