I have a project which I had enabled jwt for authorization on it. The problem is that whenever I send an empty header request or expired authorization code in the header it doesn't send me the unauthorized error, it shows in the log that the token is not valid but allows the request to continue working. this is my configuration code:
@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");
}
}
and this is my jwt request filter:
@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);
}
}
and finally here is 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");
}
}
and this is the log that shows I did not send any token in header, but it allows the request:
any idea that what should I do? for further information, I should say that this code was working but stopped working after a while and I didn't find any reason because I had no changes in these files for months.
The problem is the misconfiguration at this line
web.ignoring().mvcMatchers(String.valueOf(HttpMethod.OPTIONS), "/**");
It should be
web.ignoring().mvcMatchers(HttpMethod.OPTIONS, "/**");
As you might have noticed now that your configuration is actually ignoring all request paths from Spring Security filters. That is the reason that all unauthorized requests (which you expect) are allowed now.
You are missing addFilterAfter and also update your code as below.
@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();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.