SpringSecurity从数据库中获取用户信息进行验证的案例详解

作者:BLUcoding 时间:2024-01-23 17:16:25 

基于 SpringBoot与SpringSecurity整合 案例的修改:

数据库 user 表

SpringSecurity从数据库中获取用户信息进行验证的案例详解

注,密码是由 BCrypt 算法加密对应用户名所得。


root$2a$10$uzHVooZlCWBkaGScKnpha.ZrK31NI89flKkSuTcKYjdc5ihTPtPyq
blu$2a$10$mI0TRIcNF4mg34JmH6T1KeystzTWDzWFNL5LQmmlz.fHndcwYHZGe
kaka$2a$10$/GMSSJ3AzeeBK3rBC4t8BOZ5zkfb38IlwlQl.6mYTEpf22r/cCZ1a
admin$2a$10$FKf/V.0WdHnTNWHDTtPLJe2gBxTI6TBVyFjloXG9IuH4tjebOTqcS

数据库 role 表

SpringSecurity从数据库中获取用户信息进行验证的案例详解

注:role名称必须带上前缀 ROLE_ (SpringSecurity框架要求)


role_user 表

SpringSecurity从数据库中获取用户信息进行验证的案例详解


实体类 SysUser


@Data
public class SysUser {

private Integer id;
private String name;
private String password;
}

实体类 SysRole


@Data
public class SysRole {
private Integer id;
private String name;
}

UserMapper


public interface UserMapper {

@Select("select * from user where name = #{name}")
SysUser loadUserByUsername(String name);

}

RoleMapper


public interface RoleMapper {

@Select("SELECT role.`name` FROM role WHERE role.id in (SELECT role_id FROM "
+ " role_user as r_s JOIN `user` as u ON r_s.user_id = u.id and u.id = #{id})")
List<SysRole> findRoleByUserId(int id);

}

UserService 接口

该接口需继承UserDetailsService


package com.blu.service;

import org.springframework.security.core.userdetails.UserDetailsService;

public interface UserService extends UserDetailsService {

}

UserServiceImpl 实现类


package com.blu.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
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.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.blu.entity.SysRole;
import com.blu.entity.SysUser;
import com.blu.mapper.LoginMapper;
import com.blu.mapper.UserMapper;
import com.blu.service.UserService;

@Service
@Transactional
public class UserServiceImpl implements UserService {

@Autowired
private UserMapper userMapper;

@Autowired
private RoleMapper roleMapper;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
try {
SysUser sysUser = userMapper.loadUserByUsername(username);
if(sysUser==null) {
return null;
}
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
List<SysRole> list = roleMapper.findRoleByUserId(sysUser.getId());
for(SysRole role : list) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
//封装 SpringSecurity 需要的UserDetails 对象并返回
UserDetails userDetails = new User(sysUser.getName(),sysUser.getPassword(),authorities);
return userDetails;
} catch (Exception e) {
e.printStackTrace();
//返回null即表示认证失败
return null;
}
}

}

加密类


@Bean
public BCryptPasswordEncoder bcryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}

SpringSecurity 配置类


package com.blu.config;

import org.springframework.beans.factory.annotation.Autowired;
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.crypto.bcrypt.BCryptPasswordEncoder;

import com.blu.service.impl.UserServiceImpl;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

@Autowired
private UserServiceImpl userServiceImpl;
@Autowired
private BCryptPasswordEncoder bcryptPasswordEncoder;

@Override
protected void configure(HttpSecurity http) throws Exception {

http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");

http.formLogin().loginPage("/tologin")
.usernameParameter("name")
.passwordParameter("password")
.loginProcessingUrl("/login");
http.csrf().disable();
http.logout().logoutSuccessUrl("/");
http.rememberMe().rememberMeParameter("remember");

}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userServiceImpl).passwordEncoder(bcryptPasswordEncoder);
}

}

以上方式在认证时是将数据库中查出的用户信息通过 UserServiceImpl 封装成 UserDetails 交给 SpringSecurity去认证的,我们还可以让用户实体类直接实现UserDetails:

MyUser:


package com.blu.entity;

import java.util.Collection;
import java.util.List;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import com.fasterxml.jackson.annotation.JsonIgnore;

