SpringSecurity - WebFlux环境下实现用户动态认证

Posted 小毕超

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringSecurity - WebFlux环境下实现用户动态认证相关的知识,希望对你有一定的参考价值。

一、SpringSecurity - WebFlux

上篇文章我们讲解了SpringSecurity 整合JWT使用 Token 的方式认证授权,但是从前面的学习中应该可以发现,我们是在SpringMVC环境下实现的,所写的过滤器都是基于Servlet的。我们也知道Spring很早就退出了WebFlux异步非阻塞的web框架,是基于Netty实现的一款高性能的web框架,性能要比SpringMVC高的多,还有现在我们常用的SpringGateWay网关也是基于WebFlux框架实现的,而在WebFlux环境下的认证授权就和前面基于SpringMVC的方式不太一样了,整体来说相差不大,但有些地方实现起来还是有差异,所以本篇文章我们一起学习下WebFlux环境下的用户动态认证,在后面的文章我会继续讲解WebFlux环境下的动态角色权限,及整合JWT使用Token的方式认证授权。

在学习本篇文章最好已经了解了SpringSecurity ,不了解的可以看下本专栏的其他讲解SpringSecurity的博客,下面是上篇文章的地址:

https://blog.csdn.net/qq_43692950/article/details/122396221

二、环境搭建准备

新建一个SpringBoot项目,在pom中引入以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

下面新建两个测试接口,后面就使用这个接口做测试:

@RestController
public class TestController 

    @GetMapping("/admin/test")
    public Mono<String> adminTest()
        return Mono.just("success : /admin/test ");
    

    @GetMapping("/common/test")
    public Mono<String> commonTest()
        return Mono.just("success : /common/test ");
    

启动项目,在浏览器请求我们的接口:http://localhost:8080/admin/test

看到这个页面,我们应该就熟悉了,和前面讲用户认证的时候也是出现这个页面,这里的密码也是打印在了控制台中:

用户名默认user,输入上面控制台打印的密码,就可以访问接口了:

这里的用户名密码还是和前面讲的一样,我们可以配制在配制文件中也可以,在使用程序配制的方式配制,比如可以加上下面这个配制类。

@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfig 

    @Bean
    public ReactiveUserDetailsService userDetailsService() 
        UserDetails user = User.withUsername("admin").password(passwordEncoder().encode("1234")).authorities("admin").build();
        return new MapReactiveUserDetailsService(user);
    

    @Bean
    PasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    

再次启动项目,就可以使用admin用户来登录了:


显然使用上面这些用户认证方式,都达不到我们想要的效果,在前面的文章中我们都是基于数据库的认证,同样在WebFlux中也要使用数据库,下面我们就看下使用数据库的方式认证。

三、数据库的方式认证

在这里我们还是使用在前几篇文章中创建的表,包括实体类,这里就不把代码给复制进来了。

在前面做数据库认证的时候我们是创建一个UserService并实现了UserDetails 接口,在Webflux中就不是UserDetails ,现在要换成ReactiveUserDetailsService接口了,整个接口中只有一个抽象方法findByUsername,其中传入的参数还是和前面的一致,是用户名,我们可以根据用户名查询到用户的信息及角色或权限,返回出去,对于返回是一个Mono但其中的类型还是和前面的一致,都是UserDetails对象。

下面我们写一个UserDetailService来实现ReactiveUserDetailsService接口:

@Service
public class UserDetailService implements ReactiveUserDetailsService 
    @Autowired
    UserMapper userMapper;

    @Autowired
    RoleMapper roleMapper;

    @Override
    public Mono<UserDetails> findByUsername(String username) 
        return Mono.fromCallable(()->
            LambdaQueryWrapper<UserEntity> wrapper = new LambdaQueryWrapper<UserEntity>()
                    .eq(UserEntity::getUsername, username);
            UserEntity userEntity = userMapper.selectOne(wrapper);
            if (userEntity == null) 
                throw new UsernameNotFoundException("用户不存在!");
            
            List<GrantedAuthority> auths = roleMapper.getAllRoleByUserId(userEntity.getId())
                    .stream()
                    .map(r -> new SimpleGrantedAuthority(r.getRole()))
                    .collect(Collectors.toList());
            userEntity.setRoles(auths);
            return userEntity;
        );
    

其中的逻辑和前面的完全一致,下面修改SecurityConfig配制:

@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfig 

    @Autowired
    UserDetailService userDetailService;

    @Bean
    public ReactiveAuthenticationManager authenticationManager() 
        UserDetailsRepositoryReactiveAuthenticationManager authenticationManager = new UserDetailsRepositoryReactiveAuthenticationManager(userDetailService);
        authenticationManager.setPasswordEncoder(passwordEncoder());
        return authenticationManager;
    

    @Bean
    PasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    

再次启动项目,就可以使用数据库中的用户认证了:



喜欢的小伙伴可以关注我的个人微信公众号,获取更多学习资料!

以上是关于SpringSecurity - WebFlux环境下实现用户动态认证的主要内容,如果未能解决你的问题,请参考以下文章

SpringSecurity - WebFlux环境下实现用户动态认证

SpringSecurity系列4基于Spring Webflux集成SpringSecurity实现前后端分离无状态Rest API的权限控制原理分析

WebFlux 和 Spring Security 会碰出哪些火花?

WebFlux 和 Spring Security 会碰出哪些火花?

在 Spring WebFlux 中使用 Spring Security 实现身份验证的资源是啥

Spring Security WebFlux IP 白名单