我希望允许所有用户通过JWT登录。仅允许登录的用户访问专用端点。没有记录任何内容,甚至没有“拒绝访问”。下面是我的SecurityConfig
配置类。
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableMethodSecurity
public class SecurityConfig {
private final JwtAuthenticationFilter jwtAuthFilter;
private final AuthenticationProvider authProvider;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeHttpRequests()
.requestMatchers(publicEndpoints()).permitAll()
.requestMatchers(userEndpoints()).permitAll()
.requestMatchers(adminEndpoints()).hasRole("ADMIN")
.anyRequest().denyAll()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authenticationProvider(authProvider)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.accessDeniedHandler((request, response, ex) -> {
System.out.println("Access Denied: " + ex.getMessage());
response.sendError(HttpServletResponse.SC_FORBIDDEN);
});
return http.build();
}
private RequestMatcher userEndpoints() {
return new OrRequestMatcher(
new AntPathRequestMatcher("/u/**")
);
}
private RequestMatcher adminEndpoints() {
return new OrRequestMatcher(
new AntPathRequestMatcher("/admin/**")
);
}
private RequestMatcher publicEndpoints() {
return new OrRequestMatcher(
new AntPathRequestMatcher("/user/register"),
new AntPathRequestMatcher("/user/signin")
);
}
}
下面是JwtAuthenticationFilter:
@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtService jwtService;
private final UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain) throws ServletException, IOException {
final String authHeader = request.getHeader("Authorization");
if(authHeader == null || !authHeader.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
return;
}
final String jwtToken = authHeader.substring(7); // removes "Bearer " string.
final String username = jwtService.extractUsername(jwtToken);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtService.isTokenValid(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authToken.setDetails(new WebAuthenticationDetailsSource()
.buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
}
}
目前,使用上述配置,我没有得到任何日志。我尝试将安全配置更改为.requestMatchers(userEndpoints()).hasRole("USER")
,但仍然返回403 Forbidden。但这一次,有一个日志说“访问被拒绝:拒绝访问”。
我也尝试过使用@PreAuthorize("hasRole('USER')")
作为被调用的控制器方法,但也没有什么效果。
1条答案
按热度按时间a0zr77ik1#
在SecurityConfig类中,在securityFilterChain方法中,使用的是**“denyAll()"方法。有了它,你说所有上述要求都应该被拒绝。将denyAll()修改为authenticated()**。
方法如下: