为 JWT 使用过滤器时,HttpServletRequest 为空,标头适用于邮递员,但不适用于 localhost
Posted
技术标签:
【中文标题】为 JWT 使用过滤器时,HttpServletRequest 为空,标头适用于邮递员,但不适用于 localhost【英文标题】:HttpServletRequest is null when using filter for JWT, headers work on postman but not localhost 【发布时间】:2020-08-08 14:10:41 【问题描述】:我将 React 用于前端,Java spring boot 用于后端。在我使用 Bcrypt 对密码进行编码之前,我的 api 正在工作,但现在在每次响应为空的 api 调用之前,内部过滤器似乎存在问题......
这是我的 WebSecurityConfig.java
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
private UserDetailsService myUserDetailsService;
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncode());
@Bean
public PasswordEncoder passwordEncode()
return new BCryptPasswordEncoder();
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean();
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/authenticate").permitAll()
.antMatchers("/personInfo").permitAll()
.antMatchers("/signup").permitAll().
anyRequest().authenticated().and().
addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class).exceptionHandling();
这是我的 JWTRequestFilter.java
我认为这可能与 passwordEncoder() 有关,因为当我不使用 BcryptPasswordEncoder() 时我的调用正在工作...
@Component
public class JwtRequestFilter extends OncePerRequestFilter
@Autowired
private MyUserDetailsService userDetailsService;
@Autowired
private JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException
if(request == null)
System.out.println("request is null");
final String authorizationHeader = request.getHeader("Authorization");
String username = null;
String jwt = null;
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer "))
jwt = authorizationHeader.substring(7);
username = jwtUtil.extractUsername(jwt);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null)
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(jwt, userDetails))
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
chain.doFilter(request, response);
我在前端使用 react 并使用 axios 调用
async totals()
console.log('Bearer ', localStorage.getItem('id_token'));
let data = await axios.get("http://localhost:8080/totals",
headers:
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('id_token')
)
.then(this._checkStatus);
return data.request.response;
当我在邮递员中使用令牌时,api 工作,所以问题出在初始请求和过滤器之间......
我得到的错误是 - 从源“http://localhost:3000”访问“http://localhost:8080/totals”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态。
感谢您的宝贵时间:)
【问题讨论】:
【参考方案1】:如果有人遇到同样的问题,我通过在 WebSecurityConfig.java 中的 configure(HttpSecurity httpSecurity) 方法末尾添加这一行来解决它
httpSecurity.cors();
:)
【讨论】:
以上是关于为 JWT 使用过滤器时,HttpServletRequest 为空,标头适用于邮递员,但不适用于 localhost的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Boot 2 上实现基于过滤器的 JWT 身份验证与 OAuth2 JWT 身份验证
前后端分离的Web应用程序中使用Spring Security+Mybatis+JWT非对称加密+动态权限管理:身份验证过滤器
不使用 UsernamePasswordAuthenticationToken 的 Spring Security JWT 验证