Java 使用jwt在springboot中始终允许未经授权的请求
我有一个项目,我已经启用了jwt的授权。问题在于,每当我发送一个空的标头请求或标头中的过期授权码时,它不会向我发送未经授权的错误,它会在日志中显示令牌无效,但允许请求继续工作。这是我的配置代码:Java 使用jwt在springboot中始终允许未经授权的请求,java,spring,spring-boot,jwt,authorization,Java,Spring,Spring Boot,Jwt,Authorization,我有一个项目,我已经启用了jwt的授权。问题在于,每当我发送一个空的标头请求或标头中的过期授权码时,它不会向我发送未经授权的错误,它会在日志中显示令牌无效,但允许请求继续工作。这是我的配置代码: @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private UserDetailsService jwtUserDetailsService;
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// configure AuthenticationManager so that it knows from where to load
// user for matching credentials
// Use BCryptPasswordEncoder
auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(BCryptVersion.$2Y);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/authenticate","/user","/swagger-ui.html","/swagger-ui/**"
,"/v3/api-docs/**").permitAll().
anyRequest().authenticated().and().
exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
httpSecurity.logout().logoutSuccessUrl("/authenticate").logoutUrl("/logout").permitAll();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().mvcMatchers(String.valueOf(HttpMethod.OPTIONS), "/**");
// ignore swagger
web.ignoring().mvcMatchers("/swagger-ui.html/**", "/configuration/**", "/swagger-resources/**", "/v2/api-docs");
}
}
这是我的jwt请求过滤器:
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private JwtUserDetailsService jwtUserDetailsService;
private JwtTokenUtil jwtTokenUtil;
public JwtRequestFilter(JwtTokenUtil jwtTokenUtil) {
this.jwtTokenUtil = jwtTokenUtil;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String requestTokenHeader = request.getHeader("Authorization");
String username = null;
String jwtToken = null;
// JWT Token is in the form "Bearer token". Remove Bearer word and get
// only the Token
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
jwtToken = requestTokenHeader.substring(7);
try {
username = jwtTokenUtil.getUsernameFromToken(jwtToken);
} catch (IllegalArgumentException e) {
System.out.println("Unable to get JWT Token");
} catch (ExpiredJwtException e) {
System.out.println("JWT Token has expired");
}
}
else if (requestTokenHeader == null){
logger.info("Does not provide Authorization Header");
}
else if (!requestTokenHeader.startsWith("Bearer ")){
logger.warn("JWT Token does not begin with Bearer");
}
// Once we get the token validate it.
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(username);
// if token is valid configure Spring Security to manually set
// authentication
if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// After setting the Authentication in the context, we specify
// that the current user is authenticated. So it passes the
// Spring Security Configurations successfully.
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
最后是JwtAuthenticationEntryPoint:
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable {
private static final long serialVersionUID = -7858869558953243875L;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
这是一个日志,显示我没有在头中发送任何令牌,但它允许请求:
你知道我该怎么做吗?
关于进一步的信息,我应该说此代码正在工作,但在一段时间后停止工作,我没有找到任何原因,因为我已经几个月没有对这些文件进行任何更改。您丢失了addFilterAfter,并更新了您的代码,如下所示
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/authenticate","/user","/swagger-ui.html","/swagger-ui/**"
,"/v3/api-docs/**").permitAll().
anyRequest().authenticated().and().
exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class).logout().logoutSuccessUrl("/authenticate").logoutUrl("/logout").permitAll();
}
请参阅问题在于此行的配置错误
web.ignoring().mvcMatchers(String.valueOf(HttpMethod.OPTIONS), "/**");
应该是
web.ignoring().mvcMatchers(HttpMethod.OPTIONS, "/**");
正如您现在可能已经注意到的,您的配置实际上忽略了来自Spring安全过滤器的所有请求路径。这就是现在允许所有未经授权的请求(您期望的)的原因。您能提供应该受到保护的端点吗?这是终结点,但所有其他终结点都是相同的。很抱歉听到这个消息。但是TaskConfig.java中的代码和整个项目都经过了良好的测试,并且可以正常工作。你能试着再校准一次吗?希望它能工作。谢谢再次给出我的答案谢谢,我删除了这一行,因为它不允许我删除字符串.valueof。