restful项目的权限控制实现技巧

前言

最近的项目在用restful风格在写,果然url都有了意义,功能都可以从url中推测出来,restful的url和非restful的url最大的一个感官区别就是,rest的url可能存在一些变量,比如下面这样:/check/api/user/12345/history,这个url解释起来就是:查看账号为12345的用户的历史资料,而非rest的url是:/check/api/user/history。那么,现在问题就来了,权限控制的核心是判断url,rest的url中却有变量,那么,rest风格的项目如何实现权限控制呢?

实现

其实在我我写这篇文章之前,我的思路是把url的变量去掉,然后存权限表中,然后判断的时候就把访问的url按照相同的规则处理,再在数据库中查,如果查到了代表有权限,反之没有。但事实证明,这种思路只有在变量在url的结尾时才可行。

首先我贴一下权限表的结构,这个是权限控制的核心表。

[sql]  view plain  copy
  1. -- Create table  
  2. create table STAFF_POWER  
  3. (  
  4.   stp_id      NUMBER not null,  
  5.   stp_name    VARCHAR2(40),  
  6.   create_time TIMESTAMP(6),  
  7.   stp_url     VARCHAR2(100),  
  8.   stp_method  VARCHAR2(10)  
  9. )  
  10. tablespace CHECK_ZS  
  11.   pctfree 10  
  12.   initrans 1  
  13.   maxtrans 255  
  14.   storage  
  15.   (  
  16.     initial 64K  
  17.     next 1M  
  18.     minextents 1  
  19.     maxextents unlimited  
  20.   );  
  21. -- Create/Recreate primary, unique and foreign key constraints   
  22. alter table STAFF_POWER  
  23.   add constraint STP_PK primary key (STP_ID)  
  24.   using index   
  25.   tablespace CHECK_ZS  
  26.   pctfree 10  
  27.   initrans 2  
  28.   maxtrans 255  
  29.   storage  
  30.   (  
  31.     initial 64K  
  32.     next 1M  
  33.     minextents 1  
  34.     maxextents unlimited  
  35.   );  
  36. alter table STAFF_POWER  
  37.   add constraint STP_UN unique (STP_URL, STP_METHOD)  
  38.   using index   
  39.   tablespace CHECK_ZS  
  40.   pctfree 10  
  41.   initrans 2  
  42.   maxtrans 255  
  43.   storage  
  44.   (  
  45.     initial 64K  
  46.     next 1M  
  47.     minextents 1  
  48.     maxextents unlimited  
  49.   );  
每个字段的意思我解释一下,id是主键,name是这条权限的名字,time是创建时间,由系统自动生成,url是url,method是访问方式。

然后比较关键的一点就来了,url存的时候将变量全部换成%,为什么这样呢,先看下我判断权限的sql:

[html]  view plain  copy
  1. <select id="selectByUrlAndMethod" resultMap="BaseResultMap" parameterType="java.lang.String">  
  2.     select *  
  3.     from STAFF_POWER  
  4.     <where>  
  5.         and STP_METHOD = #{method}  
  6.         and #{url} like STP_URL   
  7.     </where>  
  8.   </select>  
我用的mybatis。

权限拦截器的核心代码如下:

[java]  view plain  copy
  1. StaffPower power=powerSer.selectByUrlAndMethod(url, method);  
  2.         if (power!=null) {  
  3.             boolean isPass=role.getPowers()!=null && (","+role.getPowers()+",").contains(","+power.getStpId()+",");  
  4.             if (isPass==false) {  
  5.                 Result<String> result=new Result<String>(BaseRestController.ERROR, Code.ROLE_NO_PERMISSION, "您没有权限,请联系管理员");  
  6.                 PrintWriter pw=resp.getWriter();  
  7.                 pw.print(gson.toJson(result));  
  8.                 pw.flush();  
  9.                 pw.close();  
  10.                 return false;  
  11.             }  
  12.             return isPass;  
  13.         }else{  
  14.             log.error("没有这个权限   "+url+"  "+method);  
  15.             Result<String> result=new Result<String>(BaseRestController.ERROR, Code.PERMISSION_NO_EXIST, "该模块还没有设计权限,暂时不能操作");  
  16.             PrintWriter pw=resp.getWriter();  
  17.             pw.print(gson.toJson(result));  
  18.             pw.flush();  
  19.             pw.close();  
  20.             return false;  
  21.         }  


扫描二维码关注公众号,回复: 1587961 查看本文章

现在数据库中有这样一条权限:


我现在想看历史,于是访问 /check/api/sourceTp/3803140612558/history,然后sql是怎么执行的呢,下面是执行的结果:


[java]  view plain  copy
  1. [2017-05-11 10:09:54.400] - [DEBUG] [http-nio-8080-exec-9  :17561] ==>  Preparing: select * from STAFF_POWER WHERE STP_METHOD = ? and ? like STP_URL   
  2. [2017-05-11 10:09:54.400] - [DEBUG] [http-nio-8080-exec-9  :17561] ==> Parameters: GET(String), /check/api/sourceTp/3803140612558/history(String)  
  3. [2017-05-11 10:09:54.403] - [DEBUG] [http-nio-8080-exec-9  :17564] <==      Total: 1  

看到这里,它的原理应该就很清楚了,权限控制核心是url+method的判断,而rest的url比较特别从而导致无法像原来那样判断,于是我把所有的变量替换为%,而%是sql模糊查询的符号,所以就刚好可以借用sql的模糊查询来完成判断(中间不做任何处理)。

总结

判断的核心是url+method,但最最核心(而且好多人都没想到这种方法)的是使用%,%代表任意。

猜你喜欢

转载自blog.csdn.net/qq_38869854/article/details/80664834