三、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的设置
运行项目进行测试
不懂的可以骚扰我

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@我不是大鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值