Preface
Recent projects are written in a restful style. Sure enough, URLs are meaningful and functions can be inferred from urls. One of the biggest sensory differences between restful URLs and non-restful URLs is that there may be some variables in restful urls, such as the following: / check/api/user/12345/history, which is interpreted as: The url for viewing the history of the user whose account is 12345 instead of rest is: / check/api/user/history. Now, the problem is that the core of permission control is to judge the url of rest, but there are variables in the url of rest. So, how can reststyle projects achieve permission control?
Realization
In fact, before I write this article, my idea is to remove the variables of url, then save them in the privilege table, and then process the visited URL according to the same rules when judging, and then check in the database, if the delegate has privileges, otherwise No. But it turns out that this idea is only feasible at the end of the url.
First, I will paste the structure of the permission table, which is the core table of permission control.
I'll explain what each field means. id is the primary key, name is the name of this permission, time is the creation time, automatically generated by the system, URL is the url, method is the access method.-- Create table create table STAFF_POWER ( stp_id NUMBER not null, stp_name VARCHAR2(40), create_time TIMESTAMP(6), stp_url VARCHAR2(100), stp_method VARCHAR2(10) ) tablespace CHECK_ZS pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K next 1M minextents 1 maxextents unlimited ); -- Create/Recreate primary, unique and foreign key constraints alter table STAFF_POWER add constraint STP_PK primary key (STP_ID) using index tablespace CHECK_ZS pctfree 10 initrans 2 maxtrans 255 storage ( initial 64K next 1M minextents 1 maxextents unlimited ); alter table STAFF_POWER add constraint STP_UN unique (STP_URL, STP_METHOD) using index tablespace CHECK_ZS pctfree 10 initrans 2 maxtrans 255 storage ( initial 64K next 1M minextents 1 maxextents unlimited );
Then the key point comes. When url is stored, all variables are replaced. Why? Look at the sql of my jurisdiction first.
I use mybatis.<select id="selectByUrlAndMethod" resultMap="BaseResultMap" parameterType="java.lang.String"> select * from STAFF_POWER <where> and STP_METHOD = #{method} and #{url} like STP_URL </where> </select>
The core code of the privilege interceptor is as follows:
StaffPower power=powerSer.selectByUrlAndMethod(url, method); if (power!=null) { boolean isPass=role.getPowers()!=null && (","+role.getPowers()+",").contains(","+power.getStpId()+","); if (isPass==false) { Result<String> result=new Result<String>(BaseRestController.ERROR, Code.ROLE_NO_PERMISSION, "You do not have permission,Please contact the administrator"); PrintWriter pw=resp.getWriter(); pw.print(gson.toJson(result)); pw.flush(); pw.close(); return false; } return isPass; }else{ log.error("No permission "+url+" "+method); Result<String> result=new Result<String>(BaseRestController.ERROR, Code.PERMISSION_NO_EXIST, "The module has no design permission and can not be operated for the time being."); PrintWriter pw=resp.getWriter(); pw.print(gson.toJson(result)); pw.flush(); pw.close(); return false; }
There is now such a privilege in the database:
Now I want to look at history, so I visit / check/api/sourceTp/3803140612558/history, and then how does sql execute? Here is the result of execution:
[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 [2017-05-11 10:09:54.400] - [DEBUG] [http-nio-8080-exec-9 :17561] ==> Parameters: GET(String), /check/api/sourceTp/3803140612558/history(String) [2017-05-11 10:09:54.403] - [DEBUG] [http-nio-8080-exec-9 :17564] <== Total: 1
See here, its principle should be very clear, the core of authority control is the judgment of url+method, and rest's url is special, which makes it impossible to judge as before, so I replaced all variables with%, and% is the symbol of SQL fuzzy query, so we can just borrow sql's fuzzy query to complete the judgment.( No treatment is done in the middle.
summary
The core of judgment is url+method, but the most important (and many people did not think of this method) is use.