第4章 Spring Security 基于数据库的登录认证

2022-09-20 08:37:32

一般来说,我们的用户信息都是存放在数据库中的,本章节就基于数据库来完成认证与授权。

数据库设计

这里需要三张表:user(用户信息表)、role(角色表)、user_role(用户与角色关系表)。一般来说,角色与权限相关,所以用户具有什么样的角色,就拥有什么样的权限。

create table `user` (
    `id` int unsigned NOT NULL AUTO_INCREMENT,
    `username` varchar(50) NOT NULL,
    `password` varchar(50) NOT NULL,
    `enabled` varchar(50) DEFAULT NULL,
    `locked` varchar(50) DEFAULt NULL,
    PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

create table `role` (
    `id` int unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(50) NOT NULL,
    PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

create table `user_role` (
    `id` int unsigned NOT NULL AUTO_INCREMENT,
    `uid` int NOT NULL,
    `rid` int NOT NULL,
    PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Maven依赖

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.9</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency>

application.yml配置文件

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/world?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&serverTimezone=UTC
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    password: root

UserDetailsService的实现

UserDetailsService 是由Spring Security提供给我们的接口,如下所示。

publicinterfaceUserDetailsService{UserDetailsloadUserByUsername(String var1)throwsUsernameNotFoundException;}

我们可以自定义实现。

@ServicepublicclassUserServiceimplementsUserDetailsService{@AutowiredprivateUserMapper userMapper;@OverridepublicUserDetailsloadUserByUsername(String username)throwsUsernameNotFoundException{// 根据用户名查找用户User user= userMapper.loadUserByUsername(username);if(user==null){return user;}// 根据用户id查找所具有的角色List<Role> roles= userMapper.getUserRoleByUid(user.getId());
        user.setRoles(roles);return user;}}

Mapper类

@MapperpublicinterfaceUserMapper{@Select("select * from user where username=#{username}")UserloadUserByUsername(String username);@Select("SELECT * FROM role r INNER JOIN user_role ur ON r.id = ur.rid WHERE uid=#{id}")List<Role>getUserRoleByUid(Integer id);}

实体类

Spring Security的用户都是用UserDetails 类代表。我们需要实现UserDetails 接口。

publicclassUserimplementsUserDetails{privateInteger id;privateString username;privateString password;privateBoolean enabled;privateBoolean locked;privateList<Role> roles;@OverridepublicCollection<?extendsGrantedAuthority>getAuthorities(){List<SimpleGrantedAuthority> authorities=newArrayList<>();for(Role role: roles){
            authorities.add(newSimpleGrantedAuthority(role.getName()));}return authorities;}@OverridepublicStringgetPassword(){return password;}@OverridepublicStringgetUsername(){return username;}@OverridepublicbooleanisAccountNonExpired(){returntrue;}@OverridepublicbooleanisAccountNonLocked(){returntrue;}@OverridepublicbooleanisCredentialsNonExpired(){returntrue;}@OverridepublicbooleanisEnabled(){returntrue;}// getter or setter 省略}

WebSecurityConfigurerAdapter配置

@ConfigurationpublicclassUserWebSecurityConfigextendsWebSecurityConfigurerAdapter{@AutowiredprivateUserService userService;// 密码编码器,这里是明文,不对密码进行加密@BeanpublicPasswordEncoderpasswordEncoder(){returnnewPasswordEncoder(){@OverridepublicStringencode(CharSequence charSequence){return charSequence.toString();}@Overridepublicbooleanmatches(CharSequence charSequence,String s){return charSequence.toString().equals(s);}};}@Overrideprotectedvoidconfigure(HttpSecurity http)throwsException{
        http.authorizeRequests().antMatchers("/admin/**").hasAnyRole("ADMIN").anyRequest().authenticated();}@Overrideprotectedvoidconfigure(AuthenticationManagerBuilder auth)throwsException{
        auth.userDetailsService(userService);}}

备注
本系列都是学习《深入浅出Spring Security》的笔记

  • 作者:buffeer
  • 原文链接:https://blog.csdn.net/buffeer/article/details/120768488
    更新时间:2022-09-20 08:37:32