Repository navigation
Closed
Description
Preamble
As the soul user group grows larger and larger, enterprises attach importance to gateway configuration permissions. The
following is a list of added functions:
- Authentication for soul-admin login
- Menu permission control
- Single-page function button permission control
Preparations
- JWT (Json Web Token)
- Shiro
Program Logic
- Login logic
- The user name and password of the front-end POST are logged in to/login. If an encrypted token is returned, the logon page is redirected if the token fails.
- After that, you must add the X-Access-Token field to the header to Access each URL request that requires permissions. For example, X-Access-Token: token, the token is the key.
- Logic after successful login
- After the login is successful, the frontend sends a Token to the backend to request the user to use the resource interface. The backend obtains the user name from the token, retrieves the resource and returns it to the frontend.
Sequence Diagram of login and resource acquisition
User role permission table structure
- Use existing user tables.
- role table field description
| Field | Description |
|---|---|
| id | unique id |
| role_name | role name |
| description | description |
- user_role table field description
| Field | Description |
|---|---|
| id | unique id |
| user_id | unique user id |
| role_id | role unique id |
- resource table field description
| Field | Description |
|---|---|
| id | unique id |
| parent_id | parent menu id |
| title | menu name |
| name | frontend route name |
| url | the url used by frontend route |
| component | the name of frontend component |
| resource_type | resource type 0: main menu 1: submenu 2: function button |
| sort | menu display sorting |
| icon | menu usage icon |
| is_leaf | Entry recursion is judged by whether it is leaf or not |
| is_route | whether it is a route (extended use) 1 yes 0 no |
| perms | for example, sys:user:add/ sys:user:edit |
| status | data status 1 is valid and 0 is invalid |
- permission table structure
| Field | Description |
|---|---|
| id | unique id |
| objectId | role id or user id |
| permissionType | permission type ROLE role permission, USER user permission |
| resourceId | resource id |
Plan
- Role, basic permission data currently does not interact with the page, use SQL to insert the default data, and add later; However, the soul-admin backend provides the corresponding add, delete, modify, and query development interface
- Logon authentication control is preferred
- User permission menu acquisition and control
Recommendations
- Whether you need to provide certain permissions based on the time range for a single user but not for a role. eg: 2020-12-29 13:00:00~2020-12-29 14:00:00 a user has the new plug-in permission, and the timeout expires.
Reacted by Asxing , guojia1698, lahmxu, David Liu, Frank, MingHao Li, FocusZhouGD, hellboy0621 and Liming Deng
Reacted by Asxing
Reacted by Asxing
Reacted by Asxing
Reacted by Asxing


