SpringSecurity连接数据库(二)

SpringSecurity连接数据库操作如下:

  1. 创建表结构
-- 用户表
CREATE TABLE `sys_user`(
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) NOT NULL,
`password` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;


-- 角色表
CREATE TABLE `sys_role`(
`id` INT NOT NULL,
`code` VARCHAR(255) NOT NULL,
`name` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 中间表
CREATE  TABLE sys_user_role(
`user_id` INT NOT NULL,
`role_id` INT NOT NULL,
PRIMARY  KEY (`user_id`,`role_id`),
CONSTRAINT  `fk_role_id` FOREIGN  KEY (`role_id`) REFERENCES  `sys_role` (`id`) ON DELETE CASCADE  ON UPDATE CASCADE,
CONSTRAINT  `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `sys_user`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
)ENGINE =INNODB  DEFAULT CHARSET=utf8

ON DELETE CASCADE ON UPDATE CASCADE:代表主表的id发生改变时,从表的id也同时进行delete或update。

  1. 导入依赖
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
       </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-jdbc</artifactId>
       </dependency>
  1. 在AuthenticationManagerBuilder中,默认提供了一个UserDetailsService接口,此接口中只有一个loadUserByUsername(String username) 方法,由此可知,此方法是可以根据用户名来获取用户信息的,
    在这里插入图片描述

  2. 通过实现UserDetailsService接口,从而获取表中用户信息及角色的授权

package com.coffee.springbootstudy.serverimpl;

import com.coffee.springbootstudy.mapper.SysUserMapper;
import com.coffee.springbootstudy.pojo.SysUser;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

   @Resource
   SysUserMapper sysUserMapper;

   public PasswordEncoder passwordEncoder(){
       return new BCryptPasswordEncoder();
   }

   @Override
   public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
       if (username == null) {
           throw new RuntimeException("用户名不能为空");
       }

       //如果用户名不为空,则根据用户名获取用户信息

       SysUser sysUser = sysUserMapper.selectByPrimaryKey(username);

       if (sysUser == null) {
           throw new UsernameNotFoundException("这个用户不存在");
       }
/**
1. public User(String username, String password, Collection<? extends GrantedAuthority> authorities) {
2.         this(username, password, true, true, true, true, authorities);
3.     }
4.  5.     userDetails有三个子类,User是其一,User类中包含两个重写方法
*/
       List<GrantedAuthority> authorities = new ArrayList<>();
       //获取角色
       List<String> roleCodeByUserName = sysUserMapper.getRoleCodeByUserName(username);
       roleCodeByUserName.forEach(code -> {
           SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(code);
           authorities.add(simpleGrantedAuthority);
           System.out.println(code);
       });
       return new User(sysUser.getUsername(), passwordEncoder().encode(sysUser.getPassword()),authorities);
   }
}
  1. 通过自定义security策略,实现configure(AuthenticationManagerBuilder auth),并且对业务进行调用。
    @Resource
   UserDetailsService userDetailsService;

   //认证
   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       /**
        * inMemoryAuthentication在内存中对用户名及密码进行认证
        */
//        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1", "vip2")
//                .and()
//                .withUser("zhangsan").password(new BCryptPasswordEncoder().encode("123")).roles("vip2");

/**
* 连接数据库
*/


       auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());

   }

  1. 测试
    在这里插入图片描述
    我们采用“张三”这个用户进行登录,从表中数据可知他属于普通用户,我们在授权中对普通用户设定了只能访问level2模块下的使用子模块,
    在这里插入图片描述
    在这里插入图片描述

注意点:

  • 在角色表中,code字段值需要加上“ROLE_”前缀,不然则无法识别。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值