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

论坛 期权论坛 脚本     
niminba   2021-5-26 11:07   749   0

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

数据库 user 表

在这里插入图片描述

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

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

数据库 role 表

在这里插入图片描述

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


role_user 表

在这里插入图片描述


实体类 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;
 }

}

到此这篇关于SpringSecurity从数据库中获取用户信息进行验证的文章就介绍到这了,更多相关SpringSecurity数据库获取用户信息验证内容请搜索社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持社区!

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP