@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfiguration {
private final JwtAuthenticationFilter jwtAuthFilter;
private final AuthenticationProvider authenticationProvider;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.headers()
.frameOptions().disable()
.and()
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/h2/**").permitAll()
.requestMatchers("/api/v1/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authenticationProvider(authenticationProvider)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
我有一个config类,我在代码中放置了.requestMatchers("/h2/**").permitAll()
,但是当我访问http://localhost:8080/h2
时,我得到了:
对本地主机的访问被拒绝
JwtAuthenticationFilter:
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");
final String jwt;
final String userEmail;
if (authHeader == null ||!authHeader.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
return;
}
jwt = authHeader.substring(7);
userEmail = jwtService.extractUsername(jwt);
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);
}
}
doFilterInternal方法是过滤器的主要方法。它检查传入请求是否具有“Authorization”标头,其中JWT以“Bearer“开头,如果是,则使用JwtService从JWT提取用户电子邮件,并使用UserDetailsService加载用户详细信息。如果JWT有效且用户详细信息加载成功,在SecurityContextHolder中创建并设置一个认证对象。2然后通过filterChain.doFilter(request,response)调用继续过滤器链。
1条答案
按热度按时间1tuwyuhd1#
.requestMatchers(new AntPathRequestMatcher("/h2/**")).permitAll()
而不是:.requestMatchers("/h2/**").permitAll()