【发布时间】:2019-12-25 20:02:40
【问题描述】:
我创建了两个过滤器来使用 JWT 令牌执行身份验证。 我想在第一个中处理 JWT 异常:exceptionTokenVerificationHandlerFilter 并检查第二个中是否一切正常:jwtTokenFilter。 如果由于过期日期而导致身份验证失败,则该过程返回到第一个过滤器并向前端发送响应,并带有拒绝访问消息。
我将此答案用作对我的应用程序的支持: https://github.com/szerhusenBC/jwt-spring-security-demo/issues/63#issuecomment-377012514
我的课:
WebSecurityConfig
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.addFilterBefore(exceptionTokenVerificationHandlerFilter, JwtTokenFilter.class)
.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.cors().and()
.csrf().disable()
.authorizeRequests() // .antMatchers("/**")
.antMatchers("/login/**", "/register/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
//.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
.addFilterAt(customUsernamePasswordAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
/*.formLogin()
.loginPage("http://localhost:4200/login")//.failureUrl("/login-error")
.loginProcessingUrl("/login")
.usernameParameter("email")
.successHandler(customAuthenticationSuccessHandler)
.and()*/
.logout()
.permitAll();
}
ExceptionTokenVerificationHandlerFilter
package app.shellx.security;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.filter.OncePerRequestFilter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.JwtException;
@Configuration
public class ExceptionTokenVerificationHandlerFilter extends OncePerRequestFilter {
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
filterChain.doFilter(request, response);
} catch (JwtException e) {
String message;
switch(e.getClass().getName()) {
case "ExpiredJwtException":
message = "token-expired";
break;
default:
message = e.getMessage();
break;
}
response.setStatus(HttpStatus.BAD_REQUEST.value());
response.getWriter().write(convertObjectToJson(message));
}
}
private String convertObjectToJson(Object object) throws JsonProcessingException {
if (object == null) {
return null;
}
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(object);
}
}
JwtTokenFilter
package app.shellx.security;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;
@Configuration
public class JwtTokenFilter extends GenericFilterBean {
private JwtTokenProvider jwtTokenProvider;
public JwtTokenFilter(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {
String token = jwtTokenProvider.resolveToken((HttpServletRequest) req);
if (token != null && jwtTokenProvider.validateToken(token)) {
Authentication auth = token != null ? jwtTokenProvider.getAuthentication(token) : null;
SecurityContextHolder.getContext().setAuthentication(auth);
}
filterChain.doFilter(req, res);
}
}
那么我可以在过滤器链中一个接一个地添加两个自定义过滤器吗?
我现在从编译器收到以下错误消息:
原因:java.lang.IllegalArgumentException:未注册Filter类app.shellx.security.JwtTokenFilter后无法注册
【问题讨论】:
-
什么是 JSON Web Token Token,为什么在代码中重复单词 token 很重要?
-
@Tom 无缘无故,我只是习惯了这样命名
标签: java spring spring-security spring-filter