个人可以做建站网站么,小程序开发流程步骤,公司网站如何做优化,网站制作 那种语言好文章目录 拦截器实现白名单即API鉴权自定义拦截器注册拦截器 拦截器Service注入失效解决方式#xff1a;获取用户真实IP地址 工具类 Spring Boot 中使用拦截器 参考#xff1a;https://blog.csdn.net/taojin12/article/details/88342576?ops_request_misc%257B%2522request%… 文章目录 拦截器实现白名单即API鉴权自定义拦截器注册拦截器 拦截器Service注入失效解决方式获取用户真实IP地址 工具类 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%257Drequest_id170823498416800197050192biz_id0utm_mediumdistribute.pc_search_result.none-task-blog-2alltop_positive~default-1-88342576-null-null.142v99pc_search_result_base7utm_termspringboot%E6%8B%A6%E6%88%AA%E5%99%A8%E7%9A%84%E4%BD%BF%E7%94%A8spm1018.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;}Overridepublic 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);SetString 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;charsetUTF-8);response.getWriter().write(new String(访问失效.getBytes(StandardCharsets.UTF_8)));return false;}} catch (Exception e) {response.setContentType(application/json;charsetUTF-8);response.getWriter().write(new String(参数错误.getBytes(StandardCharsets.UTF_8)));return false;}// 3、校验参数MapString, OperationAppDO operationAppDOMap getOperationAppService().getAll();if (!operationAppDOMap.containsKey(appId)){return false;}ListString 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;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {//logger.info(执行完方法之后进执行(Controller方法调用之后)但是此时还没进行视图渲染);}Overridepublic 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 {Overridepublic void addInterceptors(InterceptorRegistry registry) {// 实现 WebMvcConfigurer 不会导致静态资源被拦截registry.addInterceptor(new MyInterceptor()).addPathPatterns(/**);}}
拦截器Service注入失效解决方式
原因拦截器加载的时间点在springcontext之前所以在拦截器中注入自然为null
通过ApplicationContext来获取bean 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 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;Overridepublic 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 TMapString, 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-For192.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;}}