Activity
listart commentedon Dec 29, 2020
The menu is a kind of resource, which has the characteristics of tree structure and URI mapping. It is recommended to maintain it independently from the permission table. It is recommended to save the Instance-Level Access String directly with reference to shiro WildcardPermission in the permission table.
nuo-promise commentedon Dec 29, 2020
@yu199195 @dengliming What do you think?
nuo-promise commentedon Jan 11, 2021
soul-admin login authentication and page permission API documentation
HTTP/HTTPS message format
Overview
Request method
Request Header
Request parameters
GET
POST
Sample request parameters
{ "param1": "xxx", "param2":"xxx", ... }Response paramteters
Sample response parameters
{ "code": 200, "msg":"login success", "data":null/xxx }**
Login module
Login
Interface Type
Description
Request method
Request parameters
Sample request parameters
Success response parameter DashboardUserV0
Sample response parameters
{ "code": 200, "message": "login dashboard user success", "data": { "id": "1", "userName": "admin", "password": "jHcpKkiDbbQh7W7hh8yQSA==", "role": 1, "enabled": true, "token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NzI5MjYwMDMsInVzZXJuYW1lIjoiZGptIn0.nSJ1LPh6ZZ9gcjW5TG2XKA2ED7FasPygSOCf5dqHsL4", "dateCreated": "2018-06-23 15:12:22", "dateUpdated": "2020-11-24 12:59:12" } }Note
User module
Edit user features
Interface Type
Description
Request method
Request parameters
Sample request parameters
Success response parameter DashboardUserV0
Sample response parameters
{ "code": 200, "message": "detail success", "data": { "id": "1348274356818300928", "userName": "ding", "password": "1", "role": 1, "enabled": true, "dateCreated": "2021-01-10 22:23:51", "dateUpdated": "2021-01-10 22:30:27", "roles": [ { "id": "1347926115137064960", "roleName": "admin", "description": "管理员", "dateCreated": "2021-01-09 23:20:04", "dateUpdated": "2021-01-09 23:59:51" } ], "allRoles": [ { "id": "1347926115137064960", "roleName": "admin", "description": "管理员", "dateCreated": "2021-01-09 23:20:04", "dateUpdated": "2021-01-09 23:59:51" } ] } }Save user information after editing
Interface Type
Description
Request method
Request parameters
Sample request parameters
Response paramteters
Sample response parameters
{ "code": 200, "msg":"登录成功", "data":null/xxx }Role Management Module
Add roles
Interface Type
Description
Request method
Request parameters
Sample request parameters
{ "roleName":"admin", "description":"管理员角色" }Response paramteters
Sample response parameters
{ "message": "添加成功!", "code": 200, "data": 1, }View all roles
Interface Type
Description
Request method
Request parameters
Sample request parameters
{ "startPage":1, "pageSize":10 }Response paramteters
data entity CommonPager -> PageParameter
**
data entity CommonPager -> dataList -> data element
Sample response parameters
{ "message": "获取角色列表成功", "code": 200, "data": { "page": { "currentPage":1, "prePage":1, "nextPage":1, "pageSize":12, "offset":0, "totalPage":1, "totalCount":2 }, "dataList": [ { "id": "5dbfc02fb4c30b1cd789971f", "roleName": "super", "description": "内部角色", "dateCreated": "2019-11-04T14:07:43.452+0000", "dateUpdated": null }, { "id": "5dbfc0d4b4c30b1cd7899720", "roleName": "user", "description": "用户角色", "dateCreated": "2019-11-04T14:07:43.452+0000", "dateUpdated": null } ] } }Obtain the role list when adding a user
Interface Type
Description
Request method
Sample request parameters
Response paramteters
data entity List -> RoleVO
Sample response parameters
{ "message": "删除成功!", "code": 200, "data": [ { "id":"dsfsf", "roleName":"admin", "description":"管理员", "dateCreated":"2021-01-01 23:23:23", "dateUpdated":"2021-01-01 23:23:23" }, { "id":"dsfsf", "roleName":"admin1", "description":"管理员1", "dateCreated":"2021-01-01 23:23:23", "dateUpdated":"2021-01-01 23:23:23" } ] }View a role
Interface Type
Description
Request method
Request parameters
Sample request parameters
Response paramteters
data entity
**
data entity class - sysRole
data entity - allPermissionInfo
data entity - allPermissionInfo-treeList
Sample response parameters
{ "code": 200, "message": "detail success", "data": { "rolePermissionList": [], "sysRole": { "id": "1346358560427216896", "roleName": "super", "description": "超级管理员", "dateCreated": "2021-01-05 01:31:10", "dateUpdated": "2021-01-05 02:23:13" }, "allPermissionInfo": { "treeList": [ { "id": "1346775491550474240", "title": "SOUL.MENU.PLUGIN.LIST", "name": "plug", "children": [ { "id": "1347026381504262144", "title": "divide", "name": "divide", "children": [ { "id": "1347050493052071936", "title": "添加修改divide选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347026381504262144" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347026805170909184", "title": "hystrix", "name": "hystrix", "children": [ { "id": "1347051850521784320", "title": "添加修改hyxtrix选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347026805170909184" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347027413357572096", "title": "rewrite", "name": "rewrite", "children": [ { "id": "1347052833968631808", "title": "添加修改rewrite选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347027413357572096" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347027482244820992", "title": "springCloud", "name": "springCloud", "children": [ { "id": "1347053324018528256", "title": "添加修改springCloud选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347027482244820992" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347027526339538944", "title": "sign", "name": "sign", "children": [ { "id": "1347053363814084608", "title": "添加修改sign选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347027526339538944" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347027566034432000", "title": "waf", "name": "waf", "children": [ { "id": "1347053404050042880", "title": "添加修改waf选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347027566034432000" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347027647999520768", "title": "rate_limter", "name": "rate_limter", "children": [ { "id": "1347053442419535872", "title": "添加修改rate_limiter选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347027647999520768" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347027717792739328", "title": "dubbo", "name": "dubbo", "children": [ { "id": "1347053477844627456", "title": "添加修dubbo选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347027717792739328" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347027769747582976", "title": "monitor", "name": "monitor", "children": [ { "id": "1347053516423835648", "title": "添加修改monitor选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347027769747582976" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347027830602739712", "title": "sentinel", "name": "sentinel", "children": [ { "id": "1347053554310983680", "title": "添加修改sentinel选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347027830602739712" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347027918121086976", "title": "resilience4j", "name": "resilience4j", "children": [ { "id": "1347053595729735680", "title": "添加修改resilience4j选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347027918121086976" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347027995199811584", "title": "tars", "name": "tars", "children": [ { "id": "1347053631159021568", "title": "添加修改tars选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347027995199811584" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347028169120821248", "title": "context_path", "name": "context_path", "children": [ { "id": "1347053666227597312", "title": "添加修改context_path选择器按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1347028169120821248" } ], "isLeaf": false, "parentId": "1346775491550474240" }, { "id": "1347063567603609600", "title": "sofa", "name": "sofa", "children": null, "isLeaf": true, "parentId": "1346775491550474240" } ], "isLeaf": false, "parentId": "" }, { "id": "1346776175553376256", "title": "SOUL.MENU.SYSTEM.MANAGMENT", "name": "system", "children": [ { "id": "1346777157943259136", "title": "SOUL.MENU.SYSTEM.MANAGMENT.USER", "name": "manage", "children": [ { "id": "1347032308726902784", "title": "添加用户按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1346777157943259136" } ], "isLeaf": false, "parentId": "1346776175553376256" }, { "id": "1346777449787125760", "title": "SOUL.MENU.SYSTEM.MANAGMENT.PLUGIN", "name": "plugin", "children": [ { "id": "1347034027070337024", "title": "查询插件按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1346777449787125760" } ], "isLeaf": false, "parentId": "1346776175553376256" }, { "id": "1346777623011880960", "title": "SOUL.PLUGIN.PLUGINHANDLE", "name": "pluginhandle", "children": [ { "id": "1347047555588042752", "title": "查询插件处理按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1346777623011880960" } ], "isLeaf": false, "parentId": "1346776175553376256" }, { "id": "1346777766301888512", "title": "SOUL.MENU.SYSTEM.MANAGMENT.AUTHEN", "name": "auth", "children": [ { "id": "1347048004105940992", "title": "查询认证按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1346777766301888512" } ], "isLeaf": false, "parentId": "1346776175553376256" }, { "id": "1346777907096285184", "title": "SOUL.MENU.SYSTEM.MANAGMENT.METADATA", "name": "metadata", "children": [ { "id": "1347048968414179328", "title": "查询元数据按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1346777907096285184" } ], "isLeaf": false, "parentId": "1346776175553376256" }, { "id": "1346778036402483200", "title": "SOUL.MENU.SYSTEM.MANAGMENT.DICTIONARY", "name": "dict", "children": [ { "id": "1347049542417264640", "title": "查询字典按钮", "name": "", "children": null, "isLeaf": true, "parentId": "1346778036402483200" } ], "isLeaf": false, "parentId": "1346776175553376256" } ], "isLeaf": false, "parentId": "" } ], "permissionIds": [ "1346775491550474240", "1346776175553376256", "1346777157943259136", "1346777449787125760", "1346777623011880960", "1346777766301888512", "1346777907096285184", "1346778036402483200" ] } } }Delete a role
Interface Type
Description
Request method
Request parameters
Sample request parameters
Response paramteters
Sample response parameters
{ "message": "删除成功!", "code": 200, "data": 1 }Update roles
Interface Type
Description
Request method
Request parameters
Sample request parameters
{ "roleName":"super", "currentPermissionIds":[ "1346775491550474240", "1346776175553376256", "1346777157943259136", "1346777449787125760", "1346777623011880960", "1346777766301888512" ] }Response paramteters
Sample response parameters
{ "message": "编辑成功!", "code": 200, "data": 1, }Permission management module
Obtain menu permissions
Interface Type
Description
Request method
Request parameters
**
Sample request parameters
Response paramteters
data entity
data entity - allAuth/auth
data entity - menu
data entity - menu->meta
Sample response parameters
{ "code": 200, "message": "get menu and permission success", "data": { "menu": [ { "id": "1346776175553376256", "name": "system", "url": "/system", "component": "system", "meta": { "icon": "setting", "title": "SOUL.MENU.SYSTEM.MANAGMENT" }, "children": [ { "id": "1346777766301888512", "name": "auth", "url": "/system/auth", "component": "auth", "meta": { "icon": "", "title": "SOUL.MENU.SYSTEM.MANAGMENT.AUTHEN" }, "children": [], "sort": 3 }, { "id": "1346777157943259136", "name": "manage", "url": "/system/manage", "component": "manage", "meta": { "icon": "", "title": "SOUL.MENU.SYSTEM.MANAGMENT.USER" }, "children": [], "sort": 0 }, { "id": "1346777623011880960", "name": "pluginhandle", "url": "/system/pluginhandle", "component": "pluginhandle", "meta": { "icon": "", "title": "SOUL.PLUGIN.PLUGINHANDLE" }, "children": [], "sort": 2 }, { "id": "1346778036402483200", "name": "dict", "url": "/system/dict", "component": "dict", "meta": { "icon": "", "title": "SOUL.MENU.SYSTEM.MANAGMENT.DICTIONARY" }, "children": [], "sort": 5 }, { "id": "1346777449787125760", "name": "plugin", "url": "/system/plugin", "component": "plugin", "meta": { "icon": "", "title": "SOUL.MENU.SYSTEM.MANAGMENT.PLUGIN" }, "children": [], "sort": 1 }, { "id": "1346777907096285184", "name": "metadata", "url": "/system/metadata", "component": "metadata", "meta": { "icon": "", "title": "SOUL.MENU.SYSTEM.MANAGMENT.METADATA" }, "children": [], "sort": 4 } ], "sort": 1 } ], "currentAuth": [ { "perms": "plugin:dubboSelector:add", "description": "添加修dubbo选择器按钮" }, { "perms": "plugin:sofaSelector:delete", "description": "删除sofa选择器按钮" } ], "allAuth": [ { "perms": "system:manager:add", "description": "添加用户按钮" }, { "perms": "system:manager:list", "description": "查询用户按钮" } ] } }HessTina-YuI commentedon Jan 11, 2021
Client permission
Shiro configuration
Define shiro's white list
In application.yml
Using comma to split white list, like:
If you want to allow the same route to request server, like:
When token is error, the server will response:
{ "code": 600, "message": "token is error" }Define permission
For example:
In @RequiresPermissions, fill in permission. The format is @RequiresPermissions("xxx:xxx:xxx"), also @RequiresPermissions({"xxx:xxx:xxx", "yyy:yyy:yyy"})
When token has no permission, the server will response:
{ "code": 601, "message": "token has no permission" }JWT
org.dromara.soul.admin.utils.JwtUtils is JWT 的 tool class
In application.yml, to configurate attribute
Current stage, JwtUtils has two method.
Merge branch 'master' into apache#917
[#917] soul-admin Permission Complete (#998)
Merge branch 'apache#917' of https://github.com/nuo-promise/soul into a…