Spring Boot 中使用拦截器
参考:https://blog.csdn.net/taojin12/article/details/88342576?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170823498416800197050192%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=170823498416800197050192&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-88342576-null-null.142v99pc_search_result_base7&utm_term=springboot%E6%8B%A6%E6%88%AA%E5%99%A8%E7%9A%84%E4%BD%BF%E7%94%A8&spm=1018.2226.3001.4187
拦截器实现白名单即API鉴权
自定义拦截器
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Configuration
public class MyInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(MyInterceptor.class);
private static WhiteListService whiteListService;
private static OperationAppService operationAppService;
private WhiteListService getWhitelistService() {
if (Objects.isNull(whiteListService)){
whiteListService = (WhiteListService)ApplicationContextUtil.getBean("whiteListServiceImpl");
}
return whiteListService;
}
private OperationAppService getOperationAppService() {
if (Objects.isNull(operationAppService)){
operationAppService = (OperationAppService)ApplicationContextUtil.getBean("operationAppServiceImpl");
}
return operationAppService;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
String methodName = method.getName();
logger.info("====拦截到了方法:{},在该方法执行之前执行====", methodName);
// 1、白名单
String ipAddress = CusAccessObjectUtil.getIpAddress(request);
Set<String> allIp = getWhitelistService().getALl();
if (!allIp.contains(ipAddress)){
return false;
}
// 2、校验header中的时间戳,时差不超过5分钟
String timestamp = "";
String sign = "";
String appId = "";
try {
timestamp = request.getHeader(InterceptorConstant.TIMESTAMP);
sign = request.getHeader(InterceptorConstant.SIGN);
appId = request.getHeader(InterceptorConstant.APPID);
if ((Math.abs(System.currentTimeMillis() - Long.valueOf(timestamp)) / 1000 / 60) > 5) {
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(new String("访问失效".getBytes(StandardCharsets.UTF_8)));
return false;
}
} catch (Exception e) {
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(new String("参数错误".getBytes(StandardCharsets.UTF_8)));
return false;
}
// 3、校验参数
Map<String, OperationAppDO> operationAppDOMap = getOperationAppService().getAll();
if (!operationAppDOMap.containsKey(appId)){
return false;
}
List<String> paramList = new ArrayList<>();
paramList.add(appId);
paramList.add(timestamp);
paramList.add(operationAppDOMap.get(appId).getAppSecret());
Collections.sort(paramList, String::compareTo);
StringBuilder builder = new StringBuilder();
paramList.forEach(param -> builder.append(param));
String md5 = EncryptionUtil.getMD5(builder.toString());
if (Objects.equals(md5, sign)){
return true;
}
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//logger.info("执行完方法之后进执行(Controller方法调用之后),但是此时还没进行视图渲染");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//logger.info("整个请求都处理完咯,DispatcherServlet也渲染了对应的视图咯,此时我可以做一些清理的工作了");
}
}
注册拦截器
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyInterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 实现 WebMvcConfigurer 不会导致静态资源被拦截
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
}
}
拦截器@Service注入失效解决方式:
原因:拦截器加载的时间点在springcontext之前,所以在拦截器中注入自然为null
通过ApplicationContext来获取bean文章来源:https://www.toymoban.com/news/detail-827954.html
@Configuration
public class MyInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(MyInterceptor.class);
private static WhiteListService whiteListService;
private WhiteListService getWhitelistService() {
if (Objects.isNull(whiteListService)){
whiteListService = (WhiteListService)ApplicationContextUtil.getBean("whiteListServiceImpl");
}
return whiteListService;
}
}
ApplicationContextUtil文章来源地址https://www.toymoban.com/news/detail-827954.html
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class ApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static ApplicationContext getApplicationContext(){
return context;
}
/**
* 通过name获取 Bean
* @param name beanName
* @return Object
*/
public static Object getBean(String name){
return context.getBean(name);
}
public static <T>Map<String, T> getBeanByType(Class <T> type){
return context.getBeansOfType(type);
}
public static String[] getBeanNamesForType(Class <?> type){
return context.getBeanNamesForType(type);
}
}
获取用户真实IP地址 工具类
import javax.servlet.http.HttpServletRequest;
/**
* 自定义访问对象工具类
*
* 获取对象的IP地址等信息
* @author X-rapido
*
*/
public class CusAccessObjectUtil {
/**
* 获取用户真实IP地址,不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
* 参考文章: http://developer.51cto.com/art/201111/305181.htm
*
* 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?
* 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
*
* 如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130,
* 192.168.1.100
*
* 用户真实IP为: 192.168.1.110
*
* @param request
* @return
*/
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
到了这里,关于Springboot中自定义拦截器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!