如何跳过 oncePerRequestFilter 和 运行 登录休息端点
How to skip oncePerRequestFilter and run login rest endpoint
我正在尝试学习 spring 安全性但卡在过滤器上。
我知道 oncePerRequestFilter 适用于每个请求,我打算在此过滤器中检查 JWT 令牌。但是,如果用户是新用户并试图到达 /auth/login 端点,那么我需要以某种方式说出此过滤器允许,然后为 /auth/login 执行我的方法。但是我找不到 运行 那种方法。
这是我的 OncePerRequestFilter
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("JwtAuthenticationFilter.doFilterInternal is working");
if(request.getServletPath().equals("/auth/login")) {
System.out.println("if there is a request to /auth/login just continue");
filterChain.doFilter(request, response);
}
// else continue to check JWT token
}
}
我的端点
@AllArgsConstructor
@RestController("/auth")
public class LoginController {
private final AuthenticationManager authenticationManager;
@PostMapping("/login")
public LoginTokenResponse login(@RequestBody LoginRequest loginRequest) {
System.out.println("login method is working");
if(loginRequest == null) {
throw new IllegalArgumentException("No credentials provided");
}
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword());
Authentication authentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
// do other things and return LoginResponseToken
return null;
}
@GetMapping("/ping")
public String ping() {
System.out.println("pong is working");
return "pong";
}
}
和 WebSecurityConfigurerAdapter
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final PasswordCheckUserDetailService passwordCheckUserDetailService;
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
builder.userDetailsService(passwordCheckUserDetailService)
.passwordEncoder(UserPasswordEncoder.getUserPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.cors().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authorizeRequests().antMatchers(HttpMethod.POST, "/auth/login/**").permitAll();
http.authorizeRequests().anyRequest().authenticated();
JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter();
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
当我向 /auth/login 发出 post 请求时
我收到以下响应并且登录方法根本不起作用。 (不打印)
{
"timestamp": "2022-03-12T00:59:38.932+00:00",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/auth/login"
}
如果要检查其他部分:https://github.com/xsenko/JWTAuthentication/tree/develop/src/main/java/com/senko/JWTAuthentication
@RestController("/auth")
- 用于逻辑组件名称,不用于请求映射。
你应该使用 @RequestMapping("/auth")
我正在尝试学习 spring 安全性但卡在过滤器上。 我知道 oncePerRequestFilter 适用于每个请求,我打算在此过滤器中检查 JWT 令牌。但是,如果用户是新用户并试图到达 /auth/login 端点,那么我需要以某种方式说出此过滤器允许,然后为 /auth/login 执行我的方法。但是我找不到 运行 那种方法。
这是我的 OncePerRequestFilter
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("JwtAuthenticationFilter.doFilterInternal is working");
if(request.getServletPath().equals("/auth/login")) {
System.out.println("if there is a request to /auth/login just continue");
filterChain.doFilter(request, response);
}
// else continue to check JWT token
}
}
我的端点
@AllArgsConstructor
@RestController("/auth")
public class LoginController {
private final AuthenticationManager authenticationManager;
@PostMapping("/login")
public LoginTokenResponse login(@RequestBody LoginRequest loginRequest) {
System.out.println("login method is working");
if(loginRequest == null) {
throw new IllegalArgumentException("No credentials provided");
}
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword());
Authentication authentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
// do other things and return LoginResponseToken
return null;
}
@GetMapping("/ping")
public String ping() {
System.out.println("pong is working");
return "pong";
}
}
和 WebSecurityConfigurerAdapter
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final PasswordCheckUserDetailService passwordCheckUserDetailService;
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
builder.userDetailsService(passwordCheckUserDetailService)
.passwordEncoder(UserPasswordEncoder.getUserPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.cors().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authorizeRequests().antMatchers(HttpMethod.POST, "/auth/login/**").permitAll();
http.authorizeRequests().anyRequest().authenticated();
JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter();
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
当我向 /auth/login 发出 post 请求时 我收到以下响应并且登录方法根本不起作用。 (不打印)
{
"timestamp": "2022-03-12T00:59:38.932+00:00",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/auth/login"
}
如果要检查其他部分:https://github.com/xsenko/JWTAuthentication/tree/develop/src/main/java/com/senko/JWTAuthentication
@RestController("/auth")
- 用于逻辑组件名称,不用于请求映射。
你应该使用 @RequestMapping("/auth")