Jersey+Spring Boot+Spring Security REST接口无法获取Authorization头求助
看起来你遇到了前后端分离场景下,Angular客户端携带的Authorization请求头无法被Jersey服务端获取的问题,结合你的技术栈,核心原因大概率和跨域预检请求处理以及Spring Security的拦截规则有关,下面分步骤给出可落地的解决方案:
1. 调整Spring Security配置,放行预检请求并允许Authorization头
首先修改你的SecurityConfiguration类,确保浏览器发送的OPTIONS预检请求被放行,同时配置跨域响应头允许Authorization头传递:
import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.web.header.writers.StaticHeadersWriter; import org.springframework.http.HttpMethod; @Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private CustomUserDetailsService userDetailService; @Override protected void configure(HttpSecurity http) throws Exception { http // REST API场景下通常关闭CSRF(如果你的业务需要可以保留,但要额外适配) .csrf().disable() // 配置跨域允许的响应头 .headers() .addHeaderWriter(new StaticHeadersWriter( "Access-Control-Allow-Origin", "https://your-angular-domain.com" // 生产环境务必指定具体域名,不要用* )) .addHeaderWriter(new StaticHeadersWriter( "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" )) .addHeaderWriter(new StaticHeadersWriter( "Access-Control-Allow-Headers", "Authorization, Content-Type" )) .and() // 放行所有OPTIONS预检请求,避免被认证拦截 .authorizeRequests() .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 其他所有请求需要认证 .anyRequest().authenticated() .and() // 这里根据你的认证方式调整,比如HTTP Basic或JWT过滤器 .httpBasic(); } // 配置密码加密器(如果用用户名密码认证的话) @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder()); } }
2. 确保Jersey资源正确获取请求头
在你的Jersey资源类中,通过@Context HttpHeaders来获取请求头,这样就能拿到Authorization的值了:
import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; @Path("/api") public class YourResource { @GET @Path("/demo") public String getDemoData(@Context HttpHeaders headers) { // 直接获取Authorization头 String authHeader = headers.getHeaderString(HttpHeaders.AUTHORIZATION); if (authHeader != null) { // 这里可以继续处理认证逻辑,比如解析JWT或Basic凭证 return "Authorization header received: " + authHeader; } return "Authorization header not found"; } }
另外,Spring Boot整合Jersey时,要确保你的Jersey配置类正确注册资源,避免路径冲突:
import org.glassfish.jersey.server.ResourceConfig; import org.springframework.context.annotation.Configuration; @Configuration public class JerseyConfig extends ResourceConfig { public JerseyConfig() { // 注册你的Jersey资源类 register(YourResource.class); } }
3. 验证Angular客户端的请求配置
最后确认Angular端的请求确实正确携带了Authorization头,示例代码如下:
import { HttpClient, HttpHeaders } from '@angular/common/http'; @Injectable() export class ApiService { constructor(private http: HttpClient) {} fetchDemoData() { const authToken = 'your-jwt-token-or-basic-credentials'; const headers = new HttpHeaders({ 'Authorization': `Bearer ${authToken}`, // Basic认证的话换成`Basic ${btoa('user:pass')}` 'Content-Type': 'application/json' }); return this.http.get('/api/demo', { headers }); } }
关键注意事项
- 生产环境绝对不要用
Access-Control-Allow-Origin: *,必须指定你的前端域名,避免安全风险 - 如果用JWT认证,需要在Spring Security中添加JWT过滤器,确保请求到达Jersey资源前完成认证,同时保证Authorization头不被过滤
- 检查是否有自定义过滤器拦截了请求,导致Authorization头被修改或丢失
内容的提问来源于stack exchange,提问作者Ritesh Bhanushali
相关产品推荐
相关产品推荐

