!!!!注意 ,本项目是在上一个项目的基础上循序渐进的,请移步本专栏上一个项目
Rbac权限表设计 sql表地址在这里,点击不需要积分即刻下载
RBAC(基于角色的权限控制)模型的核心是在用户和权限之间引入了角色的概念。取消了用户和权限的直接关联,改为通过用户关联角色、角色关联权限的方法来间接地赋予用户权限(如下图),从而达到用户和权限解耦的目的。 Maven依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<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>
<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?serverTimezone=Asia/Shanghai&allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
Mapper接口 导入Mapper接口 新建mapper包 新建接口与数据库交互 完整代码如下
权限mapper
package com.thunisoft.spring_security.mapper;
import com.thunisoft.spring_security.model.PermissionEntity;
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_security.mapper;
import com.thunisoft.spring_security.model.PermissionEntity;
import com.thunisoft.spring_security.model.UserEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface UserMapper {
/**
* 根据用户名查询用户
* @param userName
* @return
*/
@Select(" SELECT * from sys_user where username = #{userName}")
UserEntity findByUsername(String userName);
/**
* 查询用户的权限根据用户查询权限
*
* @param
* @return
*/
@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<PermissionEntity> findPermissionByUsername(String userName);
}
动态根据账户名称查询权限 使用UserDetailsService实现动态查询数据库验证账号 新建service包,在下面新建类 完整代码如下
package com.thunisoft.spring_security.service;
import com.thunisoft.spring_security.mapper.UserMapper;
import com.thunisoft.spring_security.model.PermissionEntity;
import com.thunisoft.spring_security.model.UserEntity;
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.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class MemberDetailsService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
//查询用户
UserEntity userEntity = userMapper.findByUsername(s);
if (userEntity==null){
return null;
}
//查询用户权限
List<PermissionEntity> permissionEntityList = userMapper.findPermissionByUsername(s);
ArrayList<GrantedAuthority> grantedAuthorities = new ArrayList<>();
permissionEntityList.forEach((a)->{
grantedAuthorities.add(new SimpleGrantedAuthority(a.getPermTag()));
});
// 设置权限
userEntity.setAuthorities(grantedAuthorities);
return userEntity;
}
}
WebSecurity相关配置 完整配置如下
package com.thunisoft.spring_security.config;
import com.thunisoft.spring_security.mapper.PermissionMapper;
import com.thunisoft.spring_security.model.PermissionEntity;
import com.thunisoft.spring_security.service.MemberDetailsService;
import com.thunisoft.spring_security.utils.MD5Util;
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.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.antMatchers(a.getUrl()).hasAnyAuthority(a.getPermTag());
});
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().withUser("admin").password("admin").authorities("addMember","delMember","editMember","showMember");
auth.inMemoryAuthentication().withUser("orange").password("orange").authorities("showMember");
*/
auth.userDetailsService(memberDetailsService).passwordEncoder(new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return MD5Util.encode((String)charSequence);
}
@Override
public boolean matches(CharSequence charSequence, String s) {
String rawPass = MD5Util.encode((String) charSequence);
boolean result = rawPass.equals(s);
return result;
}
});
}
/**
* 密码不做任何处理
* @return
*/
/* @Bean
public static NoOpPasswordEncoder passwordEncoder(){
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}*/
}
MD5工具类如下
package com.thunisoft.spring_security.utils;
import java.security.MessageDigest;
public class MD5Util {
private static final String SALT = "mayikt";
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("orange"));
}
}
主要是websecrity的设置 运行项目进行测试 不懂的可以骚扰我
|