一个SSH的项目(springmvc+hibernate),须要提供接口给app使用。首先考虑的就是权限问题,app要遵循极简模式,部份内容无需验证,用过滤器不能解决某些无需验证的方法 因此最终选择用AOP 解决。大体思路是使用自定义注解,在须要权限控制的方法前(controller层)使用注解而后使用AOP拦截访问的方法,判断当前用户是否登陆了(判断是否携带了登陆以后获取到的 token ),从而决定是否拦截。javascript
<!--aop配置,基于类的代理 -->
<!-- <aop:aspectj-autoproxy proxy-target-class="true"/>-->
<aop:aspectj-autoproxy/>
注意:1、必定要放在spring的配置文件中,不要单独新建一个文件html
二、proxy-target-class属性值决定是基于接口的仍是基于类的代理被建立。若是proxy-target-class 属性值被设置为true,那么基于类的代理将起做用(这时须要cglib库)。若是proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理将起做用。前端
@Retention(RetentionPolicy.RUNTIME)//注解会在class中存在,运行时可经过反射获取 @Target(ElementType.METHOD)//目标是方法 @Documented public @interface LoginRequired{ }
ElementType.MeTHOD
表示该自定义注解能够用在方法上RetentionPolicy.RUNTIME
表示该注解在代码运行时起做用java
能够在自定义注解中加入一些默认方法jquery
@Component @Aspect public class TokenInterceptor { private static final Logger logger = Logger.getLogger(TokenInterceptor.class); @Resource private BllUserService bllUserService; @Pointcut("@annotation(org.jeecgframework.core.annotation.LoginRequired)") public void serviceAspect() { }
//环绕通知(特别适合作权限系统) //@Before @Around("serviceAspect()") public Object checkPermission(ProceedingJoinPoint joinPoint) throws Throwable{ AjaxJson json=new AjaxJson(); // String methodName = joinPoint.getSignature().getName(); // Object target = joinPoint.getTarget(); // Method method = getMethodByClassAndName(target.getClass(), methodName); //获得拦截的方法 Object[] args = joinPoint.getArgs(); HttpServletRequest request=(HttpServletRequest)args[0]; if(!validate(request)){ //request.setAttribute("message", "您没有执行该操做权限"); json.setMsg("您没有执行该操做权限"); json.setSuccess(false); return json; } return joinPoint.proceed(); } private boolean validate(HttpServletRequest request)throws Exception {
// String token=request.getParameter("token");//根据前端传值进行修改 String token=request.getHeader("token"); if(StringUtil.isEmpty(token)){ } Map<String, Object> resultMap=Jwt.validToken(token); TokenState state=TokenState.getTokenState((String)resultMap.get("state")); switch (state) { case VALID: //取出payload中数据,放入到request做用域中 request.setAttribute("data", resultMap.get("data")); break; case EXPIRED://暂时没作 case INVALID: return false; } return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }
@Aspect放在类头上,把这个类做为一个切面。ajax
@Compenent注解标识其为Spring管理Bean,而@Aspect注解不能被Spring自动识别并注册为Bean,必须经过@Component注解来完成spring
注:这儿用了JWT作token验证,感兴趣的同窗自行百度json
/** * 校验token是否合法,返回Map集合,集合中主要包含 state状态码 data鉴权成功后从token中提取的数据 * 该方法在过滤器中调用,每次请求API时都校验 * @param token * @return Map<String, Object> */ public static Map<String, Object> validToken(String token) { Map<String, Object> resultMap = new HashMap<String, Object>(); try { JWSObject jwsObject = JWSObject.parse(token); Payload payload = jwsObject.getPayload(); JWSVerifier verifier = new MACVerifier(SECRET); if (jwsObject.verify(verifier)) { JSONObject jsonOBj = payload.toJSONObject(); // token校验成功(此时没有校验是否过时) resultMap.put("state", TokenState.VALID.toString()); // 若payload包含ext字段,则校验是否过时 if (jsonOBj.containsKey("ext")) { long extTime = Long.valueOf(jsonOBj.get("ext").toString()); long curTime = new Date().getTime(); // 过时了 if (curTime > extTime) { resultMap.clear(); resultMap.put("state", TokenState.EXPIRED.toString()); } } resultMap.put("data", jsonOBj); } else { // 校验失败 resultMap.put("state", TokenState.INVALID.toString()); } } catch (Exception e) { //e.printStackTrace(); // token格式不合法致使的异常 resultMap.clear(); resultMap.put("state", TokenState.INVALID.toString()); } return resultMap; }
@RequestMapping(params = "physicalList") @ResponseBody @LoginRequired public AjaxJson getPhysicalList(HttpServletRequest request){ }
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="initial-scale=1, maximum-scale=1"> <title></title> </head> <body> <button type="button" onclick="getdata()">测试页面</button><br/> <script type="text/javascript" src="js/jquery.min.js" ></script> <script> var token="123"; function getdata(){ $.ajax({ type:"post", dataType:"json", url:"", headers:{ token:token//将token放到请求头中 }, // beforeSend: function(request) { // request.setRequestHeader("token", token); // }, success:function(data){ console.log(data); $('body').append(JSON.stringify(data)); }, }); } </script> </body> </html>
能够发现页面请求被拦截了restful
参考:http://blog.csdn.net/caomiao2006/article/details/51287206mvc
http://www.jianshu.com/p/576dbf44b2ae
http://www.scienjus.com/restful-token-authorization/