繁体   English   中英

为什么 antMatchers 不工作并尝试验证登录路由?

[英]Why antMatchers not working and trying to authenticate Login route?

我在 spring 安全性中进行身份验证 API 时遇到问题。

我有 JWT 登录的设置,并使用 Spring Security OncePerRequestFilter 注册路由。 出于某种原因,当我尝试登录时,它还会尝试运行doFilter方法。 意思是,即使用户尝试使用username and password ,我的 api 也会查找jwt Bearer token

我的SecurityConfig.java如下所示,但 antMatchers 不适用于我想的login路径。

有谁可以帮助我吗?

安全配置.java

@Configuration
@AllArgsConstructor
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final AppUserService appUserService;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private JwtFilter jwtFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable();

        http
                .authorizeRequests()
                .antMatchers("/api-docs", "/swagger").permitAll()
                .antMatchers("/api/v0/auth/login").permitAll()
                .antMatchers("/h2-console/**").permitAll()
                .anyRequest()
                .authenticated();

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.addFilterBefore(this.jwtFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(this.daoAuthenticationProvider());
    }

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setPasswordEncoder(this.bCryptPasswordEncoder);
        provider.setUserDetailsService(this.appUserService);
        return provider;
    }
}
@RestController
@AllArgsConstructor
@RequestMapping(path = "/api/v0/auth")
public class AuthController {

    @Autowired
    private AuthService authService;

    @PostMapping("/login")
    public ResponseEntity<AuthResponse> login(@RequestBody LoginRequest request) throws Exception {
        AuthResponse response = this.authService.login(request);
        return ResponseEntity.ok().body(response);
    }
// ..... the rest

当我访问/api-docs", "/swagger"时, API 不会尝试进行身份验证。但是 API 会为/api/v0/auth/login做,因为我可以在之后的日志中看到我在 doFilter 中添加的日志向/api/v0/auth/login发送请求

@Component
public class JwtFilter extends OncePerRequestFilter {

    private Logger log = LoggerFactory.getLogger(JwtFilter.class);

    @Override
    protected void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain filterChain) throws ServletException, IOException {


        String authorization = request.getHeader("Authorization");
        String token = null;
        String userName = null;
        log.info("@@ doFilterInternal: {}", authorization);
        
        // jwt and authentication stuff

        filterChain.doFilter(request, response);
    }
}

// what I see in the log for login request
// 2023-01-22 09:49:06.716  INFO 15780 --- [nio-8080-exec-1] c.h.s.config.security.filter.JwtFilter   : @@ doFilterInternal: null

因为我在 antMatchers 中添加了一个登录端点,所以它不应该记录这个并跳过我认为的身份验证。 有人可以帮我解决我所缺少的吗?

请参阅这篇文章,使用 permitAll 的 HttpSecurity 配置,您没有绕过过滤器 -> Spring Security with filters permitAll not working 如果您不想调用您的过滤器,您可以将 url 排除配置移动到 WebSecurity,设置如下

@Override
public void configure(WebSecurity web) throws Exception {
    web
        .ignoring()
        .antMatchers("/api/v0/auth/login");
}

或者您可以将 url exclude 添加到 OncePerRequestFilter,如下所示 -

private final RequestMatcher uriMatcher = new AntPathRequestMatcher("/api/v0/auth/login", HttpMethod.GET.name());

@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
    return uriMatcher.matches(request);
}

我猜您想使用 POST 方法登录,那么您需要在方法中明确说明,如下所示

    http
         .csrf().disable()
         .antMatchers("HttpMethod.POST, /api/v0/auth/login").permitAll()
         ...

您还可以尝试只保护需要的端点

 http
            .authorizeRequests()
            .antMatchers("/secured").authenticated()
            .anyRequest()
            .permitAll();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM