IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 三、SpringSecurity+auth2.0系列(动态权限控制基于数据库进行设计) -> 正文阅读

[大数据]三、SpringSecurity+auth2.0系列(动态权限控制基于数据库进行设计)

!!!!注意 ,本项目是在上一个项目的基础上循序渐进的,请移步本专栏上一个项目

Rbac权限表设计
sql表地址在这里,点击不需要积分即刻下载

RBAC(基于角色的权限控制)模型的核心是在用户和权限之间引入了角色的概念。取消了用户和权限的直接关联,改为通过用户关联角色、角色关联权限的方法来间接地赋予用户权限(如下图),从而达到用户和权限解耦的目的。
在这里插入图片描述
Maven依赖

        <!-- 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>
        <!-- https://mvnrepository.com/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?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的设置
运行项目进行测试
不懂的可以骚扰我

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-09-08 10:48:29  更:2021-09-08 10:48:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:31:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码