Код: Выделить всё
/api/user
Моя конфигурация безопасности 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"));
}
}
Код: Выделить всё
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
Мобильная версия