只写一下技术点,琐碎的东西就不提了
和手动配置用户名和密码相比,基于数据库认证多了几个东西。
UserDetail和UserDetailService。两个的作用分别是什么呢。
翻一下文档。两个都是org.springframework.security.core.userdetails包下的。
UserDetail的作用是:提供核心用户信息。
出于安全目的,Spring Security不会直接使用实现。 它们只是存储用户信息,这些信息随后被封装到Authentication对象中。 这允许将与安全无关的用户信息(例如电子邮件地址,电话号码等)存储在方便的位置。
具体实现必须格外小心,以确保为每种方法强制执行详细的非空合同。 请参阅用户以获取参考实现(您可能希望在代码中对其进行扩展或使用)。
也就是说,当实体类实现了这个接口,那么原本需要手动配置的用户名和密码等信息都会通过数据库查询后存储到该实体类中,并封装到Authentication对象。
UserDetail对象中有以下几个方法,分别为:
//获取查询用户的所有角色,例如admin,user之类的
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
//账户是否没有过期
boolean isAccountNonExpired();
//账户是否没被锁定
boolean isAccountNonLocked();
//密码是否没有过期
boolean isCredentialsNonExpired();
//账户是否禁用
boolean isEnabled();
不是很难理解蛤
UserDetailService对象的作用是:加载用户特定数据的核心接口。
它在整个框架中都用作用户DAO,并且是DaoAuthenticationProvider使用的策略。
该接口仅需要一种只读方法,从而简化了对新数据访问策略的支持。
在本案例里定义的UserService类只需要实现这个接口即可。
接口中有一个方法loadUserByUsername()该方法的作用是根据用户名加载用户信息
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.loadUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("用户不存在!");
}
user.setRoles(userMapper.getUserRolesById(user.getId()));
return user;
}
都写好之后,在配置类里再添加一些信息就可以了
在参数为AuthenticationManagerBuilder的方法中将UserService配置进去
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService);
}
userDetailsService这个方法的作用是根据传入的自定义UserDetailsService添加身份验证。然后,它返回DaoAuthenticationConfigurer以允许自定义身份验证。
此方法还确保UserDetailsService可用于getDefaultUserDetailsService()方法。 请注意,其他UserDetailsService可能会覆盖此UserDetailsService作为默认值。
剩下配置以下请求规则就🉑️
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/dba/**").hasRole("dba")
.antMatchers("/admin/**").hasRole("admin")
.antMatchers("/user/**").hasRole("user")
.and()
.formLogin()
.permitAll()
.and()
.csrf()
.disable();
}