对请求进行权限拦截可以使用三种方法:1、过滤器,2、拦截器,3.AOP
这里使用aop,主要是项目其他地方使用了拦截器,而新增的api接口是在拦截器放行,执行顺序依次是过滤器、拦截器、切面。
话不多说,上代码
1.首先增加对应的包,我这里使用的是gradle进行版本管理
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop compile group: 'org.springframework.boot', name: 'spring-boot-starter-aop', version: '2.1.6.RELEASE'
2.创建新的切面类,加上 @Aspect、@Component 两个注释,进行声明
/** * @description 对外开放api接口验证切面 * @author: czw * @create: 2019-08-14 10:40 **/ @Aspect @Component public class AuthAspect { Logger logger = LoggerFactory.getLogger(getClass()); @Resource private ApiAuthService apiAuthService; /** * 第一个*代表返回类型不限 * 第二个*代表所有方法 * (..) 代表参数不限 * @return */ @Around("execution(* net.microlinktech.xxx.xxx.xxx.api.ApiController.*(..))") public Object aspectHandlerMethod(ProceedingJoinPoint pjp) throws Throwable { HttpServletRequest request = ContextHolderUtils.getRequest(); String token = request.getHeader("authToken"); if(StringUtils.isEmpty(token)){ return JSON.toJSON(ApiResult.error(-1,"请求签名不能为空!")).toString(); } String base64DecodeStr = new String(Base64.decodeBase64(token)); String[] str = base64DecodeStr.split(","); ApiAuth apiAuth = apiAuthService.findByApiId(str[0]); if(checkDate(str[1]) > 5){ //当时间超过五分钟就提示超时 return JSON.toJSON(ApiResult.error(-2,"签名已超时!")); } //判断是否白名单请求 String requestIp = RequestIpUtils.getIp(request); if(!requestIp.equals(apiAuth.getIp())){ return JSON.toJSON(ApiResult.error(-3,"请求失败,ip:" + requestIp +",不在白名单内!")); } //判断apiId是否存在 if(null == apiAuth){ return JSON.toJSON(ApiResult.error(-4,"签名不存在,该核实后再使用!")); } String checkToken = getToken(apiAuth.getApiId(),apiAuth.getApiKey(),str[1]); //判断是否存在,存在再根据key+id+time生成token进行对比,验证是否被修改 if(!token.equals(checkToken)){ return JSON.toJSON(ApiResult.error(-5,"请求中止,该签名已被篡改!")); } logger.info("authToken=" + request.getHeader("authToken")); return pjp.proceed(); } }
3.创建切面指定的类进行测试
/** * @description 对外开放api接口 * @author: czw * @create: 2019-08-14 10:49 **/ @Controller @RequestMapping(value = "/api/") public class ApiController { @PostMapping("test") @ResponseBody public String test(){ return "调用api成功!"; } }
就这样完成了切面权限认证,有时间再写其他两种拦截方法!