public class MyUser implements UserDetails {

@Data
private Integer id;
private String name;
private String password;
private List<MyRole> roles;

@JsonIgnore
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {

return roles;
}

@Override
public String getPassword() {
return password;
}

@JsonIgnore
@Override
public String getUsername() {
return name;
}

@JsonIgnore
@Override
public boolean isAccountNonExpired() {
return true;
}

@JsonIgnore
@Override
public boolean isAccountNonLocked() {
return true;
}

@JsonIgnore
@Override
public boolean isCredentialsNonExpired() {
return true;
}

@JsonIgnore
@Override
public boolean isEnabled() {
return true;
}

}

MyRole:


package com.blu.entity;

import org.springframework.security.core.GrantedAuthority;
import com.fasterxml.jackson.annotation.JsonIgnore;

@Data
public class MyRole implements GrantedAuthority {

private Integer id;
private String name;

@JsonIgnore
@Override
public String getAuthority() {
return name;
}

}

MyUserMapper:


package com.blu.mapper;

import com.blu.entity.MyUser;

public interface MyUserMapper {

MyUser findByName(String name);

}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.blu.mapper.MyUserMapper">
<resultMap type="com.blu.entity.MyUser" id="myUserMap">
<id column="uid" property="id"></id>
<result column="uname" property="name"></result>
<result column="password" property="password"></result>
<collection property="roles" ofType="com.blu.entity.MyRole">
<id column="rid" property="id" />
<result column="rname" property="name" />
</collection>
</resultMap>

<select id="findByName" parameterType="String"
resultMap="myUserMap">
select u.id uid,u.name uname,u.password,r.id rid,r.name rname
from user u,role r,role_user ur
where u.name = #{name} and ur.user_id = u.id and ur.role_id = r.id
</select>
</mapper>

修改:UserServiceImpl:


package com.blu.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.blu.entity.MyUser;
import com.blu.mapper.MyUserMapper;
import com.blu.service.UserService;

@Service
public class UserServiceImpl implements UserService {

@Autowired
private MyUserMapper myUserMapper;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
MyUser myUser = myUserMapper.findByName(username);
return myUser;
}

}

来源:https://blucoding.blog.csdn.net/article/details/110727891

标签:SpringSecurity,数据库,验证
0
投稿

猜你喜欢

  • 520使用Python实现“我爱你”表白

    2022-07-16 05:25:47
  • python之tensorflow手把手实例讲解斑马线识别实现

    2021-11-11 05:53:19
  • Django配置MySQL数据库的完整步骤

    2023-07-19 14:43:47
  • tensorflow TFRecords文件的生成和读取的方法

    2022-04-04 23:21:05
  • Python实现获取汉字偏旁部首的方法示例【测试可用】

    2022-10-26 16:42:16
  • SQL“多字段模糊匹配关键字查询”

    2008-04-24 14:16:00
  • uniapp页面跳转的五种方式总结

    2023-08-23 19:46:24
  • python Tkinter的图片刷新实例

    2023-10-31 04:32:24
  • python制作图片缩略图

    2023-08-23 18:49:32
  • MYSQL启用日志和查看日志

    2010-12-03 16:24:00
  • numpy自动生成数组详解

    2023-09-02 22:53:47
  • 解决vue组件中click事件失效的问题

    2023-07-02 16:34:10
  • 在windows下使用python进行串口通讯的方法

    2022-01-03 11:10:19
  • Mysql数据库监听binlog的开启步骤

    2024-01-26 03:50:36
  • JS与jQuery判断文本框还剩多少字符可以输入的方法

    2024-04-25 13:07:20
  • ubuntu系统下 python链接mysql数据库的方法

    2024-01-19 22:05:20
  • python批量读取txt文件为DataFrame的方法

    2021-09-29 12:04:21
  • mysql查询一天,查询一周,查询一个月的数据

    2011-01-29 16:22:00
  • MySQL的查询计划中ken_len的值计算方法

    2024-01-24 13:32:49
  • 简单介绍Python中的filter和lambda函数的使用

    2023-05-30 18:18:36
  • asp之家 网络编程 m.aspxhome.com