三、SpringSecurity+auth2.0系列(动态权限控制,基于数据库进⾏设计)注意 ,本项⽬是在上⼀个项⽬的基础上循序渐进的,请移步本专栏上⼀个项⽬
Rbac权限表设计
RBAC(基于⾓⾊的权限控制)模型的核⼼是在⽤户和权限之间引⼊了⾓⾊的概念。取消了⽤户和权限的直接关联,改为通过⽤户关联⾓⾊、⾓⾊关联权限的⽅法来间接地赋予⽤户权限(如下图),从⽽达到⽤户和权限解耦的⽬的。
Maven依赖
<!-- springboot 整合mybatis框架 -->
<dependency>
<groupId&batis.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>
<!-- /artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
配置⽂件
datasource:
url: jdbc:mysql://127.0.0.1:3306/orange_rbac?rverTimezone=Asia/Shanghai&allowMultiQueries=true&uUnicode=true&characterEncoding=utf-8 urname: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: sql.cj.jdbc.Driver
Mapper接⼝
导⼊Mapper接⼝
新建mapper包
新建接⼝与数据库交互
完整代码如下
权限mapper
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Component;
import java.util.List;
@Mapper
public interface PermissionMapper {
@Select(" SELECT * from sys_permission ")
List<PermissionEntity> findAllPermission();
}
⽤户mapper
package com.thunisoft.spring_curity.mapper;
多吃蔬菜的好处
import com.thunisoft.del.PermissionEntity;地基基础施工
import com.thunisoft.del.UrEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface UrMapper {
/**
* 根据⽤户名查询⽤户
* @param urName
* @return
*/
@Select(" SELECT * from sys_ur where urname = #{urName}")
UrEntity findByUrname(String urName);
/**
* 查询⽤户的权限根据⽤户查询权限
*
* @param
* @return
*/
@Select(" lect permission.* from sys_ur ur" + " inner join sys_ur_role ur_role"
+ " on ur.id = ur_role.ur_id inner join "
+ "sys_role_permission role_permission on le_id = le_id "
+ " inner join sys_permission permission on role_permission.perm_id = permission.id where ur.urname = #{urName};") List<PermissionEntity> findPermissionByUrname(String urName);
}
动态根据账户名称查询权限
使⽤UrDetailsService实现动态查询数据库验证账号
新建rvice包,在下⾯新建类
完整代码如下
import com.thunisoft.del.PermissionEntity;
import com.thunisoft.del.UrEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.GrantedAuthority;
读后感400
import org.authority.SimpleGrantedAuthority;
import org.urdetails.UrDetails;
import org.urdetails.UrDetailsService;
import org.urdetails.UrnameNotFoundException;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class MemberDetailsService implements UrDetailsService {
@Autowired
private UrMapper urMapper;
@Override
public UrDetails loadUrByUrname(String s) throws UrnameNotFoundException {
//查询⽤户
UrEntity urEntity = urMapper.findByUrname(s);
if (urEntity==null){
return null;
毅力英语
}
//查询⽤户权限
List<PermissionEntity> permissionEntityList = urMapper.findPermissionByUrname(s);
梦见大黑蛇ArrayList<GrantedAuthority> grantedAuthorities = new ArrayList<>();
permissionEntityList.forEach((a)->{
grantedAuthorities.add(new PermTag()));
});
// 设置权限
urEntity.tAuthorities(grantedAuthorities);
return urEntity;
}
}
WebSecurity相关配置
完整配置如下
package com.thunisoft.fig;
import com.thunisoft.spring_curity.mapper.PermissionMapper;
import com.thunisoft.del.PermissionEntity;
import com.thunisoft.spring_curity.rvice.MemberDetailsService;
import com.thunisoft.spring_curity.utils.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import t.annotation.Bean;
import org.fig.annotation.authentication.builders.AuthenticationManagerBuilder; import org.fig.annotation.web.builders.HttpSecurity;
import org.fig.figuration.EnableWebSecurity;
import org.fig.figuration.WebSecurityConfigurerAdapter; import org.fig.figurers.ExpressionUrlAuthorizationConfigurer; import org.pto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MemberDetailsService memberDetailsService;
@Autowired
private PermissionMapper permissionMapper;
@Override
protected void configure(HttpSecurity http) throws Exception {
/**
* 新增 HttpSecurity基础配置配置
*/
// http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().httpBasic();
/**
* 新增HttpSecurity formLogin模式
*/
//http.authorizeRequests().antMatchers("/**").fullyAuthenticated().and().formLogin();
/
*
http.authorizeRequests().antMatchers("/addMember").hasAnyAuthority("addMember")
.antMatchers("/delMember").hasAnyAuthority("delMember")
.antMatchers("/showMember").hasAnyAuthority("showMember")
.antMatchers("/editMember").hasAnyAuthority("editMember").
// antMatchers("/**").fullyAuthenticated().and().formLogin()
antMatchers("/login").permitAll().antMatchers("/**").fullyAuthenticated().and().formLogin()
.loginPage("/login").and().csrf().disable();
*/
List<PermissionEntity> allPermission = permissionMapper.findAllPermission();
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests = http.authorizeRequests();
allPermission.forEach((a)->{
//地址绑定权限
authorizeRequests.Url()).PermTag());
});
authorizeRequests.antMatchers("/login").permitAll()
// 设置⾃定义登录页⾯
.antMatchers("/**").fullyAuthenticated().and().formLogin().loginPage("/login").and().csrf().disable();
}
/*
* 新增授权账户
* */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//新增⼀个⽤户为orange,密码为chengyunpeng的⽤户可以访问是所有权限
/* auth.inMemoryAuthentication().withUr("admin").password("admin").authorities("addMember","delMember","editMember","showMember"); auth.inMemoryAuthentication().withUr("orange").password("orange").authorities("showMember");
*/
auth.urDetailsService(memberDetailsService).passwordEncoder(new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
de((String)charSequence);
}
@Override
public boolean matches(CharSequence charSequence, String s) {
String rawPass = de((String) charSequence);
boolean result = rawPass.equals(s);
return result;
}
});
}
/**
* 密码不做任何处理
* @return
*/
/* @Bean
public static NoOpPasswordEncoder passwordEncoder(){
return (NoOpPasswordEncoder) Instance(); }*/
}
MD5⼯具类如下
package com.thunisoft.spring_curity.utils;
import java.curity.MessageDigest;
public class MD5Util {
private static final String SALT = "mayikt";
public static String encode(String password) {小学一年级猜字谜
password = password + SALT;
MessageDigest md5 = null;
try {
md5 = Instance("MD5");
} catch (Exception e) {
throw new RuntimeException(e);
}
char[] charArray = CharArray();
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.HexString(val));
}
String();
}
public static void main(String[] args) {
System.out.de("orange"));
}
}