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)



文/程忠 浏览次数:0次   2023-09-09 15:56:05

相关阅读


评论:
点击刷新

↓ 广告开始-头部带绿为生活 ↓
↑ 广告结束-尾部支持多点击 ↑