SpringSecurity-------基于数据库的认证流程

1. 环境准备

        SpringSecurity6

SpringSecurity认证有两种方式:

基于内存:

        这种方式是在程序运行前,就将用户信息在配置类中进行配置,用户信息都是固定的,这种方式用的少。

基于数据库:

        首先添加一个配置类:SecurityConfig

@Configuration 把该类放到Spring容器中

@EnableWebSecurity 开始Security.

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private UmsSysUserDetailsService sysUserDetailsService;

    /**
     * 配置过滤器链,对login接口放行
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf(csrf -> csrf.disable());
        // 放行login接口
        http.authorizeHttpRequests(auth -> auth.requestMatchers("/auth/**").permitAll()
                .anyRequest().authenticated()
        );
        return http.build();
    }

    /**
     * AuthenticationManager:负责认证的
     * DaoAuthenticationProvider:负责将 sysUserDetailsService、passwordEncoder融合起来送到AuthenticationManager中
     * @param passwordEncoder
     * @return
     */
    @Bean
    public AuthenticationManager authenticationManager(PasswordEncoder passwordEncoder) {

        //
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();


        provider.setUserDetailsService(sysUserDetailsService);
        // 关联使用的密码编码器
        provider.setPasswordEncoder(passwordEncoder);
        // 将provider放置进 AuthenticationManager 中,包含进去
        ProviderManager providerManager = new ProviderManager(provider);

        return providerManager;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

      编写Controller、Service、mapper和实体类。实体类需要实现 UserDetails,Service层需要实现UserDetailsService接口,实现loadUserByUsername方法。细节后面说。

2. 认证流程

Service层的login方法:

SpringSecurity中的认证要放到Authentication中,常用的实现类:UsernamePasswordAuthenticationToken 和 RememberMeAuthenticationToken,调用authenticationManager的authenticate方法,进行认证。

进入authenticate(ProviderManager.java)方法:

providerManager是AuthenticationManager的一个实现类,可以拿到providers,provider在哪里获取的呢???--------SecurityConfig中配置的。

    /**
     * AuthenticationManager:负责认证的
     * DaoAuthenticationProvider:负责将 sysUserDetailsService、passwordEncoder融合起来送到AuthenticationManager中
     * @param passwordEncoder
     * @return
     */
    @Bean
    public AuthenticationManager authenticationManager(PasswordEncoder passwordEncoder) {

        //
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();


        provider.setUserDetailsService(sysUserDetailsService);
        // 关联使用的密码编码器
        provider.setPasswordEncoder(passwordEncoder);
        // 将provider放置进 AuthenticationManager 中,包含进去
        ProviderManager providerManager = new ProviderManager(provider);

        return providerManager;
    }

DaoAuthenticationProvider 是基于数据库进行认证的。

继续下一步:

拿到provider调用authenticate方法,点进去是DaoAuthenticationProvider 的父类 AbstractUserDetailsAuthenticationProvider的一个方法。

这里有个断言,必须是UsernamePasswordAuthenticationToken才能够通过。        

继续:

retrieveUser 到了这个方法,进去。

可以看到方法的返回值是:UserDetails,我们的实体类就是实现了这个接口,也就是说这个方法的结果就是加载目的用户信息。

继续往下:

这里的loadUserByUsername方法,就是我们需要自己写的逻辑代码。

这个Service可以和login方法所在的Service写在一起,但是要注意循环依赖的问题,这里分开写的。

跳进去验证一下:

在这个方法里面,你可以自定义实现逻辑代码,最后返回实现了UserDetails的实体类。

到了后面如果返回的UserDetails是null,则抛出异常,认证失败;不是null就封装AUthentication,并把认证状态改成true。

3. 流程图

4. 最后

代码来源:

最新SpringSecurity6.1.5-基于Vue3实现前后端分离动态权限、路由_哔哩哔哩_bilibili

如有错误,请指正!

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值