+iam缓存刷新即时生效方案优化
This commit is contained in:
parent
e9003ad3bc
commit
da9148943f
|
@ -26,10 +26,10 @@ MySQL、MariaDB、ORACLE、SQLServer、PostgreSQL
|
|||
以下依赖在引入diboot-core-starter依赖中,可以不再引入。
|
||||
:::
|
||||
* **javax.servlet-api**(javax.servlet:javax.servlet-api:4.0.1)
|
||||
* **spring-boot-starter-web**(org.springframework.boot:spring-boot-starter-web:2.2.1.RELEASE)
|
||||
* **spring-boot-starter-web**(org.springframework.boot:spring-boot-starter-web:2.2.4.RELEASE)
|
||||
* **mybatis-plus-boot-starter**(com.baomidou:mybatis-plus-boot-starter:3.2.0)
|
||||
* **commons-io**(commons-io:commons-io:2.6)
|
||||
* **commons-lang3**(org.apache.commons:commons-lang3:3.8.1)
|
||||
* **commons-lang3**(org.apache.commons:commons-lang3:3.9)
|
||||
* **fastjson**(com.alibaba:fastjson:1.2.60)
|
||||
|
||||
:::tip
|
||||
|
|
|
@ -44,6 +44,6 @@ public class ApiPermission implements Serializable {
|
|||
private String permissionCode;
|
||||
|
||||
public String buildUniqueKey(){
|
||||
return apiMethod + "," + apiUri + "," + permissionCode;
|
||||
return className + "," + apiMethod + "," + apiUri + "," + permissionCode;
|
||||
}
|
||||
}
|
|
@ -30,28 +30,39 @@ import java.util.Set;
|
|||
@Slf4j
|
||||
public class ApiPermissionExtractor {
|
||||
|
||||
/**
|
||||
* 接口权限缓存
|
||||
*/
|
||||
private static List<ApiPermissionWrapper> API_PERMISSION_CACHE = null;
|
||||
/**
|
||||
* 唯一KEY
|
||||
*/
|
||||
private static Set<String> UNIQUE_KEY_SET = null;
|
||||
|
||||
/**
|
||||
* 提取所有的权限定义
|
||||
* @return
|
||||
*/
|
||||
public static List<ApiPermissionWrapper> extractAllApiPermissions(){
|
||||
List<ApiPermissionWrapper> apiPermissionWrappers = new ArrayList<>();
|
||||
if(API_PERMISSION_CACHE == null){
|
||||
API_PERMISSION_CACHE = new ArrayList<>();
|
||||
UNIQUE_KEY_SET = new HashSet<>();
|
||||
// 初始化
|
||||
// 提取rest controller
|
||||
List<Object> controllerList = ContextHelper.getBeansByAnnotation(RestController.class);
|
||||
extractApiPermissions(controllerList, apiPermissionWrappers);
|
||||
extractApiPermissions(controllerList);
|
||||
// 提取controller
|
||||
controllerList = ContextHelper.getBeansByAnnotation(Controller.class);
|
||||
extractApiPermissions(controllerList, apiPermissionWrappers);
|
||||
// 缓存抓取结果
|
||||
return apiPermissionWrappers;
|
||||
extractApiPermissions(controllerList);
|
||||
}
|
||||
return API_PERMISSION_CACHE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取permission
|
||||
* @param controllerList
|
||||
* @param apiPermissionWrappers
|
||||
*/
|
||||
private static void extractApiPermissions(List<Object> controllerList, List<ApiPermissionWrapper> apiPermissionWrappers){
|
||||
private static void extractApiPermissions(List<Object> controllerList){
|
||||
if(V.notEmpty(controllerList)) {
|
||||
for (Object obj : controllerList) {
|
||||
Class controllerClass = AopUtils.getTargetClass(obj);
|
||||
|
@ -80,7 +91,7 @@ public class ApiPermissionExtractor {
|
|||
ApiPermissionWrapper wrapper = new ApiPermissionWrapper(title);
|
||||
buildApiPermissionsInClass(wrapper, controllerClass, codePrefix);
|
||||
if(V.notEmpty(wrapper.getChildren())){
|
||||
apiPermissionWrappers.add(wrapper);
|
||||
API_PERMISSION_CACHE.add(wrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +112,6 @@ public class ApiPermissionExtractor {
|
|||
List<Method> annoMethods = AnnotationUtils.extractAnnotationMethods(controllerClass, BindPermission.class);
|
||||
if(V.notEmpty(annoMethods)){
|
||||
List<ApiPermission> apiPermissions = new ArrayList<>();
|
||||
Set<String> existKey = new HashSet<>();
|
||||
for(Method method : annoMethods){
|
||||
// 忽略私有方法
|
||||
if(Modifier.isPrivate(method.getModifiers())){
|
||||
|
@ -121,14 +131,14 @@ public class ApiPermissionExtractor {
|
|||
if(bindPermission != null){
|
||||
String permissionCode = (codePrefix != null)? codePrefix+":"+bindPermission.code() : bindPermission.code();
|
||||
// 提取请求url-permission code的关系
|
||||
buildApiPermission(apiPermissions, controllerClass, urlPrefix, wrapper.getClassTitle(), permissionCode, methodAndUrl, bindPermission.name(), existKey);
|
||||
buildApiPermission(apiPermissions, controllerClass, urlPrefix, wrapper.getClassTitle(), permissionCode, methodAndUrl, bindPermission.name());
|
||||
}
|
||||
// 处理RequirePermissions注解
|
||||
else if(requiresPermissions != null){
|
||||
String[] permissionCodes = requiresPermissions.value();
|
||||
for(String permissionCode : permissionCodes){
|
||||
// 提取请求url-permission code的关系
|
||||
buildApiPermission(apiPermissions, controllerClass, urlPrefix, wrapper.getClassTitle(), permissionCode, methodAndUrl, null, existKey);
|
||||
buildApiPermission(apiPermissions, controllerClass, urlPrefix, wrapper.getClassTitle(), permissionCode, methodAndUrl, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +160,7 @@ public class ApiPermissionExtractor {
|
|||
* @param apiName
|
||||
*/
|
||||
private static void buildApiPermission(List<ApiPermission> apiPermissions, Class controllerClass, String urlPrefix, String title,
|
||||
String permissionCode, String[] methodAndUrl, String apiName, Set<String> existKey){
|
||||
String permissionCode, String[] methodAndUrl, String apiName){
|
||||
String requestMethod = methodAndUrl[0], url = methodAndUrl[1];
|
||||
for(String m : requestMethod.split(Cons.SEPARATOR_COMMA)){
|
||||
for(String u : url.split(Cons.SEPARATOR_COMMA)){
|
||||
|
@ -158,18 +168,18 @@ public class ApiPermissionExtractor {
|
|||
for(String path : urlPrefix.split(Cons.SEPARATOR_COMMA)){
|
||||
ApiPermission apiPermission = new ApiPermission().setClassName(controllerClass.getName()).setClassTitle(title);
|
||||
apiPermission.setApiMethod(m).setApiName(apiName).setApiUri(path + u).setPermissionCode(permissionCode).setValue(m + ":" + path + u);
|
||||
if(!existKey.contains(apiPermission.buildUniqueKey())){
|
||||
if(!UNIQUE_KEY_SET.contains(apiPermission.buildUniqueKey())){
|
||||
apiPermissions.add(apiPermission);
|
||||
existKey.add(apiPermission.buildUniqueKey());
|
||||
UNIQUE_KEY_SET.add(apiPermission.buildUniqueKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
ApiPermission apiPermission = new ApiPermission().setClassName(controllerClass.getName()).setClassTitle(title);
|
||||
apiPermission.setApiMethod(m).setApiName(apiName).setApiUri(u).setPermissionCode(permissionCode);
|
||||
if(!existKey.contains(apiPermission.buildUniqueKey())){
|
||||
if(!UNIQUE_KEY_SET.contains(apiPermission.buildUniqueKey())){
|
||||
apiPermissions.add(apiPermission);
|
||||
existKey.add(apiPermission.buildUniqueKey());
|
||||
UNIQUE_KEY_SET.add(apiPermission.buildUniqueKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,9 @@ import com.diboot.iam.entity.IamAccount;
|
|||
import com.diboot.iam.entity.IamRole;
|
||||
import com.diboot.iam.service.IamRolePermissionService;
|
||||
import com.diboot.iam.service.IamUserRoleService;
|
||||
import com.diboot.iam.util.IamSecurityUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
|
@ -89,6 +91,8 @@ public class BaseJwtRealm extends AuthorizingRealm {
|
|||
if(userObject == null){
|
||||
throw new AuthenticationException("用户不存在");
|
||||
}
|
||||
// 清空当前用户缓存
|
||||
this.clearCachedAuthorizationInfo(IamSecurityUtils.getSubject().getPrincipals());
|
||||
return new SimpleAuthenticationInfo(userObject, jwtToken.getCredentials(), this.getName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,4 +36,12 @@ public interface IamAccountService extends BaseIamService<IamAccount> {
|
|||
*/
|
||||
boolean changePwd(ChangePwdDTO changePwdDTO, IamAccount iamAccount) throws Exception;
|
||||
|
||||
/**
|
||||
* 获取认证账号username
|
||||
* @param userType
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
String getAuthAccount(String userType, Long userId);
|
||||
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package com.diboot.iam.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.diboot.core.exception.BusinessException;
|
||||
import com.diboot.core.util.V;
|
||||
import com.diboot.core.vo.Status;
|
||||
|
@ -60,7 +62,6 @@ public class IamAccountServiceImpl extends BaseIamServiceImpl<IamAccountMapper,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean changePwd(ChangePwdDTO changePwdDTO, IamAccount iamAccount) throws Exception {
|
||||
// 验证账号信息是否存在
|
||||
|
@ -88,4 +89,15 @@ public class IamAccountServiceImpl extends BaseIamServiceImpl<IamAccountMapper,
|
|||
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthAccount(String userType, Long userId) {
|
||||
LambdaQueryWrapper<IamAccount> queryWrapper = new QueryWrapper<IamAccount>().lambda()
|
||||
.select(IamAccount::getAuthAccount)
|
||||
.eq(IamAccount::getUserType, userType)
|
||||
.eq(IamAccount::getUserId, userId);
|
||||
IamAccount account = getSingleEntity(queryWrapper);
|
||||
return account!=null? account.getAuthAccount() : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.diboot.iam.mapper.IamRolePermissionMapper;
|
|||
import com.diboot.iam.service.IamFrontendPermissionService;
|
||||
import com.diboot.iam.service.IamRolePermissionService;
|
||||
import com.diboot.iam.service.IamRoleService;
|
||||
import com.diboot.iam.util.IamSecurityUtils;
|
||||
import com.diboot.iam.vo.IamFrontendPermissionVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -78,7 +79,9 @@ public class IamRolePermissionServiceImpl extends BaseIamServiceImpl<IamRolePerm
|
|||
IamRolePermission rolePermission = new IamRolePermission(roleId, permissionId);
|
||||
rolePermissionList.add(rolePermission);
|
||||
}
|
||||
return createEntities(rolePermissionList);
|
||||
boolean success = createEntities(rolePermissionList);
|
||||
IamSecurityUtils.clearAllAuthorizationCache();
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -95,9 +98,12 @@ public class IamRolePermissionServiceImpl extends BaseIamServiceImpl<IamRolePerm
|
|||
IamRolePermission rolePermission = new IamRolePermission(roleId, permissionId);
|
||||
rolePermissionList.add(rolePermission);
|
||||
}
|
||||
return createEntities(rolePermissionList);
|
||||
boolean success = createEntities(rolePermissionList);
|
||||
IamSecurityUtils.clearAllAuthorizationCache();
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IamRoleService getRoleService() {
|
||||
return iamRoleService;
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.diboot.iam.entity.IamRole;
|
|||
import com.diboot.iam.entity.IamUserRole;
|
||||
import com.diboot.iam.exception.PermissionException;
|
||||
import com.diboot.iam.mapper.IamUserRoleMapper;
|
||||
import com.diboot.iam.service.IamAccountService;
|
||||
import com.diboot.iam.service.IamRoleService;
|
||||
import com.diboot.iam.service.IamUserRoleService;
|
||||
import com.diboot.iam.util.IamSecurityUtils;
|
||||
|
@ -19,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
@ -38,7 +40,10 @@ public class IamUserRoleServiceImpl extends BaseIamServiceImpl<IamUserRoleMapper
|
|||
private IamUserRoleMapper iamUserRoleMapper;
|
||||
@Autowired
|
||||
private IamRoleService iamRoleService;
|
||||
@Autowired
|
||||
private IamAccountService iamAccountService;
|
||||
|
||||
// 扩展接口
|
||||
private IamExtensible iamExtensible;
|
||||
private boolean iamExtensibleImplChecked = false;
|
||||
|
||||
|
@ -73,13 +78,21 @@ public class IamUserRoleServiceImpl extends BaseIamServiceImpl<IamUserRoleMapper
|
|||
if(superAdminRoleId != null && superAdminRoleId.equals(entity.getRoleId())){
|
||||
checkSuperAdminIdentity();
|
||||
}
|
||||
return super.createEntity(entity);
|
||||
boolean success = super.createEntity(entity);
|
||||
if(success){
|
||||
// 清空缓存
|
||||
clearUserAuthCache(entity.getUserType(), entity.getUserId());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = {Exception.class})
|
||||
public boolean createEntities(Collection entityList) {
|
||||
if (V.notEmpty(entityList)) {
|
||||
if (V.isEmpty(entityList)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Long superAdminRoleId = getSuperAdminRoleId();
|
||||
boolean hasSuperAdmin = false;
|
||||
for(Object entity : entityList){
|
||||
|
@ -91,8 +104,13 @@ public class IamUserRoleServiceImpl extends BaseIamServiceImpl<IamUserRoleMapper
|
|||
if(hasSuperAdmin){
|
||||
checkSuperAdminIdentity();
|
||||
}
|
||||
boolean success = super.createEntities(entityList);
|
||||
if(success){
|
||||
// 清空用户缓存
|
||||
IamUserRole entity = ((List<IamUserRole>) entityList).get(0);
|
||||
clearUserAuthCache(entity.getUserType(), entity.getUserId());
|
||||
}
|
||||
return super.createEntities(entityList);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -110,7 +128,12 @@ public class IamUserRoleServiceImpl extends BaseIamServiceImpl<IamUserRoleMapper
|
|||
for(Long roleId : roleIds){
|
||||
entityList.add(new IamUserRole(userType, userId, roleId));
|
||||
}
|
||||
return super.createEntities(entityList);
|
||||
boolean success = super.createEntities(entityList);
|
||||
if(success){
|
||||
// 清空用户缓存
|
||||
clearUserAuthCache(userType, userId);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -148,7 +171,12 @@ public class IamUserRoleServiceImpl extends BaseIamServiceImpl<IamUserRoleMapper
|
|||
for(Long roleId : roleIds){
|
||||
entityList.add(new IamUserRole(userType, userId, roleId));
|
||||
}
|
||||
return super.createEntities(entityList);
|
||||
boolean success = super.createEntities(entityList);
|
||||
if(success){
|
||||
// 清空用户缓存
|
||||
clearUserAuthCache(userType, userId);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -176,4 +204,17 @@ public class IamUserRoleServiceImpl extends BaseIamServiceImpl<IamUserRoleMapper
|
|||
throw new PermissionException("非超级管理员用户不可授予其他用户超级管理员权限!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空用户的认证缓存,以便权限变化及时生效
|
||||
* @param userType
|
||||
* @param userId
|
||||
*/
|
||||
private void clearUserAuthCache(String userType, Long userId){
|
||||
String username = iamAccountService.getAuthAccount(userType, userId);
|
||||
if(V.notEmpty(username)){
|
||||
IamSecurityUtils.clearAuthorizationCache(username);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import org.springframework.core.env.Environment;
|
|||
public class IamBasePluginManager implements PluginManager {
|
||||
|
||||
// 验证SQL
|
||||
private static final String VALIDATE_SQL = "SELECT id FROM ${SCHEMA}.iam_permission WHERE id=0";
|
||||
private static final String VALIDATE_SQL = "SELECT id FROM ${SCHEMA}.iam_role WHERE id=0";
|
||||
|
||||
public void initPlugin(IamBaseProperties iamBaseProperties){
|
||||
// 检查数据库字典是否已存在
|
||||
|
|
|
@ -4,8 +4,13 @@ import com.diboot.core.util.S;
|
|||
import com.diboot.core.util.V;
|
||||
import com.diboot.iam.config.Cons;
|
||||
import com.diboot.iam.entity.IamAccount;
|
||||
import com.diboot.iam.jwt.BaseJwtRealm;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.AuthorizationInfo;
|
||||
import org.apache.shiro.cache.Cache;
|
||||
import org.apache.shiro.crypto.hash.SimpleHash;
|
||||
import org.apache.shiro.mgt.RealmSecurityManager;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.util.ByteSource;
|
||||
|
||||
|
@ -17,6 +22,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||
* @version v2.0
|
||||
* @date 2019/12/26
|
||||
*/
|
||||
@Slf4j
|
||||
public class IamSecurityUtils extends SecurityUtils {
|
||||
|
||||
/**
|
||||
|
@ -47,6 +53,38 @@ public class IamSecurityUtils extends SecurityUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空指定用户账户的权限信息的缓存 使其立即生效
|
||||
*/
|
||||
public static void clearAuthorizationCache(String username){
|
||||
RealmSecurityManager rsm = (RealmSecurityManager) IamSecurityUtils.getSecurityManager();
|
||||
BaseJwtRealm baseJwtRealm = (BaseJwtRealm)rsm.getRealms().iterator().next();
|
||||
if(baseJwtRealm != null){
|
||||
Cache<Object, AuthorizationInfo> cache = baseJwtRealm.getAuthorizationCache();
|
||||
if(cache != null) {
|
||||
cache.remove(username);
|
||||
log.debug("已清空账号 {} 的权限缓存,以便新权限生效.", username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空所有权限信息的缓存 使其立即生效
|
||||
*/
|
||||
public static void clearAllAuthorizationCache(){
|
||||
RealmSecurityManager rsm = (RealmSecurityManager) IamSecurityUtils.getSecurityManager();
|
||||
BaseJwtRealm baseJwtRealm = (BaseJwtRealm)rsm.getRealms().iterator().next();
|
||||
if(baseJwtRealm != null){
|
||||
Cache<Object, AuthorizationInfo> cache = baseJwtRealm.getAuthorizationCache();
|
||||
if(cache != null) {
|
||||
for(Object key : cache.keys()) {
|
||||
cache.remove(key);
|
||||
}
|
||||
log.debug("已清空全部登录用户的权限缓存,以便新权限生效.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* 对用户密码加密
|
||||
* @param iamAccount
|
||||
|
|
|
@ -41,7 +41,7 @@ create unique index idx_iam_account on iam_account(auth_account, auth_type, user
|
|||
-- 角色表
|
||||
create table iam_role
|
||||
(
|
||||
id int auto_increment comment 'ID' primary key,
|
||||
id bigint auto_increment comment 'ID' primary key,
|
||||
name varchar(20) not null comment '名称',
|
||||
code varchar(20) not null comment '编码',
|
||||
description varchar(100) null comment '备注',
|
||||
|
@ -52,42 +52,39 @@ create table iam_role
|
|||
-- 用户角色表
|
||||
create table iam_user_role
|
||||
(
|
||||
id int auto_increment comment 'ID' primary key,
|
||||
id bigint auto_increment comment 'ID' primary key,
|
||||
user_type varchar(100) default 'IamUser' not null comment '用户类型',
|
||||
user_id bigint not null comment '用户ID',
|
||||
role_id int not null comment '角色ID',
|
||||
role_id bigint not null comment '角色ID',
|
||||
is_deleted tinyint(1) default 0 not null comment '是否删除',
|
||||
create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间'
|
||||
)AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8 COMMENT '用户角色关联';
|
||||
-- 索引
|
||||
create index idx_iam_user_role on iam_user_role (user_type, user_id);
|
||||
|
||||
-- 权限表
|
||||
create table iam_permission
|
||||
-- 前端资源权限表
|
||||
create table iam_frontend_permission
|
||||
(
|
||||
id int auto_increment comment 'ID' primary key,
|
||||
parent_id int default 0 not null comment '上级ID',
|
||||
application varchar(50) default 'MS' not null comment '所属应用',
|
||||
type varchar(10) default 'MENU' not null comment '权限类别',
|
||||
name varchar(20) not null comment '名称',
|
||||
code varchar(50) null comment '编码',
|
||||
operation_name varchar(50) null comment '操作名称',
|
||||
operation_code varchar(50) null comment '操作编码',
|
||||
sort_id smallint(6) default 999 not null comment '排序号',
|
||||
extdata varchar(100) null comment '扩展属性',
|
||||
id bigint auto_increment comment 'ID' primary key,
|
||||
parent_id bigint default 0 not null comment '父级菜单',
|
||||
display_type varchar(20) not null comment '展现类型',
|
||||
display_name varchar(100) not null comment '显示名称',
|
||||
frontend_code varchar(100) not null comment '前端编码',
|
||||
api_set varchar(5120) null comment '接口列表',
|
||||
is_deleted tinyint(1) default 0 not null comment '是否删除',
|
||||
create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间',
|
||||
update_time timestamp null on update CURRENT_TIMESTAMP comment '更新时间'
|
||||
)AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8 COMMENT '权限';
|
||||
)AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8 COMMENT '前端菜单';
|
||||
|
||||
-- 索引
|
||||
create index idx_iam_permission on iam_permission (code);
|
||||
create index idx_iam_frontend_permission on iam_frontend_permission (parent_id);
|
||||
|
||||
-- 角色-权限
|
||||
create table iam_role_permission
|
||||
(
|
||||
id int auto_increment comment 'ID' primary key,
|
||||
role_id int not null comment '角色ID',
|
||||
permission_id int not null comment '权限ID',
|
||||
id bigint auto_increment comment 'ID' primary key,
|
||||
role_id bigint not null comment '角色ID',
|
||||
permission_id bigint not null comment '权限ID',
|
||||
is_deleted tinyint(1) default 0 not null comment '是否删除',
|
||||
create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间'
|
||||
)AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8 COMMENT '角色权限';
|
||||
|
|
Loading…
Reference in New Issue