我正在使用Spring启动开发应用程序并使用JWT实现身份验证。当我用邮递员测试API时,我可以看到它创建了Authorization标头,并且当手动将其发布到标头时,后续的休息调用工作没有任何问题。但是,当我从我的JavaFX应用程序执行其余调用时,我可以看到登录休息调用创建的令牌,但后续的休息调用失败,并显示403禁止状态代码。当我调试时,问题是当JWTAuthFilter(通过扩展GenericFilterBean实现)试图让Authorization标头将其传递给后续的休息调用时,它返回null。
String token = request.getHeader(HEADER_STRING);
request.getHeader(HEADER_STRING)始终返回null。
/**
* WebSecurityConfig
*/
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserRepository userRepository;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers(HttpMethod.POST, "/rest/login").permitAll()
.anyRequest().authenticated()
.and()
// We filter the rest/login requests
.addFilterBefore(new JWTLoginFilter("/rest/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
// And filter other requests to check the presence of JWT in header
.addFilterBefore(new JWTAuthFilter(),
UsernamePasswordAuthenticationFilter.class);
}
/**
* JWTAuthFilter
*/
public class JWTAuthFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
Authentication authentication = TokenAuthenticationService.getAuthentication((HttpServletRequest) request);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(request, response);
}
}
/**
* TokenAuthenticationService
*/
public class TokenAuthenticationService {
static final long EXPIRATIONTIME = 864_000_000; // 10 days
static final String SECRET = "ThisIsASecret";
static final String TOKEN_PREFIX = "Bearer";
static final String HEADER_STRING = "Authorization";
static void addAuthentication(HttpServletResponse res, String username) {
String JWT = Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT);
}
static Authentication getAuthentication(HttpServletRequest request) {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// parse the token.
String user = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody()
.getSubject();
return user != null ?
new UsernamePasswordAuthenticationToken(user, null, emptyList()) :
null;
}
return null;
}
}