rbac权限控制(代码片段)

toov5 toov5     2023-03-01     500

关键词:

1、什么是RBAC权限模型rity
2、RBAC权限模型表设计
3、整合Mybatis数据库
4、UserDetailsService
5、动态查询数据库登陆
6、动态权限角色拦截

 

 

什么是RBAC权限模型r

基于角色的权限访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注。在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。角色与角色的关系可以建立起来以囊括更广泛的客观情况。
百度百科:https://baike.baidu.com/item/RBAC/1328788?fr=aladdin

 

 

微服务系统中,管理平台也是有分布式的,比如会员管理,订单管理,支付管理等

最终通过SSO将公司颞部所有管理进行整合。 比如用户同一登录 www.toov5.com 进行管理

 

 
将权限的设置信息 不要写死 通过表去进行动态的配置 动态的维护   整合Mybatis就OK了

技术分享图片

 

 通过表的动态配置

参考前面的写死的配置

  

 数据库环境:

 

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for sys_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_permission`;
CREATE TABLE `sys_permission` (
  `id` int(10) NOT NULL,
  `permName` varchar(50) DEFAULT NULL,
  `permTag` varchar(50) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL COMMENT ‘请求url‘,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_permission
-- ----------------------------
INSERT INTO `sys_permission` VALUES (‘1‘, ‘查询订单‘, ‘showOrder‘, ‘/showOrder‘);
INSERT INTO `sys_permission` VALUES (‘2‘, ‘添加订单‘, ‘addOrder‘, ‘/addOrder‘);
INSERT INTO `sys_permission` VALUES (‘3‘, ‘修改订单‘, ‘updateOrder‘, ‘/updateOrder‘);
INSERT INTO `sys_permission` VALUES (‘4‘, ‘删除订单‘, ‘deleteOrder‘, ‘/deleteOrder‘);

-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
  `id` int(10) NOT NULL,
  `roleName` varchar(50) DEFAULT NULL,
  `roleDesc` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES (‘1‘, ‘admin‘, ‘管理员‘);
INSERT INTO `sys_role` VALUES (‘2‘, ‘add_user‘, ‘添加管理员‘);

-- ----------------------------
-- Table structure for sys_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_permission`;
CREATE TABLE `sys_role_permission` (
  `role_id` int(10) DEFAULT NULL,
  `perm_id` int(10) DEFAULT NULL,
  KEY `FK_Reference_3` (`role_id`),
  KEY `FK_Reference_4` (`perm_id`),
  CONSTRAINT `FK_Reference_4` FOREIGN KEY (`perm_id`) REFERENCES `sys_permission` (`id`),
  CONSTRAINT `FK_Reference_3` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_role_permission
-- ----------------------------
INSERT INTO `sys_role_permission` VALUES (‘1‘, ‘1‘);
INSERT INTO `sys_role_permission` VALUES (‘1‘, ‘2‘);
INSERT INTO `sys_role_permission` VALUES (‘1‘, ‘3‘);
INSERT INTO `sys_role_permission` VALUES (‘1‘, ‘4‘);
INSERT INTO `sys_role_permission` VALUES (‘2‘, ‘1‘);
INSERT INTO `sys_role_permission` VALUES (‘2‘, ‘2‘);

-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
  `id` int(10) NOT NULL,
  `username` varchar(50) DEFAULT NULL,
  `realname` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  `createDate` date DEFAULT NULL,
  `lastLoginTime` date DEFAULT NULL,
  `enabled` int(5) DEFAULT NULL,
  `accountNonExpired` int(5) DEFAULT NULL,
  `accountNonLocked` int(5) DEFAULT NULL,
  `credentialsNonExpired` int(5) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES (‘1‘, ‘admin‘, ‘张三‘, ‘15a013bcac0c50049356b322e955035e
‘, ‘2018-11-13‘, ‘2018-11-13‘, ‘1‘, ‘1‘, ‘1‘, ‘1‘);
INSERT INTO `sys_user` VALUES (‘2‘, ‘userAdd‘, ‘小余‘, ‘15a013bcac0c50049356b322e955035e
‘, ‘2018-11-13‘, ‘2018-11-13‘, ‘1‘, ‘1‘, ‘1‘, ‘1‘);

-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
  `user_id` int(10) DEFAULT NULL,
  `role_id` int(10) DEFAULT NULL,
  KEY `FK_Reference_1` (`user_id`),
  KEY `FK_Reference_2` (`role_id`),
  CONSTRAINT `FK_Reference_2` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`),
  CONSTRAINT `FK_Reference_1` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT INTO `sys_user_role` VALUES (‘1‘, ‘1‘);
INSERT INTO `sys_user_role` VALUES (‘2‘, ‘2‘);

 

对密码需要加密 md5加密    

对传入到后台的数据进行比对:

对于加密后的处理逻辑:

技术分享图片

 

maven:

        <!-->spring-boot 整合security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- springboot 整合mybatis框架 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- alibaba的druid数据库连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.9</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

 

 用户登录时候 会去各个表中查询出信息

 包括权限信息

 通过查询出来的信息给配置文件赋值,动态赋值。

 管理者可以通过管理这些表去进行权限的管理。

 

 对于User的bean字段需要严格按照规范去写,框架已经定义了接口,需要去实现:

  

// 用户信息表
@Data
public class User implements UserDetails 
   //框架地层查询时候 必须依赖的字段 实现这个接口 规范了名称
    private Integer id;
    private String username;
    private String realname;
    private String password;
    private Date createDate;
    private Date lastLoginTime;
    private boolean enabled;
    private boolean accountNonExpired;
    private boolean accountNonLocked;
    private boolean credentialsNonExpired;
    // 用户所有权限
    private List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

    public Collection<? extends GrantedAuthority> getAuthorities()   //一个用户可能多个权限 所以用了集合去处理存储
        return authorities;
    

 

对于数据库的查询:Mapper层

  

import java.util.List;

import org.apache.ibatis.annotations.Select;

import com.mayikt.entity.Permission;

public interface PermissionMapper 

    // 查询苏所有权限
    @Select(" select * from sys_permission ")
    List<Permission> findAllPermission();

 

  

import java.util.List;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import com.mayikt.entity.Permission;
import com.mayikt.entity.User;

public interface UserMapper 
    // 查询用户信息
    @Select(" select * from sys_user where username = #userName")
    User findByUsername(@Param("userName") String userName);

    // 查询用户的权限
    @Select(" select permission.* from sys_user user" + " inner join sys_user_role user_role"
            + " on user.id = user_role.user_id inner join "
            + "sys_role_permission role_permission on user_role.role_id = role_permission.role_id "
            + " inner join sys_permission permission on role_permission.perm_id = permission.id where user.username = #userName;")
    List<Permission> findPermissionByUsername(@Param("userName") String userName);

 

登录时候会首先执行的Java类:

 先查询出User信息

使用UserDetailsService实现动态查询数据库验证账号

import java.util.ArrayList;
import java.util.List;

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.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.mayikt.entity.Permission;
import com.mayikt.entity.User;
import com.mayikt.mapper.UserMapper;

// 设置动态用户信息
@Service
public class MyUserDetailsService implements UserDetailsService 
    @Autowired
    private UserMapper userMapper;

    @Override   //用户登录时候会调用这个方法 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 

        // 1.根据用户名称查询数据用户信息
        User user = userMapper.findByUsername(username);
        // 2.底层会根据数据库查询用户信息,判断密码是否正确   开发者需要做的就是查询就OK了
        // 3. 给用户设置权限     查询出来 然后赋值就OK了
        List<Permission> listPermission = userMapper.findPermissionByUsername(username);
        System.out.println("username:" + username + ",对应权限:" + listPermission.toString());
        if (listPermission != null && listPermission.size() > 0) 
            // 定义用户权限
            List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
            for (Permission permission : listPermission) 
                authorities.add(new SimpleGrantedAuthority(permission.getPermTag()));
            
            user.setAuthorities(authorities);
        
        return user;
    

 

进行权限的校验 设置:

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import com.mayikt.entity.Permission;
import com.mayikt.handler.MyAuthenticationFailureHandler;
import com.mayikt.handler.MyAuthenticationSuccessHandler;
import com.mayikt.mapper.PermissionMapper;
import com.mayikt.security.MyUserDetailsService;
import com.mayikt.utils.MD5Util;

// Security 配置
@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 
    @Autowired
    private MyAuthenticationFailureHandler failureHandler;
    @Autowired
    private MyAuthenticationSuccessHandler successHandler;
    @Autowired
    private MyUserDetailsService myUserDetailsService;
    @Autowired
    private PermissionMapper permissionMapper;

    // 配置认证用户信息和权限
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        // // 添加admin账号
        // auth.inMemoryAuthentication().withUser("admin").password("123456").
        // authorities("showOrder","addOrder","updateOrder","deleteOrder");
        // // 添加userAdd账号
        // auth.inMemoryAuthentication().withUser("userAdd").password("123456").authorities("showOrder","addOrder");
        // 如果想实现动态账号与数据库关联 在该地方改为查询数据库
        auth.userDetailsService(myUserDetailsService).passwordEncoder(new PasswordEncoder() 

            // 加密的密码与数据库密码进行比对CharSequence rawPassword 表单字段 encodedPassword
            // 数据库加密字段
            public boolean matches(CharSequence rawPassword, String encodedPassword) 
                System.out.println("rawPassword:" + rawPassword + ",encodedPassword:" + encodedPassword);
                // 返回true 表示认证成功 返回fasle 认证失败
                Boolean reslt = MD5Util.encode((String) rawPassword).equals(encodedPassword);
                System.out.println("result结果:"+reslt);
                return reslt;
            

            // 对表单密码进行加密
            public String encode(CharSequence rawPassword) 
                System.out.println("rawPassword:" + rawPassword);
                return MD5Util.encode((String) rawPassword);
            
        );
    

    // 配置拦截请求资源    进行动态请求资源
    protected void configure(HttpSecurity http) throws Exception 
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests = http
                .authorizeRequests();
        // 1.读取数据库权限列表
        List<Permission> listPermission = permissionMapper.findAllPermission();
        for (Permission permission : listPermission) 
            // 设置权限
            authorizeRequests.antMatchers(permission.getUrl()).hasAnyAuthority(permission.getPermTag());
        
        authorizeRequests.antMatchers("/login").permitAll().antMatchers("/**").fullyAuthenticated().and().formLogin()
                .loginPage("/login").successHandler(successHandler).and().csrf().disable();

    

    @Bean
    public static NoOpPasswordEncoder passwordEncoder() 
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    

 

yml:

# 配置freemarker
spring:
  freemarker:
    # 设置模板后缀名
    suffix: .ftl
    # 设置文档类型
    content-type: text/html
    # 设置页面编码格式
    charset: UTF-8
    # 设置页面缓存
    cache: false
    # 设置ftl文件路径
    template-loader-path:
      - classpath:/templates
  # 设置静态文件路径,js,css等
  mvc:
    static-path-pattern: /static/**
####整合数据库层    
  datasource:
    name: test
    url: jdbc:mysql://127.0.0.1:3306/rbac_db
    username: root
    password: root
    # druid 连接池
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    

 

 

加密工具:

import java.security.MessageDigest;

public class MD5Util 

    // 加盐
    private static final String SALT = "toov5";

    public static String encode(String password) 
        password = password + SALT;
        MessageDigest md5 = null;
        try 
            md5 = MessageDigest.getInstance("MD5");
         catch (Exception e) 
            throw new RuntimeException(e);
        
        char[] charArray = password.toCharArray();
        byte[] byteArray = new byte[charArray.length];

        for (int i = 0; i < charArray.length; i++)
            byteArray[i] = (byte) charArray[i];
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++) 
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16) 
                hexValue.append("0");
            

            hexValue.append(Integer.toHexString(val));
        
        return hexValue.toString();
    

    public static void main(String[] args) 
        System.out.println(MD5Util.encode("123456"));

    

启动类:

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@MapperScan("com.toov5.mapper")
@SpringBootApplication
public class AppSecurity 

    public static void main(String[] args) 
        SpringApplication.run(AppSecurity.class, args);
        // Security 两种模式 fromLogin 表单提交认证模式 httpBasic 浏览器与服务器做认证授权
    

 

这样就成为了 根据SQL进行动态配置修改的啦~~

 








rbac权限控制(代码片段)

1、什么是RBAC权限模型rity2、RBAC权限模型表设计3、整合Mybatis数据库4、UserDetailsService5、动态查询数据库登陆6、动态权限角色拦截  什么是RBAC权限模型r基于角色的权限访问控制(Role-BasedAccessControl)作为传统访问控制(自... 查看详情

2rbac组件后台布局模板,权限粒度控制,权限按钮(代码片段)

1、后台布局管理https://www.cnblogs.com/venicid/p/7772742.html#_label01、通用模板overflow:auto;//在a和b模板中进行切换a模板:左侧菜单跟随滚动条 b模板 左侧以及上不动****<!DOCTYPEhtml><htmllang="en"><head><metachars 查看详情

rbac权限验证(代码片段)

模型:rbac基于角色的权限访问控制什么是权限?一个包含正则表达式的url就是权限第一个版本,实现简单的权限验证需求表结构:classUserInfo(models.Model):name=models.CharField(max_length=32)pwd=models.CharField(max_length=32)roles=models.ManyToManyField(... 查看详情

rbac模型整合数据权限(代码片段)

...部分数据。控制一个用户能访问哪些资源我们有很成熟的权限管理模型即RBAC,但是控制用户只能访问某部分资源(即我们常说的数据权限)使用RBAC模型是不够的,本文我们尝试在RBAC模型的基础上融入数据权限的... 查看详情

rbac:基于角色的权限访问控制(代码片段)

...RBAC96模型最具有代表,并得到了普遍的公认。RBAC认为权限授权的过程可以抽象地概括为:Who是否可以对What进行How的访问操作,并对这个逻辑表达式进行判断是否为True的求解过程,也即是将权限问题转换为What、How... 查看详情

kubernetes-一文详解serviceaccount与rbac权限控制(代码片段)

一、ServiceAccount1.ServiceAccount介绍首先Kubernetes中账户区分为:UserAccounts(用户账户)和ServiceAccounts(服务账户)两种,它们的设计及用途如下:UserAccount是给kubernetes集群外部用户使用的,例如运维或者集群管理人员,使用kubectl命... 查看详情

权限组件之rbac(代码片段)

rbac:基于角色的权限访问控制(Role-BasedAccessControl)。 deflogin(request):ifrequest.method=="GET":returnrender(request,"login.html")else:user=request.POST.get("user")pwd=request.POST.get("pwd")user=UserInfo.o 查看详情

云原生kubernetes-基于角色的访问控制rbac(代码片段)

...源的访问的方法。简言之,不同用户之间拥有不同的访问权限,就像我们在使用ELK日志系统时,运维人员具有最高权限,根据其他人员的需求对不同的index分配可读,可写,只读,只写,其他各种权限。在k8s中,负责完成授权工... 查看详情

使用springsecurityspringdatajpa实现的rbac权限控制(代码片段)

正好这几天不是那么忙,所以就研究了一下SpringSecurity的使用,为了以后方便写篇帖子记录一下。1.什么是SpringSecurity?我想关于什么是SpringSecurity我都不需要在这里赘述,大家可以到网上百度一下,但是问了大家能... 查看详情

数据权限就该这么设计,yyyds!(代码片段)

...部分数据。控制一个用户能访问哪些资源我们有很成熟的权限管理模型即RBAC,但是控制用户只能访问某部分资源(即我们常说的数据权限)使用RBAC模型是不够的,本文我们尝试在RBAC模型的基础上融入数据权限的... 查看详情

基于django实现rbac权限管理(代码片段)

...C(Role-BasedAccessControl,基于角色的访问控制),通过角色绑定权限,然后给用户划分角色。在web应用中,可以将权限理解为url,一个权限对应一个url。在实际应用中,url是依附在菜单下的,比如一个简单的生产企业管理系统,菜单可... 查看详情

djang之基于角色的权限控制(rbac)(代码片段)

...的url地址,甲关联了管理员,则甲拥有访问所有url地址的权限,普通用户:只拥有访问查看数据(查看某个页面)的url地址,乙关联普通用户,乙就只拥有普通用户的权限2.models实现classPermission(models.Model):url=models.CharField(max_length... 查看详情

基于rbac权限控制模型的管理系统的设计与实现(代码片段)

文章目录一、RBAC权限设计1.1模型概述1.2模型分类二、基于RBAC的后台管理系统2.1项目概述2.2技术选型2.3内部处理流程2.4功能模块展示2.5权限控制展示2.6下载说明一、RBAC权限设计1.1模型概述  基于角色的访问控制RBAC,是实施... 查看详情

基于rbac权限控制模型的管理系统的设计与实现(代码片段)

文章目录一、RBAC权限设计1.1模型概述1.2模型分类二、基于RBAC的后台管理系统2.1项目概述2.2技术选型2.3内部处理流程2.4功能模块展示2.5权限控制展示2.6下载说明一、RBAC权限设计1.1模型概述  基于角色的访问控制RBAC,是实施... 查看详情

十六rbac(代码片段)

...没什么不同。角色反而是授权的机制。他通过角色完成了权限的授予,分配等。    a、角色(role):因此从内容来讲角色是指一个组织或者任务中的工作或者位置,他通常代表一种权力和资格,或者一种责任,在RBAC中还有一... 查看详情

4crm-权限管理rbac(代码片段)

1、引入权限组件rbac1、settings配置app、中间件INSTALLED_APPS=[......‘crm.apps.CrmConfig‘,"stark.apps.StarkConfig",‘rbac.apps.RbacConfig‘,]中间件MIDDLEWARE=[。。。。‘rbac.service.rbac.ValidPermission‘,]2、员工表UserInfo和rbac.Us 查看详情

[linux之权限管理⽤户组管理](代码片段)

[Linux之权限管理⽤户组管理]权限管理用户组管理RBAC权限管理RBAC(Role-BasedAccessControl,基于角色的访问控制),就是用户通过角色与权限进行关联。简单地说,一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成... 查看详情

rbac权限+中间件(代码片段)

1、权限组件rbac1、什么是权限1项目与应用2什么是权限?一个包含正则表达式url就是一个权限whowhathow---------->TrueorFlase 2、版本:用户--》角色--》权限UserInfornamepwdrolesnamepwdegon123alex456alex456alex456alex456alex456alex456alex456alex456Rol 查看详情