登录/注册
唐某
11055
占位
7
占位
31
浏览量
占位
粉丝
占位
关注
Spring Security极简入门三部曲(下篇) - 白泽来了
唐某
2021-05-07 17:54:03 2021-05-07
152
0

目录

Spring Security极简入门三部曲(下篇)

前情回顾

我们已经实现的功能:

  1. 网站分为首页、登陆页、用户页、管理员页、报错页
  2. 使用用户名密码登陆,登陆失败报错
  3. 首页、登陆页所有角色都能访问
  4. 用户页需要USER或ADMIN权限,管理员页需要ADMIN权限(权限不足时跳转至403页面)
  5. 如果用户没有登录,则访问需要权限的页面时自动跳转登录页面,登陆成功后自动跳转至访问的页面
  6. 自定义验证器,当黑客使用baize用户和任意密码登陆后,将获取全部权限

本次添加的功能:

从这篇博客开始,我们将在demo2中加入数据库得到demo3,在保留demo2的功能的基础上,增加两个用户,user2,拥有USER权限,admin2,拥有USER、ADMIN权限,这些数据都将存入数据库中,github项目地址

数据库设计

回顾一下之前给出的数据库模型

当然,本节并不会用到所有的表,规定只在用户<->角色之间进行权限的约束,也就是上图的用户表、角色表、用户角色关系表,建表语句如下:

create table `user`(
`user_id` int(11) not null auto_increment,
`username` varchar(255) default null comment '姓名',
`password` varchar(255) default null comment '密码',
primary key (`id`)
)engine=innodb, charset=utf8;
create table `role`(
`role_id` int(11) not null auto_increment,
`role_name` varchar(255) default null comment '角色',
primary key (`id`)
)engine=innodb, charset=utf8;
create table `user_role`(
`user_id` int(11) not null,
`role_id` int(11) not null,
primary key(`user_id`, `role_id`)
)engine=innodb, charset=utf8;
//这个密码是用了工具类对123进行加密后的结果
insert into `user`(`user_id`, `username`, `password`)
values
(1, 'admin2', '$2a$10$h6rzOMVI5lismIclafb7duoVCgN2ShCVr4Nn2Jx772.buyaq7rZKq'),
(2, 'user2', '$2a$10$h6rzOMVI5lismIclafb7duoVCgN2ShCVr4Nn2Jx772.buyaq7rZKq');
insert into `role`(`role_id`, `role_name`)
values
(1, 'ROLE_USER'),
(2, 'ROLE_ADMIN');
insert into `user_role`(`user_id`, `role_id`)
values
(1, 1),
(1, 2),
(2, 1);

demo时刻

实现功能:github项目地址

  1. 从数据库中读取用户名、密码,与前端输l入的信息进行对比验证(user2和admin2,密码为123)
  2. 验证通过后,登陆用户会得到数据库中存储的角色信息

demo3相比前两个demo增加了较多的文件:

  1. application.yml中添加了数据库相关的一些配置文件
  2. 因使用mybatis框架而添加了相关mapper,以及配合使用的实体类,service,xml文件等
  3. 添加了一个UserDetailsService接口的实现类MyUserDetailsService为核心类

代码分析

MyUserDetailsService是核心,它的主要作用就是自定义了一个数据库验证器加入过滤器链,用于验证前端输入的用户名是否能在数据库中表中查到,并且在查得用户时去查询角色表,为用户赋予角色权限(spring security会为我们做密码错误时的验证,不用人为去处理)

我们只需要在自定义的loadUserByUsername()方法中将参数s当作前端输入的username去使用,并且最后返回一个UserDetails接口的实现类即可(该实现类记录着用户名、密码、权限列表)

```

/**

  • UserDetailsService的实现类,用于在程序中引入一个自定义的AuthenticationProvider,实现数据库访问模式的验证

  • /

    @Service
    public class MyUserDetailsService implements UserDetailsService {

    @Autowired

    private UserService userService;

    @Autowired

    private RoleService roleService;

    @Autowired

    private UserRoleService userRoleService;

    @Override

    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

      Collection<GrantedAuthority> authorities = new ArrayList<>();
    //从数据库中取出用户信息
    User user = userService.findByName(s);
    //判断用户是否存在
    if (user == null) {
    throw new UsernameNotFoundException("数据库中无此用户!"
暂无评论