authorization
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] - 执行成功
结束
>>>>>>>>>>方法结束执行后的操作
相关阅读
今天部署了一个Authorization项目,由于改了auth服务器客户端id和密码,而前端请求header没有修改,登录时一直弹框要求输入用户名和密
$.ajax({ type: "GET", url: "http://localhost:8080/books", beforeSend: function(xhr) {