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\r\n', '2018-11-13', '2018-11-13', '1', '1', '1', '1');
INSERT INTO `sys_user` VALUES ('2', 'userAdd', '小余', '15a013bcac0c50049356b322e955035e\r\n', '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. yii2 rbac权限控制详细操作步骤

    作者:白狼 出处:http://www.manks.top/article/yii2_rbac_description本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 ...

  2. yii2 rbac权限控制之菜单menu详细教程

    作者:白狼 出处:http://www.manks.top/article/yii2_rbac_menu本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...

  3. yii2搭建完美后台并实现rbac权限控制实例教程

    1.安装yii2 未安装的请参考yii2史上最简单式安装教程,没有之一 或者参考yii2实战教程之详细安装步骤 已安装的请继续看下一步操作 2.配置数据库 2.1 配置数据库 修改common/con ...

  4. Kubernetes-16:一文详解ServiceAccount及RBAC权限控制

    一.ServiceAccount 1.ServiceAccount 介绍 首先Kubernetes中账户区分为:User Accounts(用户账户) 和 Service Accounts(服务账户) ...

  5. yii2搭建完美后台并实现rbac权限控制案例教程

    作者:白狼 出处:www.manks.top/article/yii2_frame_rbac_template 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连 ...

  6. 基于thinkphp的RBAC权限控制

    RBAC  Role-Based Access Control 权限控制在后台管理中是十分常见的,它的模型大体上是下面这张图的形式 我用的字段和上面不一样,图只是个示例 一个简易的权限控制模型只需要3 ...

  7. 转:RBAC权限控制

    名词解释: RBAC:Role-Based Access Control,基于角色的访问控制   关键词: RBAC,Java Shiro,Spring Security,   一. RBAC 要解决 ...

  8. PHP RBAC权限控制,基于CI框架(版本3.1.9)

    2018年11月7日更新:目前功能已做到事件级别权限控制,如:后台用户的添加操作.删除操作和保存操作等具体到事件级的操作方法有权限则展示相应的操作菜单,没权限则隐藏相应菜单或提示无权限到目前算是真正做 ...

  9. Yii2搭建后台并实现rbac权限控制完整实例教程

    .安装yii2 未安装的请参考yii2史上最简单式安装教程,没有之一 已安装的请继续看下一步操作 2.配置数据库 2.1 配置数据库 修改common/config/main-local.php 实际 ...

  10. 基于SpringSecurity实现RBAC权限控制(待完善)

    Spring Security是一个为企业应用系统提供声明式的安全访问控制功能,减少为了企业应用系统安全控制而编写的大量重复代码. 认证: spring security的原理就是使用很多的拦截器对U ...

随机推荐

  1. 5秒后跳转到另一个页面的js代码

    今天看视频学习时学习了一种新技术,即平时我们在一个页面点击“提交”或“确认”会自动跳转到一个页面. 在网上搜了一下,关于这个技术处理有多种方法,我只记下我在视频里学到的三种: 1.用一个respons ...

  2. gradle加载spring包

    import org.gradle.plugins.ide.eclipse.model.Facet apply plugin: 'java' apply plugin: 'war' apply plu ...

  3. 读 下一代SOA 服务技术与面向服务简明指南

    面向服务的八个设计原则 标准化服务合同 在同一个服务仓库中的服务都符合同样的合同设计标准 服务松耦合 服务合同施加了消费者低耦合的要求,而它们自己也与周围的环境脱钩 服务抽象 服务合同只包含基本信息, ...

  4. Idea之Tomcat

    安装配置   启动 三种方式,run,debug,coverage       面板说明     上面一排 Debugger:debug模式的时候显示方法,调用关系,参数值等, Server:打印日志 ...

  5. IE数组排序问题的处理

    有一哥们在微信开发中,到生成签名这抓狂了一天 最后发现微信调试工具在IE和chrome下对字符的排序竟然不同. 嗯,这个问题引起了我的关注,于是根据微信工具里的对象数组格式,撸了几句代码调试了一下,发 ...

  6. http://element.eleme.io/#/zh-CN/component/quickstart

    http://element.eleme.io/#/zh-CN/component/quickstart

  7. Storm-源码分析-Topology Submit-Executor-mk-threads

    对于executor thread是整个storm最为核心的代码, 因为在这个thread里面真正完成了大部分工作, 而其他的如supervisor,worker都是封装调用. 对于executor的 ...

  8. php5.4 的 php-fpm 的重启

    php 5.3.3以后 源码中已经内嵌了 php-fpm,不用象以前的php版本一样专门打补丁了,只需要在configure的时候添加编译参数即可. 关于php-fpm的编译参数有 –enable-f ...

  9. python - 常用的小方法

    常用的小方法: bin() oct() hex() chr() ord() dir() id() len() int() str() type() help() range(10)   /  rang ...

  10. JSONObject和JSONArray 以及Mybatis传入Map类型参数

    import org.json.JSONArray;import org.json.JSONObject; 将字符串转化为JSONArray   JSONArray  jsonArray = new ...