01 - SpringSecurity实现数据库登录
环境: springboot 3.4.2, springsecurity 6.4.2, mybatis 3.0.4
-
springsecurity中的
UserDetails
接口用于表示用户信息, 包含用户名、密码等信息。
-
UserDetailsService
接口用于加载用户信息, 里边就这一个方法public interface UserDetailsService {UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; }
SpringSecurity的过滤器链(
FilterChainProxy
)会拦截请求。登陆时主要的过滤器是UsernamePasswordAuthenticationFilter
, 它负责处理用户名和密码的认证(从请求中提取用户名和密码,并将其封装为一个UsernamePasswordAuthenticationToken
对象, 然后交由security内其他filter使用)。具体内部过程还是挺长的, 那我们能为springsecurity做什么呢?
能做的不多, 主要是自定义一个类实现
UserDetailsService
接口, 重写它的loadUserByUsername
方法, 我这里的UserService
接口继承了UserDetailsService
该方法根据name从数据库中找到用户信息, 将其封装成一个User对象(注意这里的User类不是自己定义的, 而是SpringSecurity的User类, 它是UserDetails
的实现类), 最后将这个对象返回给SpringSecurity。
SpringSecurity内部根据我们返回的userDetails
对象和用户输入的用户名密码比对(当然中间也会有用户权限的审查, 也就是UserDetails里那些boolean方法的调用), 如果都通过了, 返回响应成功。
这里还要写一个SecurityConfig
配置类, 注入PasswordEncoder
Bean, springsecurity内部会调用passwordEncoder
将用户输入的密码进行加密, 将加密后的密码与我们返回的userDetails
对象的密码比较(数据库中密码存的是密文, 密文和密文比较, 没毛病)。
总之, springsecurity有自己的一套用户概念, 自己的规则, 也可以自定义UserDetails
的实现类, 将自己定义的User对象聚合进去。
然后loadUserByUsername
方法返回自定义的类的对象
问题:
loadUserByUsername方法是根据用户输入的用户名从数据库中找对应的用户的, 如果重名怎么办?
- 不允许用户名重名, 注册时规定好。
- 允许重名, 但该方法的参数采用唯一标识如email、phone, 根据唯一标志从数据库中查找对应用户。