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

 更新时间:2021年01月26日 11:29:13   作者:BLUcoding  
这篇文章主要介绍了SpringSecurity从数据库中获取用户信息进行验证的案例详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

基于 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数据库获取用户信息验证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Mybatis反射核心类Reflector的实现

    Mybatis反射核心类Reflector的实现

    本文主要介绍了Mybatis反射核心类Reflector的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-11-11
  • 通过实例解析java过滤器和拦截器的区别

    通过实例解析java过滤器和拦截器的区别

    这篇文章主要介绍了通过实例解析java过滤器和拦截器的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • java随机抽取指定范围内不重复的n个数

    java随机抽取指定范围内不重复的n个数

    这篇文章主要为大家详细介绍了java随机抽取指定范围内不重复的n个数,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • MyBatis方法重载的陷阱及解决方案

    MyBatis方法重载的陷阱及解决方案

    在使用 MyBatis 进行开发时,尤其是使用注解模式(如 @Select、@Insert 等)时,开发者常常会遇到这样一个问题:为什么我的方法重载不能正常工作?这篇文章将深入探讨 MyBatis 的这个特性及如何规避相关的坑,需要的朋友可以参考下
    2024-09-09
  • Java Condition条件变量提高线程通信效率

    Java Condition条件变量提高线程通信效率

    这篇文章主要介绍了Java Condition条件变量提高线程通信效率,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Spring Cloud 服务网关Zuul的实现

    Spring Cloud 服务网关Zuul的实现

    这篇文章主要介绍了Spring Cloud 服务网关Zuul的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • IntelliJ IDEA将导入的项目转成maven项目

    IntelliJ IDEA将导入的项目转成maven项目

    这篇文章主要介绍了IntelliJ IDEA将导入的项目转成maven项目,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • 关于SpringBoot拦截器拦截静态资源的问题

    关于SpringBoot拦截器拦截静态资源的问题

    这篇文章主要介绍了关于SpringBoot拦截器拦截静态资源的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • ElasticSearch添加索引代码实例解析

    ElasticSearch添加索引代码实例解析

    这篇文章主要介绍了ElasticSearch添加索引代码实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • MyBatis Puls统一封装前端传递的分页排序实例

    MyBatis Puls统一封装前端传递的分页排序实例

    这篇文章主要为大家介绍了MyBatis Puls统一封装前端传递的分页排序实现实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12

最新评论