Spring Security OAuth与JWT配置导致所有请求被拦截求助
嘿,我看你在搭建基于JWT的Spring Security OAuth2授权服务时遇到了Spring Security拦截所有请求的问题——连关键的/oauth/token端点都被拦了,这确实是个典型的配置冲突问题,咱们一步步来梳理修复:
核心问题根源
你的WebSecurityConfigurerAdapter(SecurityConfig)和ResourceServerConfigurerAdapter(ResourceServerConfig)的HttpSecurity规则存在重叠,同时没有正确放行授权服务器的核心端点,导致请求还没到授权服务器就被Spring Security的过滤器链拦截了。
具体修复点
1. 给WebSecurity放行授权服务器端点
在SecurityConfig的configure(HttpSecurity http)方法里,你需要明确放行/oauth/token、/oauth/authorize这些授权服务器专属端点,不然WebSecurity会先把它们拦住:
@Override protected void configure(HttpSecurity http) throws Exception { http .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .httpBasic() .realmName(securityRealm) .and() .csrf().disable() // 新增:放行授权服务器核心端点 .authorizeRequests() .antMatchers("/oauth/token", "/oauth/authorize", "/oauth/check_token").permitAll() .anyRequest().authenticated(); }
2. 修正ResourceServer的请求匹配范围
你的ResourceServerConfig里requestMatchers()没有指定具体路径,导致它会拦截所有请求,和WebSecurity的规则打架。应该让资源服务器只负责/api/**这类业务接口,/oauth/**交给授权服务器处理:
@Override public void configure(HttpSecurity http) throws Exception { http // 只对/api/**路径应用资源服务器的授权规则 .requestMatchers() .antMatchers("/api/**") .and() .authorizeRequests() .antMatchers("/actuator/**", "/api-docs/**", "/auth/login").permitAll() .antMatchers("/api/**").authenticated() .and() // 移除formLogin:资源服务器不需要表单登录,咱们用JWT令牌授权 .exceptionHandling() .accessDeniedHandler(accessDeniedHandler()) .authenticationEntryPoint(authenticationEntryPoint()); }
3. 统一密码编码器配置
你在SecurityConfig里同时定义了两个密码编码器(一个是PasswordEncoderFactories生成的,一个是BCryptPasswordEncoder Bean),这会让Spring搞不清用哪个。咱们统一用BCryptPasswordEncoder:
// 保留这个Bean,作为全局的密码编码器 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder()); // 用咱们定义的BCrypt编码器 }
4. 完善授权服务器的安全配置
在AuthorizationServerConfig里,你得开启允许客户端通过Basic Auth获取令牌的配置,不然/oauth/token端点没法处理客户端的认证请求:
@Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer .realm(REALM) // 允许客户端用表单或Basic Auth方式获取令牌 .allowFormAuthenticationForClients() // 允许公开访问/check_token端点(用于验证JWT有效性) .checkTokenAccess("permitAll()"); }
额外提醒
- 别忘了初始化OAuth2所需的数据库表(比如
oauth_client_details、oauth_access_token等),JdbcTokenStore依赖这些表存储令牌信息。 - 确认
application.properties里的security.signing-key配置存在且有效,JWT签名全靠它。 - 你之前的
ResourceServerConfig里的表单登录配置完全没必要,资源服务器只认JWT令牌,删掉这部分能避免不必要的冲突。
内容的提问来源于stack exchange,提问作者Michael Coxon

