Я пытаюсь сделать запрос из клиентского приожения (react), с localhost:5173. Запрос содержит заголовок с JWT «Authorization».
В результате я получаю ошибку похожую на CORS. А еще на бэкенде в AuthenticationTokenFilter при получении заголовка с авторизацией получаю null. При этом через postman все работает нормально.
Изображения из вкладки Network:
https://i.stack.imgur.com/px7TF.png
https://i.stack.imgur.com/KZkaW.png
Код:
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final AuthenticationTokenFilter authenticationTokenFilter;
private final AuthenticationConfiguration authConfig;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/public").permitAll()
.requestMatchers("/login").permitAll()
.anyRequest().authenticated()
)
// .csrf((csrf) -> csrf.disable()) this I try too
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(ImmutableList.of("*"));
configuration.setAllowedMethods(ImmutableList.of("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"));
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type", "authorization", "content-type", "x-auth-token"));
configuration.setExposedHeaders(Arrays.asList("x-auth-token"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
@RequiredArgsConstructor
@Configurati
public class AuthenticationTokenFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
Integer userId = getUserIdByTokenFromVK(token);
if (userId != null) {
Set<GrantedAuthority> authorities = new HashSet<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
User user = new User();
user.setVkId(userId);
user.setJwt(token);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, null, authorities);
SecurityContextHolder.getContext().setAuthentication(auth);
}
filterChain.doFilter(request, response);
}
private Integer getUserIdByTokenFromVK(String token) {
String serviceToken = "484f88ba2b2c616503ffd3f4gsd3243f43grefsrgb923815d";
String apiVersion = "5.154";
CloseableHttpClient httpClient = HttpClients.createDefault();
String url = "https://api.vk.com/method/secure.checkToken?access_token=" + serviceToken +
"&token=" + token +
"&v=" + apiVersion;
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity != null) {
String responseString = EntityUtils.toString(entity);;
ObjectMapper objectMapper = new ObjectMapper();
VKResponse vkResponse = objectMapper.readValue(responseString, VKResponse.class);
if (vkResponse.getResponse() != null) {
return vkResponse.getResponse().getUserId();
} else if (vkResponse.getError() != null) {
Integer errorCode = vkResponse.getError().getErrorCode();
String errorMsg = vkResponse.getError().getErrorMsg();
System.out.println("Error Code: " + errorCode);
System.out.println("Error Message: " + errorMsg);
return null;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
httpClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
// .allowedOrigins("http://localhost:8080", "http://localhost:3000", "http://localhost:5173", "http://localhost:3001", "*")
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH")
.allowedHeaders("Authorization", "Cache-Control", "Content-Type");
// .allowedHeaders("*")
// .allowCredentials(true);
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("POST");
config.addAllowedMethod("GET");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PUT");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}