提问人:Hajji Achref 提问时间:7/12/2023 最后编辑:Hajji Achref 更新时间:7/13/2023 访问量:115
Spring Security 过滤器未触发
Spring Security filters not triggered
问:
我已经在我的spring java应用程序中实现了身份验证/授权机制。 这是我的配置类:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
public void configure(HttpSecurity http) throws Exception
{
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilterBefore(new JwtAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
这些是我的过滤器:
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
try {
// Parse the user's credentials from the request body
LoginRequest loginRequest = new ObjectMapper().readValue(request.getInputStream(), LoginRequest.class);
System.out.println("loginRequest: " + loginRequest);
// Create an authentication token with the user's credentials
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
loginRequest.getUsername(),
loginRequest.getPassword(),
new ArrayList<>()
);
// Authenticate the user
return authenticationManager.authenticate(authenticationToken);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
// Get the authenticated user's details
BoUser userDetails = (BoUser) authResult.getPrincipal();
// Create a JWT token for the user
String token = JwtTokenUtil.generateToken(userDetails);
// Add the token to the response headers
response.addHeader("Authorization", "Bearer " + token);
}
}
public class JwtAuthorizationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("do filter internal");
if (request.getMethod().equals("OPTIONS")) {
response.setStatus(HttpServletResponse.SC_OK);
}
else {
String jwtToken = request.getHeader(SecParams.JWT_HEADER_NAME);
System.out.println("jwtToken = " + jwtToken);
if (jwtToken == null || !jwtToken.startsWith(SecParams.HEADER_PREFIX)) {
System.out.println("null or doesn't start with Bearer");
filterChain.doFilter(request, response);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SecParams.SECRET)).build();
System.out.println("jwtVerifier = " + jwtVerifier);
DecodedJWT decodedJWT = jwtVerifier.verify(jwtToken.substring(SecParams.HEADER_PREFIX.length()));
System.out.println("decodedJWT = " + decodedJWT);
String email = decodedJWT.getSubject();
System.out.println("email = " + email);
List<String> roles = decodedJWT.getClaims().get("roles").asList(String.class);
System.out.println("roles = " + roles);
Collection<GrantedAuthority> authorities = new ArrayList<>();
roles.forEach(rn -> {
authorities.add(new SimpleGrantedAuthority(rn));
});
UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken(email, null, authorities);
SecurityContextHolder.getContext().setAuthentication(user);
filterChain.doFilter(request, response);
}
}
}
问题是这些过滤器在发送请求时不会触发;因此,我仍然可以访问资源,而无需在请求中发送令牌。
我想知道为什么我的过滤器没有被触发以及如何解决
答:
0赞
ownerofglory
7/13/2023
#1
对于与你提供的安全配置匹配的每个请求,都应调用你。JwtAuthorizationFilter
请记住,筛选器配置为按特定顺序运行。确保对单个请求最多执行一次特定过滤器。OncePerRequestFilter
但是,筛选器链的工作方式是,如果链中较早的筛选器已处理请求并且未调用 ,则链中的较晚筛选器将不会被调用。doFilter
FilterChain
一个潜在的问题可能与你正在测试的网址模式有关。请记住,您允许所有请求无需身份验证。因此,如果您正在使用 进行测试,则不会调用 ,因为您允许所有请求/login
/login
JwtAuthorizationFilter
/login
此外,在 .但是,在 JWT 身份验证方案中,添加已定义的通常,用于代替JwtAuthorizationFilter
UsernamePasswordAuthenticationFilter
JwtAuthenticationFilter
UsernamePasswordAuthenticationFilter
JwtAuthenticationFilter
UsernamePasswordAuthenticationFilter
评论
0赞
Hajji Achref
7/13/2023
我正在使用 url 来测试,但未调用该方法。我正在使用其他 url 来测试 .我尝试更改过滤器的顺序' .addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(new JwtAuthorizationFilter(), JwtAuthenticationFilter.class);',但这并不能解决问题/login
JwtAuthenticationFilter
attemptAuthentication()
JwtAuthorizationFilter
评论