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();
    }
}

再次启动项目,就可以使用数据库中的用户认证了:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
喜欢的小伙伴可以关注我的个人微信公众号,获取更多学习资料!

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小毕超

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值