springBoot+springSecurity 数据库动态管理用户、角色、权限
使用spring Security3的四种方法概述
那么在Spring Security3的使用中,有4种方法:
一种是全部利用配置文件,将用户、权限、资源(url)硬编码在xml文件中,已经实现过,并经过验证;
二种是用户和权限用数据库存储,而资源(url)和权限的对应采用硬编码配置,目前这种方式已经实现,并经过验证。
三种是细分角色和权限,并将用户、角色、权限和资源均采用数据库存储,并且自定义过滤器,代替原有的FilterSecurityInterceptor过滤器,
并分别实现AccessDecisionManager、InvocationSecurityMetadataSourceService和UserDetailsService,并在配置文件中进行相应配置。
目前这种方式已经实现,并经过验证。
http://blog.csdn.net/woshisap/article/details/7250428
添加 Spring Security 配置类
添加spring security到我们应用中第一步是要创建Spring Security Java 配置类。
这个配置创建一个叫springSecurityFilterChain的Servlet过滤器,来对我们应用中所有的安全相关的事项(保护应用的所有url,验证用户名密码,表单重定向等)负责。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter {@AutowiredCustomSuccessHandler customSuccessHandler;@Autowiredpublic void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("USER");auth.inMemoryAuthentication().withUser("admin").password("root123").roles("ADMIN");auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/", "/home").access("hasRole('USER')").antMatchers("/admin/**").access("hasRole('ADMIN')").antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')").and().formLogin().loginPage("/login").successHandler(customSuccessHandler).usernameParameter("ssoId").passwordParameter("password").and().csrf().and().exceptionHandling().accessDeniedPage("/Access_Denied");}}
http://www.2cto.com/kf/201605/506019.html
序:
本文使用springboot+mybatis+SpringSecurity 实现数据库动态的管理用户、角色、权限管理
本文细分角色和权限,并将用户、角色、权限和资源均采用数据库存储,并且自定义滤器,代替原有的FilterSecurityInterceptor过滤器,
并分别实现AccessDecisionManager、InvocationSecurityMetadataSourceService和UserDetailsService,并在配置文件中进行相应配置。
spring security的简单原理:
使用众多的拦截器对url拦截,以此来管理权限。但是这么多拦截器,笔者不可能对其一一来讲,主要讲里面核心流程的两个。
首先,权限管理离不开登陆验证的,所以登陆验证拦截器AuthenticationProcessingFilter要讲;
还有就是对访问的资源管理吧,所以资源管理拦截器AbstractSecurityInterceptor要讲;
但拦截器里面的实现需要一些组件来实现,所以就有了AuthenticationManager、accessDecisionManager等组件来支撑。
现在先大概过一遍整个流程,
用户登陆,会被AuthenticationProcessingFilter拦截(即认证管理),调用AuthenticationManager的实现,而且AuthenticationManager会调用ProviderManager来获取用户验证信息(不同的Provider调用的服务不同,因为这些信息可以是在数据库上,可以是在LDAP服务器上,可以是xml配置文件上等),
如果验证通过后会将用户的权限信息封装一个User放到spring的全局缓存SecurityContextHolder中,以备后面访问资源时使用。
访问资源(即授权管理),访问url时,会通过AbstractSecurityInterceptor拦截器拦截,
其中会调用FilterInvocationSecurityMetadataSource的方法来获取被拦截url所需的全部权限,
在调用授权管理器AccessDecisionManager,这个授权管理器会通过spring的全局缓存SecurityContextHolder获取用户的权限信息,还会获取被拦截的url和被拦截url所需的全部权限,然后根据所配的策略(有:一票决定,一票否定,少数服从多数等),如果权限足够,则返回,权限不够则报错并调用权限不足页面。
http://blog.csdn.net/u013412066/article/details/50667960
重要
本文设计和代码是基于 上一篇博客(请点击)
springboot+mybatis+SpringSecurity 实现用户角色数据库管理
进行修改。
本文目录:
1:数据库表设计
2:权限表的业务
3:springSecurity 配置修改
4:修改home.html 文件
5:修改HomeController.Java 文件
6:测试检验
目录结构如下:
1:数据库表设计
由于本文增加了权限表所以本文的数据库表为5个分别是: 用户表、角色表、权限表、用户角色中间表、角色权限中间表
初始化数据
注意:Sys_permission 表的url通配符为两颗星,比如说 /user下的所有url,应该写成 /user/**;权限的名字可以随意起名
DROP TABLE IF EXISTS `Sys_User`; CREATE TABLE `Sys_User`(`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,`username` VARCHAR(200) NOT NULL,`password` VARCHAR(200) NOT NULL,PRIMARY KEY (`id`) ) ENGINE=INNODB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;DROP TABLE IF EXISTS `Sys_Role`; CREATE TABLE `Sys_Role`( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(200) NOT NULL,PRIMARY KEY (`id`) ) ENGINE=INNODB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;DROP TABLE IF EXISTS `Sys_permission`; CREATE TABLE `Sys_permission`(`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,`name` VARCHAR(200) NOT NULL,`description` VARCHAR(200) DEFAULT NULL,`url` VARCHAR(200) NOT NULL,`pid` BIGINT DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=INNODB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;DROP TABLE IF EXISTS `Sys_role_user`; CREATE TABLE `Sys_role_user`(`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,`sys_user_id` BIGINT UNSIGNED NOT NULL,`sys_role_id` BIGINT UNSIGNED NOT NULL,PRIMARY KEY (`id`) ) ENGINE=INNODB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;DROP TABLE IF EXISTS `Sys_permission_role`; CREATE TABLE `Sys_permission_role`(`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,`role_id` BIGINT UNSIGNED NOT NULL,`permission_id` BIGINT UNSIGNED NOT NULL,PRIMARY KEY (`id`) ) ENGINE=INNODB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;insert into SYS_USER (id,username, password) values (1,'admin', 'admin'); insert into SYS_USER (id,username, password) values (2,'abel', 'abel');insert into SYS_ROLE(id,name) values(1,'ROLE_ADMIN'); insert into SYS_ROLE(id,name) values(2,'ROLE_USER');insert into SYS_ROLE_USER(SYS_USER_ID,sys_role_id) values(1,1); insert into SYS_ROLE_USER(SYS_USER_ID,sys_role_id) values(2,2);INSERT INTO `Sys_permission` VALUES ('1', 'ROLE_HOME', 'home', '/', null), ('2', 'ROLE_ADMIN', 'ABel', '/admin', null); INSERT INTO `Sys_permission_role` VALUES ('1', '1', '1'), ('2', '1', '2'), ('3', '2', '1');
2:权限表的业务代码
2.1 java bean
Permission.java
package com.us.example.domain;/*** Created by yangyibo on 17/1/20.*/
public class Permission { private int id; //权限名称 private String name; //权限描述 private String descritpion; //授权链接 private String url; //父节点id private int pid; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescritpion() { return descritpion; } public void setDescritpion(String descritpion) { this.descritpion = descritpion; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public int getPid() { return pid; } public void setPid(int pid) { this.pid = pid; } }
2.2 dao 层
在 com.us.example.dao 包下新建PermissionDao.java 文件。
PermissionDao.java
package com.us.example.dao;
import com.us.example.config.MyBatisRepository;
import com.us.example.domain.Permission;
import java.util.List;/** * Created by yangyibo on 17/1/20. */ public interface PermissionDao { public List<Permission> findAll(); public List<Permission> findByAdminUserId(int userId); }
在src/resource/mapper目录下新建对应的mapper.xml 文件
PermissionDaoMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.us.example.dao.PermissionDao"> <select id="findAll" resultType="com.us.example.domain.Permission"> SELECT * from Sys_permission ; </select> <select id="findByAdminUserId" parameterType="int" resultType="com.us.example.domain.Permission"> select p.* from Sys_User u LEFT JOIN sys_role_user sru on u.id= sru.Sys_User_id LEFT JOIN Sys_Role r on sru.Sys_Role_id=r.id LEFT JOIN Sys_permission_role spr on spr.role_id=r.id LEFT JOIN Sys_permission p on p.id =spr.permission_id where u.id=#{userId} </select> </mapper>
3:springSecurity 配置修改
3.1 修改 WebSecurityConfig.java
修改com.us.example.config包下的 WebSecurityConfig.java 文件如下:
package com.us.example.config; import com.us.example.service.CustomUserService; import com.us.example.service.MyFilterSecurityInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; /** * Created by yangyibo on 17/1/18. */ @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private MyFilterSecurityInterceptor myFilterSecurityInterceptor; @Bean UserDetailsService customUserService(){ //注册UserDetailsService 的bean return new CustomUserService(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customUserService()); //user Details Service验证 } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() //任何请求,登录后可以访问 .and() .formLogin() .loginPage("/login") .failureUrl("/login?error") .permitAll() //登录页面用户任意访问 .and() .logout().permitAll(); //注销行为任意访问 http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class); } }
3.2 修改CustomUserService
修改CustomUserService.java 内容如下:
package com.us.example.service; import com.us.example.dao.PermissionDao; import com.us.example.dao.UserDao; import com.us.example.domain.Permission; import com.us.example.domain.SysRole; import com.us.example.domain.SysUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; /** * Created by yangyibo on 17/1/18. */ @Service public class CustomUserService implements UserDetailsService { //自定义UserDetailsService 接口 @Autowired UserDao userDao; @Autowired PermissionDao permissionDao; public UserDetails loadUserByUsername(String username) { SysUser user = userDao.findByUserName(username); if (user != null) { List<Permission> permissions = permissionDao.findByAdminUserId(user.getId()); List<GrantedAuthority> grantedAuthorities = new ArrayList <>(); for (Permission permission : permissions) { if (permission != null && permission.getName()!=null) { GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName()); //1:此处将权限信息添加到 GrantedAuthority 对象中,在后面进行全权限验证时会使用GrantedAuthority 对象。 grantedAuthorities.add(grantedAuthority); } } return new User(user.getUsername(), user.getPassword(), grantedAuthorities); } else { throw new UsernameNotFoundException("admin: " + username + " do not exist!"); } } }
3.3 新增MyAccessDecisionManager
在com.us.example.service 包下新增
MyAccessDecisionManager.java 文件
package com.us.example.service;import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Service; import java.util.Collection; import java.util.Iterator; /** * Created by yangyibo on 17/1/19. */ @Service public class MyAccessDecisionManager implements AccessDecisionManager { // decide 方法是判定是否拥有权限的决策方法, //authentication 是释CustomUserService中循环添加到 GrantedAuthority 对象中的权限信息集合. //object 包含客户端发起的请求的requset信息,可转换为 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest(); //configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果,此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。 @Override public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if(null== configAttributes || configAttributes.size() <=0) { return; } ConfigAttribute c; String needRole; for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) { c = iter.next(); needRole = c.getAttribute(); for(GrantedAuthority ga : authentication.getAuthorities()) {//authentication 为在注释1 中循环添加到 GrantedAuthority 对象中的权限信息集合 if(needRole.trim().equals(ga.getAuthority())) { return; } } } throw new AccessDeniedException("no right"); } @Override public boolean supports(ConfigAttribute attribute) { return true; } @Override public boolean supports(Class<?> clazz) { return true; } }
3.4 新增 MyFilterSecurityInterceptor
在com.us.example.service 包下新增
MyFilterSecurityInterceptor.java 文件
package com.us.example.service;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.SecurityMetadataSource; import org.springframework.security.access.intercept.AbstractSecurityInterceptor; import org.springframework.security.access.intercept.InterceptorStatusToken; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.stereotype.Service; import java.io.IOException; /** * Created by yangyibo on 17/1/19. */ @Service public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter { @Autowired private FilterInvocationSecurityMetadataSource securityMetadataSource; @Autowired public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) { super.setAccessDecisionManager(myAccessDecisionManager); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { FilterInvocation fi = new FilterInvocation(request, response, chain); invoke(fi); } public void invoke(FilterInvocation fi) throws IOException, ServletException { //fi里面有一个被拦截的url //里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限 //再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够 InterceptorStatusToken token = super.beforeInvocation(fi); try { //执行下一个拦截器 fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } finally { super.afterInvocation(token, null); } } @Override public void destroy() { } @Override public Class<?> getSecureObjectClass() { return FilterInvocation.class; } @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return this.securityMetadataSource; } }
3.5 新增 MyInvocationSecurityMetadataSourceService
在com.us.example.service 包下新增MyInvocationSecurityMetadataSourceService.java文件
package com.us.example.service;import com.us.example.dao.PermissionDao;
import com.us.example.domain.Permission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import java.util.*; /** * Created by yangyibo on 17/1/19. */ @Service public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource { @Autowired private PermissionDao permissionDao; private HashMap<String, Collection<ConfigAttribute>> map =null; /** * 加载权限表中所有权限 */ public void loadResourceDefine(){ map = new HashMap<>(); Collection<ConfigAttribute> array; ConfigAttribute cfg; List<Permission> permissions = permissionDao.findAll(); for(Permission permission : permissions) { array = new ArrayList<>(); cfg = new SecurityConfig(permission.getName()); //此处只添加了用户的名字,其实还可以添加更多权限的信息,例如请求方法到ConfigAttribute的集合中去。此处添加的信息将会作为MyAccessDecisionManager类的decide的第三个参数。 array.add(cfg); //用权限的getUrl() 作为map的key,用ConfigAttribute的集合作为 value, map.put(permission.getUrl(), array); } } //此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。 @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { if(map ==null) loadResourceDefine(); //object 中包含用户请求的request 信息 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest(); AntPathRequestMatcher matcher; String resUrl; for(Iterator<String> iter = map.keySet().iterator(); iter.hasNext(); ) { resUrl = iter.next(); matcher = new AntPathRequestMatcher(resUrl); if(matcher.matches(request)) { return map.get(resUrl); } } return null; } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } @Override public boolean supports(Class<?> clazz) { return true; } }
4:修改home.html 文件
修改src/resources/templates目录下 的home.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"> <head> <meta content="text/html;charset=UTF-8"/> <title sec:authentication="name"></title> <link rel="stylesheet" th:href="@{css/bootstrap.min.css}" /> <style type="text/css"> body { padding-top: 50px; } .starter-template { padding: 40px 15px; text-align: center; } </style> </head> <body> <nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <a class="navbar-brand" href="#">Spring Security演示</a> </div> <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li><a th:href="@{/}"> 首页 </a></li> <li><a th:href="@{/admin}"> admin </a></li> </ul> </div><!--/.nav-collapse --> </div> </nav> <div class="container"> <div class="starter-template"> <h1 th:text="${msg.title}"></h1> <p class="bg-primary" th:text="${msg.content}"></p> <div sec:authorize="hasRole('ROLE_HOME')"> <!-- 用户类型为ROLE_ADMIN 显示 --> <p class="bg-info" th:text="${msg.etraInfo}"></p> </div> <div sec:authorize="hasRole('ROLE_ADMIN')"> <!-- 用户类型为ROLE_ADMIN 显示 --> <p class="bg-info">恭喜您,您有 ROLE_ADMIN 权限 </p> </div> <form th:action="@{/logout}" method="post"> <input type="submit" class="btn btn-primary" value="注销"/> </form> </div> </div> </body> </html>
5:修改HomeController.java 文件
package com.us.example.controller;import com.us.example.domain.Msg;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * Created by yangyibo on 17/1/18. */ @Controller public class HomeController { @RequestMapping("/") public String index(Model model){ Msg msg = new Msg("测试标题","测试内容","欢迎来到HOME页面,您拥有 ROLE_HOME 权限"); model.addAttribute("msg", msg); return "home"; } @RequestMapping("/admin") @ResponseBody public String hello(){ return "hello admin"; } }
6.测试检验
启动访问 http://localhost:8080/ 到登录页面
由于数据库的配置 admin 用户拥有 访问 home和admin 页面的权限。
abel 用户只有访问 home 的权限
使用admin 登录
点击 admin 按钮 会反回结果 “hello admin“
使用abel 用户登录 点击 点击 admin 按钮 页面会报403
源码地址:https://github.com/527515025/springBoot
参考资料:
http://www.tuicool.com/articles/jq6fuur#c-23220
http://blog.csdn.net/u012367513/article/details/38866465
http://blog.csdn.net/u012373815/article/details/54633046
https://github.com/527515025/springBoot
https://github.com/helloworldtang/springBoot
springBoot+springSecurity 数据库动态管理用户、角色、权限相关推荐
- springBoot+springSecurity 数据库动态管理用户、角色、权限(二)
序: 本文使用springboot+mybatis+SpringSecurity 实现数据库动态的管理用户.角色.权限管理 本文细分角色和权限,并将用户.角色.权限和资源均采用数据库存储,并且自定义 ...
- springboot整合shiro,mybatis-plus实现用户角色,权限管控.(完整demo)
资源下载链接:https://download.csdn.net/download/dayonglove2018/13960978 shiro是轻量级的权限管控框架.很早前就接触过.不过一直没有实现了 ...
- SpringSecurity动态加载用户角色权限实现登录及鉴权
本文来说下SpringSecurity如何动态加载用户角色权限实现登录及鉴权 文章目录 概述 动态数据登录验证的基础知识 UserDetails与UserDetailsService接口 实现User ...
- oracle数据库赋权_Oracle角色权限创建用户赋权
1.权限&用户 角色权限: Sysdba:可以改变字符集.创建删除数据库.登录之后用户是SYS(可以启动和关闭数据库) Sysoper:不可改变字符集.不能创.删数据库.登陆之后用户是PUBL ...
- 后台用户角色权限管理设计
目录 1.概述 2.设计 2.1 用户管理 2.2 角色管理 2.3 权限管理 2.4 用户.角色.权限的关系 3.总结 1.概述 在设计产品后台系统设置时,可根据不同项目的实际需求来设计后台系统设置 ...
- Mysql —— C语言链接mysql数据库,用户 角色 权限(用户根据角色的不同拥有增删改查的权限、用户有三种认证方式)
db_修改过(用户 角色 权限): 1.新增用户时候id 改为最大id值加一,之前用的select查看出来的记录数加一,删除后再增加会出错: 2.删除用户时候,若该用户创建过其他用户(不能改此用户名. ...
- Jenkins中安装Role-based Authorization Strategy插件来实现用户角色权限管理
场景 CentOS中Jenkins的下载.安装.配置与启动(图文教程): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/11649 ...
- java用户角色权限管理 只显示姓_扩展RBAC用户角色权限设计方案
RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成"用 ...
- 数据库实验8 数据库安全性(用户与权限管理)实验
实验8 数据库安全性(用户与权限管理)实验 8.1实验目的及要求 加深对数据库安全性的理解 8.2实验内容 数据库用户与权限管理 8.3实验步骤 8.3.1创建新用户 1.创建新用户: Mysql&g ...
- RBAC用户角色权限管理
RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成"用 ...
最新文章
- 崛起于Springboot2.X之前端模版freemaker(23)
- java的基础语法和数据类型,IDEA
- 作者:​徐优俊(1990-),男,北京大学前沿交叉学科研究院博士生。
- 我和计算机比本领教案反思,《比本领》教学设计及反思
- 菜鸟的学习之路(9) — ArrayList类
- springboot使用thymeleaf模板引擎时出现org.xml.sax.SAXParseException的原因与解决办法
- java统计空格代码_java算法大全之统计出其中英文字母、空格、数字和其它字符的个数...
- echarts3与echarts2区别
- 服务器光纤存储系统,光纤存储服务器 配置
- kindle不支持html,你的Kindle不支持夜间模式,也许是这个原因
- 三种安卓模拟器的安装和比较
- 数字化转型的趋势、挑战与战略
- 分页查询时报错:The bean ‘localeResolver‘, defined in class path resource [com/botany/spore/core/config/Comm
- Docker容器热迁移技术(基于CRIU实现)
- Web —— 单页面和多页面模式
- 从美国Java软件工程师的最低工资话说程序员职业规划
- 初学者如何查阅自然语言处理(NLP)领域学术资料
- ARP request或reply包丢失导致速率下降优化
- 电脑上视频剪辑软件预览处只有画面没有声音
- 【CodingNoBorder - 09】无际软工队 - 求职岛:ALPHA 阶段项目展示
热门文章
- 【最小生成树】还是畅通工程
- ASP.NET和ASP程序防止在IE中进行缓存
- 爬虫之代理和cookie的处理
- 63. (FileInputStream)输入字节流
- github创建远程仓库
- 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 工作原理和相关组件(三)...
- centos Install Docker
- 【转】BLE开发的各种坑
- Ubuntu命令大全(转载)
- 错误 C2280	Union : 尝试引用已删除的函数	 以及 警告 C4624	“Grade”: 已将析构函数隐式定义为“已删除”的一种解决方法...