SpringSecurity数据库获取用户信息验证 SpringSecurity从数据库中获取用户信息进行验证的案例详解
BLUcoding 人气: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; } }
加载全部内容