springboot项目下几种拦截方式
1.aop
pom.xml依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.1.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> </dependencies>
代码:
package com.xx; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.lang.reflect.Method; @Aspect @Order(-1) @Component public class ControllerAspect { private static final Logger LOG = LoggerFactory.getLogger(ControllerAspect.class); //对服务实现类进行切面,动态指定数据源 @Pointcut("(execution(* com..*.*(..))) )") public void pointCut() { } @Before(value = "pointCut()") public void doBeforeWithDefault(JoinPoint joinPoint) { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); //获取当前切点方法对象 Method method = methodSignature.getMethod(); Class dclass=method.getDeclaringClass(); if (dclass.isInterface()) {//判断是否为借口方法 try { //获取实际类型的方法对象 method = joinPoint.getTarget().getClass() .getDeclaredMethod(joinPoint.getSignature().getName(), method.getParameterTypes()); } catch (NoSuchMethodException e) { LOG.error("方法不存在!", e); } } } }
2.WebFilter Controller的拦截,传统的
@WebFilter("/*") public class FilterDemo implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("FilterDemo..."); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }
3.响应式 WebFilter
这个不好用,它同时会过滤以下AuthFilter的url。除非只用这个Filter,不把它和AuthFilter一起用。
package cn.xx; import cn.hutool.json.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.Ordered; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; import reactor.core.publisher.Mono; import java.nio.charset.StandardCharsets; import java.util.List; @Component @Slf4j public class ControllerFilter implements WebFilter { @Autowired private AuthService authService; @Override public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) { try { String token=null; List<String> tokenList=serverWebExchange.getRequest().getHeaders().get(JWTConstant.TOKEN); if (tokenList != null && tokenList.size() > 0) { token = tokenList.get(0); } if (token == null) { return authService.sendBlock(serverWebExchange.getResponse()); } JWTToken jwtToken = new JWTToken(FebsUtil.decryptToken(token)); boolean ret = authService.doAuthentication(jwtToken); if (!ret) { return authService.sendBlock(serverWebExchange.getResponse()); } }catch(Exception e){ log.error(e.getMessage(),e); } return webFilterChain.filter(serverWebExchange); } }
4.响应式GlobalFilter, Ordered
package cn.xx; import io.netty.buffer.UnpooledByteBufAllocator; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.StopWatch; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.NettyDataBufferFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequestDecorator; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.server.HandlerStrategies; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import javax.annotation.Resource; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Locale; import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; /** * 请求日志打印 */ @Component @Slf4j public class AuthFilter implements GlobalFilter, Ordered { @Override public int getOrder() { return OrderedConstant.REQUEST_FILTER; } @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); String token = ""; try { // verification failed, blocked List<String> tokenList = request.getHeaders().get(JWTConstant.TOKEN); if (tokenList != null && tokenList.size() > 0) { token = tokenList.get(0); } String url = request.getURI().getPath(); String httpMethod = request.getMethod().name(); boolean ret = authService.verifyUrl(url, httpMethod, token); if (!ret) { return authService.sendBlock(exchange.getResponse()); } } catch (Exception e) { log.error("AuthGlobalFilter error: ", e); } return handleLog(exchange, chain, token); } }
5. spring mvc
配置拦截器:
package com.xx.auth; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; //不能用WebMvcConfigurationSupport,用这个会把spring.data-formate等配置替换 /** * 第 */ @Configuration public class PermissionConfiguration implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // //注册RequestInterceptor拦截器 InterceptorRegistration registration = registry.addInterceptor(new AuthenticationInterceptor()); registration.addPathPatterns("/**"); } }
拦截器实现:
package cn.xx.auth; import cn.xx.auth.factory.AuthFactory; import cn.hutool.extra.spring.SpringUtil; import lombok.extern.slf4j.Slf4j; 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.io.IOException; import java.lang.reflect.Method; @Slf4j public class AuthenticationInterceptor implements HandlerInterceptor { //@Autowired //private AuthFactory authFactory; /** * 请求处理之前调用 */ @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws IOException { log.info("请求地址:【{}】", httpServletRequest.getServletPath()); //如果不是映射到方法直接通过 if (!(object instanceof HandlerMethod)) { return true; } HandlerMethod handlerMethod = (HandlerMethod) object; Method method = handlerMethod.getMethod(); if (method.isAnnotationPresent(UserPermission.class)) { UserPermission annotation = method.getAnnotation(UserPermission.class); Class<? extends AuthFactory> authenticator = annotation.adminAuth(); AuthFactory authFactory= SpringUtil.getBean(authenticator); return authFactory.auth(httpServletRequest, httpServletResponse, object); } return true; } /** * 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后) */ @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } /** * 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作) */ @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } }
配合标注方法:
@UserPermission(adminAuth = AdminAuthenticator.class)
相关阅读
评论:
↓ 广告开始-头部带绿为生活 ↓
↑ 广告结束-尾部支持多点击 ↑