Ошибка при попытке разрешить POST-запросы к /api/user в Spring SecurityJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Ошибка при попытке разрешить POST-запросы к /api/user в Spring Security

Сообщение Anonymous »

Я настроил Spring Security для своего приложения Spring Boot, чтобы разрешать только запросы POST

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

/api/user
но при выполнении такого запроса я получаю ошибку 403 Forbidden. Другие пути, настроенные в настройках безопасности, работают должным образом.
Моя конфигурация безопасности Spring:

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

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

private final JwtAuthFilter jwtAuthFilter;
private final UserRepository userRepository;

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
jwtAuthFilter.setUserDetailsService(userDetailsService());

http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(requests -> requests
.requestMatchers(HttpMethod.POST, "/api/user").permitAll()  // Allow POST requests to /api/user
.requestMatchers("/auth/**").permitAll()  // Allow other public paths, if any
.anyRequest().authenticated())  // Require authentication for all other requests
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authenticationProvider(authenticationProvider())
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

return http.build();
}

@Bean
public AuthenticationProvider authenticationProvider() {
final DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}

@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();  // Use BCryptPasswordEncoder for production
}

@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
return config.getAuthenticationManager();
}

@Bean
public UserDetailsService userDetailsService() {
return email -> userRepository.findByEmail(email)
.map(user -> new User(
user.getEmail(),
user.getPassword(),
user.getRoles().stream()
.map(role -> new SimpleGrantedAuthority(role.getName()))
.collect(Collectors.toList())))
.orElseThrow(() ->  new UsernameNotFoundException("User not found"));
}
}

JWT-фильтр:

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

package i.config.security;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Setter;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Objects;

import static org.springframework.http.HttpHeaders.AUTHORIZATION;

@Component
public class JwtAuthFilter extends OncePerRequestFilter {

private final JwtUtils jwtUtils;

@Setter
private UserDetailsService userDetailsService;

public JwtAuthFilter(JwtUtils jwtUtils) {
this.jwtUtils = jwtUtils;
}

@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
final String authHeader = request.getHeader(AUTHORIZATION);
final String userEmail;
final String jwtToken;

if (Objects.isNull(authHeader) || !authHeader.startsWith("Bearer")) {
filterChain.doFilter(request, response);
return;
}

jwtToken = authHeader.substring(7);
userEmail = jwtUtils.extractUsername(jwtToken);

if (Objects.nonNull(userEmail) &&
Objects.isNull(SecurityContextHolder.getContext().getAuthentication())) {
UserDetails userDetails = userDetailsService.loadUserByUsername(userEmail);
if (jwtUtils.isTokenValid(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
filterChain.doFilter(request, response);
}
}

Запрос:

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

POST http://localhost:8080/api/user
Content-Type: application/json

{
"name": "sSs",
"email": "sSs@a.b",
"password": "1",
"roles": [
{
"name": "ROLE_ADMIN"
}
]
}
Проблема:
Я получаю ошибку 403 Forbidden для запросов POST к /api/user. Другие пути, такие как /auth/**, работают правильно.
Вопрос:
Что может быть причиной ошибки 403 и как правильно настроить Spring Безопасность для разрешения запросов POST к /api/user?
Проверена конфигурация пути и метода.
Проверена функциональность фильтра JWT.
Включено подробное ведение журнала безопасности Spring.

Подробнее здесь: https://stackoverflow.com/questions/788 ... g-security
Ответить

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

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

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

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

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