爲何要寫這個:
緣由簡單,就是需求來了,哈哈!!!
要求:
1.本身對外提供的接口,哪些廠商有權限訪問。
2.每一個接口限制訪問次數,天天須要重置訪問次數上限。
具體的緣由不說了,千言萬語就是安全,安全,安全。redis
開始咱們的表演
先來一遍Spring Boot
在來一遍Spring MVCspring
第一個重點:本身對外提供的接口,哪些廠商有權限訪問
1、設置攔截URL請求數據庫
/** * @Description: 設置攔截 * @author: 你瞅瞅~~ * @create: 2020-01-10 14:51 */ public class AuthRequestInterceptor implements HandlerInterceptor { @Autowired private AuthService authService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 驗證權限 if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; // AuthRequest是咱們定義在controller方法上的註解~ AuthRequest authRequest = handlerMethod.getMethod().getAnnotation(AuthRequest.class); // AuthRequest是咱們定義在controller類上的註解~ if (authRequest == null) { authRequest = handlerMethod.getMethod().getDeclaringClass().getAnnotation(RequiredPermission.class); // 獲取請求URL String requestURI = request.getRequestURI(); // 校驗接口URL/訪問次數 // redis或數據庫(加緩存) 中獲取該用戶的權限信息 並判斷是否有權限 List<String> authCount = authService.getAuthCount(); if (!authURL.contains(requestURI)) { return false; } // 這裏簡單寫一下,明確一點就是【接口URL --> 訪問次數】 Long accessCount = authCount.getAccessCount(); if (accessCount < 0) { return false; } else { int count = accessCount - 1; authService.updateCount(count); } } return true; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
2、使用註解的攔截器
寫這個註解的意思很明確,這樣無論在哪裏項目均可以設置統一攔截,給你們提供一個簡單的註解就完事了,若是你用了Spring boot你就知道註解是多麼省事。express
自定義一個註解 AuthRequest 類segmentfault
/** * @Description: 註解攔截 * @author: 你瞅瞅~~ * @create: 2020-01-10 14:51 */ @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface AuthRequest { String value(); }
三.攔截配置文件WebAppConfig
@Configuration 這個註解,在啓動的時候在會被加載
多個攔截就設置多個相似定義方法 getInterceptor1()/getInterceptor2()緩存
/** * @Description:對外接口權限攔截 * @author: 你瞅瞅~~ * @create: 2020-01-10 14:51 */ @Configuration public class WebAppConfig extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { // 攔截@AuthRequest註解的所求請求 // addPathPatterns 用於添加攔截規則 // excludePathPatterns 用戶排除攔截 registry.addInterceptor(getInterceptor1()).addPathPatterns("/login/**"); registry.addInterceptor(getInterceptor2()).addPathPatterns("/login2/**"); super.addInterceptors(registry); } @Bean public HandlerInterceptor getInterceptor(){ return new authInterceptor; } }
四.Controller添加攔截請求註解安全
/** * @Description:對外接口權限攔截 * @author: 你瞅瞅~~ * @create: 2020-01-10 14:51 */ 這個註解就是攔截整個Controller全部請求,全局註解 @AuthRequest @RequestMapping("/login") public class AuthController { private static final String NO_AUTH = "接口權限"; // 權限註解,至關於局部註解,AuthController.AuthRequest表示在進入攔截判斷是否有值 @AuthRequest(AuthController.AuthRequest) @RequestMapping("/list") public String list() { // 各類操做 return "/login/users"; } // 未註解,表示不攔截 @RequestMapping("/de;ete") public String detail() { // 各類操做 return "/login/user"; } }
第二個重點:每一個接口限制訪問次數,天天須要重置訪問次數上限
簡單說明:設置定時刷新任務,在須要刷新的方法上定時刷新,這樣就能夠天天獲取重置次數,固然也可寫到redis裏,這樣的話,就能夠不用定時刷新獲取。mvc
1.Application 要加註解,也就是總開關@EnableAsync
2.在須要獲取的接口上加上@Scheduled 配置cron表達式app
/** * @Description: 定時任務,天天刷新請求次數 * @author: 你瞅瞅~~ * @create: 2020-01-10 14:51 */ @Scheduled(cron = "0 0 1 * * ?") // 天天凌晨一點刷新接口,authRequest定義一個全局變量 public void accessCountCurrentByCron() { List<String> authRequest = authRequest.getAuthRequests(); if(authRequest.size !=0){ logger.warn("我在刷新。。。"); result authRequest; } } }
爲何寫Spring mvc 由於咱們有老項目,嘿嘿
重頭再來,咱們走完了Spring boot,那來講說Spring mvc ide
在咱們SpringMVC中也可使用攔截器對用戶的請求進行攔截,
用戶能夠自定義攔截器來實現 HandlerInterceptor
主要區別就是個添個配置,Spring boot能夠用註解完事,Spring mvc須要寫在配置文件,剩下的都同樣。
1、添加簡單配置springmvc.xml
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path\="/login/**"/> <bean class\="com.interceptor.AuthInterceptor"/> </mvc:interceptor> </mvc:interceptors> // 這裏是爲了掃描到註釋@AuthRequest // 啓動包掃描功能,以便註冊帶有@Controlle <context:component-scan base-package\="com.org.須要攔截的類" use-default-filters\="false"\> <context:include-filter type\="annotation" expression\="org.springframework.stereotype.Controller"/> <context:include-filter type\="annotation" expression\="com.interceptor.AuthRequest"/> </context:component-scan>
能夠參考這篇文章,spring mvc的用法Controller寫的很詳細 :[https://segmentfault.com/a/11...]
碰見的問題【重點】:
HandlerInterceptor攔截器使用中,就能碰見這個問題,
Required request body is missing OR Stream closed
繼承並實現 HttpServletRequestWrapper包裝類,有時間在補充......