当用一个有效的body向/API/v1/auth/authenticate发出请求时,我的Postman会得到一个名为token的cookie,其值是一个jwt。令牌被设置为20分钟后过期,当它过期时,我用确切的body运行调用,这次使用cookie,它被拒绝,基本上说cookie过期了,这是真的。但是,这个端点不需要进行身份验证,正如我在安全配置文件中所建立的那样。这是怎么回事?
我还想补充的是,当在Postman中更改cookie的名称时,请求会被接受,并得到我的响应,沿着一个名为token的新cookie,当删除cookie时,它也会被接受。
AuthController:
@RestController
@RequestMapping("/api/v1/auth/")
@RequiredArgsConstructor
public class AuthenticationController {
private final AuthenticationService authenticationService;
@PostMapping("/register")
public ResponseEntity<AuthenticationResponse> register(@RequestPart("user") UserSignUpDto user,
@RequestPart("inpFile") MultipartFile profilePicture) {
return ResponseEntity.ok(authenticationService.register(user, profilePicture));
}
@PostMapping("/authenticate")
public ResponseEntity<AuthenticationResponse> authenticate(@RequestBody UserLogInDto request,
HttpServletResponse response) {
return ResponseEntity.ok(authenticationService.authenticate(request, response));
}
@ExceptionHandler(ResponseStatusException.class)
public ResponseEntity<Exception> handleConflictError(ResponseStatusException exception) {
// todo figure out ResponseStatusException
return ResponseEntity.status(exception.getStatusCode()).body(exception);
}
}
安全配置:
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfiguration {
private final JwtAuthenticationFilter jwtAuthenticationFilter;
private final AuthenticationProvider authProvider;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(Customizer.withDefaults())
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> {
auth.requestMatchers("/api/v1/auth/**").permitAll();
auth.requestMatchers("/home/**").permitAll();
auth.requestMatchers("/user/**").permitAll();
auth.requestMatchers("/picture/**").permitAll();
auth.anyRequest().authenticated();
})
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authenticationProvider(authProvider)
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("http://localhost:4200"));
configuration.setAllowCredentials(true);
configuration.setAllowedMethods(List.of("GET", "POST"));
configuration.setAllowedHeaders(List.of("Content-Type"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
JwtAuthenticationFilter:
@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtService jwtService;
private final UserDetailsService userDetailsService;
@Override
protected void doFilterInternal( // todo: ask ChatGPT to explain this
@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain
) throws ServletException, IOException {
final String userEmail;
final String jwt;
final Cookie jwtCookie = request.getCookies() != null ? Arrays.stream(request.getCookies()).filter(cookie -> cookie.getName().equals("token"))
.findFirst()
.orElse(null): null;
if (jwtCookie == null) {
filterChain.doFilter(request, response);
return;
}
jwt = jwtCookie.getValue();
userEmail = jwtService.extractUsername(jwt);// todo extract the userEmail token;
if (userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail);
if (jwtService.isTokenValid(jwt, userDetails)) {
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
}
}
1条答案
按热度按时间wj8zmpe11#
看起来你的
JwtAuthenticationFilter
代码中的这一部分是相关的:请注意,如果您的cookie不使用该确切名称,则将跳过您的机制。检查您的
SecurityConfiguration
,过滤器存在于所有请求中,因此您需要实现一种机制来不将过滤器添加到这些不安全的端点,或者向过滤器添加一个方法覆盖,以便它不会在不安全的端点上激活:一种方法是使用
request.getRequestURI()
。