Spring AOP实现接口安全认证

来源:互联网 发布:重庆啤酒 事件 知乎 编辑:程序博客网 时间:2024/06/03 18:33

利用Spring AOP解密请求参数,实现接口安全认证

在写接口的时候经常会遇到需要进行安全认证的场景,如果是一两个接口写个公共的安全检查方法,然后每个接口去调用一下就可以了,但是如果接口很多,这个过程就显得有点繁琐了,由于工作需要所以看了几篇通过SpringAOP实现的,自己也在项目中实验了一下,代码如下。

Spring AOP有什么环绕通知,前置后置通知,大家可以具体看下关于这几个通知的含义及用法。

自定义一个注解,@Security.java,代码如下

package com.light.api.helper.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import com.light.api.constant.Authority;/** *  * @Description: 自定义安全验证注解 * */@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Security {    /**     *      * @Title: sign     * @Description: 签名字段     * @return String[]     * @throws     */    String[] sign() default {};    /**     *      * @Title: field     * @Description: 加密的字段     * @return String[]     * @throws     */    String[] field() default {};    /**     *      * @Title: method     * @Description:      * @return Authority     * @throws     */    Authority method() default Authority.DEFAULT_ACCESS;}

Spring AOP的具体实现类

package com.light.api.helper.aop;import java.util.Arrays;import javax.annotation.Resource;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.reflect.MethodSignature;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;/** *  * @Description: 接口安全验证AOP * */@Aspect@Componentpublic class SecurityAOP {    private static final Logger logger = LoggerFactory.getLogger(SecurityAOP.class);    @Resource    private TrafficPermissionManager<TrafficPermission> trafficPermissionManager;    /**     * 在所有标注@Security的地方切入     */    @Before("@annotation(com.light.api.helper.annotation.Security)")    public void beforeExec(JoinPoint joinPoint) throws IOException {    }    @After("@annotation(com.light.api.helper.annotation.Security)")    public void afterExec(JoinPoint joinPoint) {    }    @AfterThrowing(value = "@annotation(com.light.api.helper.annotation.Security)", throwing = "ex")    public void afterThrowing(JoinPoint joinPoint, Exception ex) {        String methodName = joinPoint.getSignature().getName();        logger.error("@AfterThrowing-->The method {} occurs exception:{}", methodName, ex);    }    @Around("@annotation(com.light.api.helper.annotation.Security)")    public Object around(ProceedingJoinPoint point) throws Throwable {        logger.info("@Around start ...");        MethodSignature ms = (MethodSignature) point.getSignature();        Authority authority = ms.getMethod().getAnnotation(Security.class).method();        String[] signs = ms.getMethod().getAnnotation(Security.class).sign();        String[] fields = ms.getMethod().getAnnotation(Security.class).field();        Object[] args = point.getArgs();        for (int i = 0; i < args.length; i++) {            if (args[i] instanceof SecurityRequest) {                // 需要实现的业务逻辑                // 在这儿可以对参数进行解密操作,并赋值给args[i]中,传递到目标方法中。然后在目标方法中就可以使用已经解密的参数了。            }            if (args[i] instanceof String) {                // 需要实现的业务逻辑            }        }        // 这个很重要        Object response = point.proceed(args);        // 在这块可以记日志。        return response;    }}

因为使用的是注解方式的AOP,所以只需要在SpringMVC.xml配置文件中添加下面这段代码就可以了

<aop:aspectj-autoproxy proxy-target-class="true"/>

controller中的代码如下:

    @Security(sign = { "aaa", "bbb" }, fields = { "aaa", "bbb" }, method = Authority.TEST)    @RequestMapping(value = { "/test", "/test1" }, method = { RequestMethod.POST }, produces = {            "application/json" }, consumes = { "application/json" })    @ResponseBody    public SecurityResponse test(@RequestBody TrafficRequest trafficRequest, String request) {        //具体实现        return null;    }
到这里基本就可以了,大家可以根据需要具体实现。
0 0
原创粉丝点击