1、需求
a、对http请求进行访问权限设定
b、对特定请求方法进行拦截,统一进行权限认证
2、方案
自定义注解(用于控制哪些方法需要拦截),通过AOP在需要拦截的Controller方法进行统一拦截权限认证
3、代码
a、自定义注解
import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuthorizationReceive {
String module() default "";
String methods() default "";
}
b、aop
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
@Aspect
@Slf4j
public class AuthorizationAop {
//获取开始时间
private long BEGIN_TIME ;
//获取结束时间
private long END_TIME;
@Pointcut("execution(* web.front..*.*(..))")
private void controllerAspect(){}
/**
* 方法开始执行
*/
@Before("controllerAspect()")
public void doBefore(){
BEGIN_TIME = System.currentTimeMillis();
System.out.println("开始");
}
/**
* 方法结束执行
*/
@After("controllerAspect()")
public void after(){
END_TIME = System.currentTimeMillis();
System.out.println("结束");
}
/**
* 方法结束执行后的操作
*/
@AfterReturning("controllerAspect()")
public void doAfter(){
System.out.println(">>>>>>>>>>方法结束执行后的操作");
}
/**
* 方法有异常时的操作
*/
@AfterThrowing("controllerAspect()")
public void doAfterThrow(){
System.out.println("例外通知-----------------------------------");
}
/**
* 方法执行
* @param pjp
* @return
* @throws Throwable
*/
@Around("controllerAspect()")
public Object around(ProceedingJoinPoint pjp) throws Throwable{
//日志实体对象
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 拦截的实体类,就是当前正在执行的controller
Object target = pjp.getTarget();
// 拦截的方法名称。当前正在执行的方法
String methodName = pjp.getSignature().getName();
// 拦截的方法参数
Object[] args = pjp.getArgs();
// 拦截的放参数类型
Signature sig = pjp.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
msig = (MethodSignature) sig;
Class[] parameterTypes = msig.getMethod().getParameterTypes();
Object object = null;
Method method = null;
try {
method = target.getClass().getMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (null != method) {
// 判断是否包含自定义的注解,说明一下这里的SystemLog就是我自己自定义的注解
if (method.isAnnotationPresent(AuthorizationReceive.class)) {
AuthorizationReceive authorizationReceive = method.getAnnotation(AuthorizationReceive.class);
System.out.println("-------------->"+authorizationReceive.methods());
System.out.println("-------------->"+authorizationReceive.module());
//获取 Authorization 进行认证
System.out.println("-------------->"+request.getHeader("Authorization"));
try {
object = pjp.proceed();
log.info("执行成功");
} catch (Throwable e) {
// TODO Auto-generated catch block
log.info("执行失败");
}
} else {//没有包含注解
object = pjp.proceed();
log.info("此操作不包含注解");
}
} else { //不需要拦截直接执行
object = pjp.proceed();
log.info("不需要拦截直接执行");
}
return object;
}
}
c、spring-mvc配置文件添加aop配置
<!--Aop切面编程的配置-->
<aop:aspectj-autoproxy expose-proxy="true"></aop:aspectj-autoproxy>
<bean id="logAopAction" class="com.common.aop.AuthorizationAop"></bean>
d、controller方法拦截
import com.alibaba.fastjson.JSONObject;
import com.jeeplus.common.aop.AuthorizationReceive;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import sun.misc.BASE64Decoder;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@RequestMapping(value = "out/test/")
@Controller
@Slf4j
public class TestController {
@Autowired
private HttpServletRequest httprequest;
@RequestMapping(value = "getAuthorization",method = {RequestMethod.POST})
@AuthorizationReceive(module = "认证",methods = "获取验证")
@ResponseBody
public JSONObject getAuthorization(){
JSONObject json = new JSONObject();
String authorization = httprequest.getHeader("Authorization");
json.put("authorization",authorization);
System.out.println(authorization);
try {
String userAndPass=new String(new BASE64Decoder().decodeBuffer(authorization.split(" ")[1]));
if(userAndPass.split(":").length<2){
json.put("error","没有权限");
}else{
String user=userAndPass.split(":")[0];
String pass=userAndPass.split(":")[1];
json.put("user",user);
json.put("pass",pass);
}
} catch (IOException e) {
e.printStackTrace();
}
return json;
}
}
控制台打印信息:
-------------->获取验证
-------------->认证
-------------->Basic TEphZXI6MTIzNDU2
开始
Basic TEphZXI6MTIzNDU2
2018-03-21 12:36:43,576 INFO [com.common.aop.AuthorizationAop] - 执行成功
结束
>>>>>>>>>>方法结束执行后的操作