我已经使用Spring Boot 2创建了一个Rest API项目。我已经使用jwt进行了身份验证。我可以生成令牌。但是,当我在带有请求的标头中发送生成的令牌时,它总是将我重定向到“ /”路径而不是所请求的路径(在我的情况下为“ / rest / hello”)。
这是我的自定义AuthenticationProvider
@Component
public class JwtAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
@Autowired
private JwtValidator jwtValidator;
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
}
@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken)authentication;
String token = jwtAuthenticationToken.getToken();
JwtUser jwtUser = jwtValidator.validate(token);
if (jwtUser == null) {
throw new RuntimeException("JWT Token not correct");
}
List<GrantedAuthority> grantedAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(jwtUser.getRole());
return new JwtUserDetails(jwtUser.getUserName(), jwtUser.getId(), grantedAuthorities, token);
}
@Override
public boolean supports(Class<?> authentication) {
return JwtAuthenticationToken.class.isAssignableFrom(authentication);
}
}
这是我的自定义过滤器
public class JwtAuthenticationTokenFilter extends AbstractAuthenticationProcessingFilter {
public JwtAuthenticationTokenFilter() {
super("/rest/**");
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith("Token ")) {
throw new RuntimeException("JWT Token is missing");
}
String authenticationToken = header.substring(6);
JwtAuthenticationToken token = new JwtAuthenticationToken(authenticationToken);
return this.getAuthenticationManager().authenticate(token);
}
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
public void setAuthenticationSuccessHandler(JwtSuccessHandler jwtSuccessHandler) {
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
super.successfulAuthentication(request, response, chain, authResult);
chain.doFilter(request, response);
}
}
这是我的安全配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class JwtSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationProvider authenticationProvider;
@Autowired
private JwtAuthenticationEntryPoint entryPoint;
@Bean
public AuthenticationManager authenticationManager() {
return new ProviderManager(Collections.singletonList(authenticationProvider));
}
@Bean
public JwtAuthenticationTokenFilter authenticationTokenFilter(){
JwtAuthenticationTokenFilter filter = new JwtAuthenticationTokenFilter();
filter.setAuthenticationManager(authenticationManager());
filter.setAuthenticationSuccessHandler(new JwtSuccessHandler());
return filter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/rest/**").authenticated().and().exceptionHandling().authenticationEntryPoint(entryPoint)
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
http.headers().cacheControl();
}
}
我还有用于用户详细信息和令牌的自定义类。