针对您的问题,我来为您详细讲解Spring Boot如何实现filter拦截token验证和跨域。
一、使用Filter拦截Token验证
1. 引入相关依赖
在pom.xml文件中引入以下相关依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
2. 编写TokenFilter
在项目中新建TokenFilter.java文件,继承OncePerRequestFilter类,并重写doFilterInternal方法。在该方法中,我们可以对请求头中的Token进行验证。
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class TokenFilter extends OncePerRequestFilter {
@Value("${jwt.secret}")
private String secret;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String token = request.getHeader("Authorization");
if(StringUtils.isEmpty(token) || !token.startsWith("Bearer ")){
filterChain.doFilter(request, response);
return;
}
try {
Claims claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token.replace("Bearer ", ""))
.getBody();
request.setAttribute("claims", claims);
} catch (SignatureException e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid Token!");
return;
}
filterChain.doFilter(request, response);
}
}
3. 配置TokenFilter
在Spring Boot中使用@WebFilter注解进行配置。在项目启动时,会自动加载该Filter进行处理。
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.RequestContextFilter;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean tokenFilter(){
FilterRegistrationBean<TokenFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new TokenFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setName("TokenFilter");
registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return registrationBean;
}
}
至此,我们就已经完成了使用Filter拦截Token验证的过程。
二、使用Filter实现跨域请求
1. 编写CorsFilter
在项目中新建CorsFilter.java文件,继承OncePerRequestFilter类,并重写doFilterInternal方法。在该方法中,我们可以设置response的header,实现跨域请求。
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Token");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Expose-Headers", "*");
if("OPTIONS".equalsIgnoreCase(request.getMethod())){
response.setStatus(HttpServletResponse.SC_OK);
return;
}
filterChain.doFilter(request, response);
}
}
2. 配置CorsFilter
同样地,在Spring Boot中使用@WebFilter注解进行配置。在项目启动时,会自动加载该Filter进行处理。
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean corsFilter(){
FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new CorsFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setName("CorsFilter");
registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return registrationBean;
}
}
至此,我们就已经完成了使用Filter实现跨域请求的过程。
三、完整的配置文件
最后,如果您需要参考完整的配置文件,可以使用以下代码块进行配置。该配置文件中包含上述两种Filter的配置。
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.RequestContextFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Configuration
public class FilterConfig {
@Value("${jwt.secret}")
private String secret;
@Bean
public FilterRegistrationBean tokenFilter(){
FilterRegistrationBean<TokenFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new TokenFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setName("TokenFilter");
registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return registrationBean;
}
@Bean
public FilterRegistrationBean corsFilter(){
FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new CorsFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setName("CorsFilter");
registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return registrationBean;
}
private class TokenFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String token = request.getHeader("Authorization");
if(StringUtils.isEmpty(token) || !token.startsWith("Bearer ")){
filterChain.doFilter(request, response);
return;
}
try {
Claims claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token.replace("Bearer ", ""))
.getBody();
request.setAttribute("claims", claims);
} catch (SignatureException e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid Token!");
return;
}
filterChain.doFilter(request, response);
}
}
private class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Token");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Expose-Headers", "*");
if("OPTIONS".equalsIgnoreCase(request.getMethod())){
response.setStatus(HttpServletResponse.SC_OK);
return;
}
filterChain.doFilter(request, response);
}
}
}
至此,希望我这份攻略可以帮到您。如果还有任何问题,欢迎继续提问。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Springboot 如何实现filter拦截token验证和跨域 - Python技术站