Springboot 系列 (13) - Springboot+Redis(二) | 使用 Lettuce 实现用户验证实例

 

Lettuce 是一个可扩展的线程安全 Redis 客户端,用于同步、异步和反应式使用。如果多个线程避免阻塞和事务性操作(如 BLPOP 和 MULTI/EXEC ),则它们可能共享一个连接。Lettuce 是基于 Netty 框架,支持高级 Redis 功能,如 Sentinel、群集、管道、自动重新连接和 Redis 数据模型。

本文使用 Redis 的 Lettuce 客户端实现用户验证实例。

Lettuce:https://lettuce.io/
Lettuce GitHub:https://github.com/lettuce-io/lettuce-core


1. 开发环境

    Windows版本:Windows 10 Home (20H2)   
    IntelliJ IDEA (https://www.jetbrains.com/idea/download/):Community Edition for Windows 2020.1.4
    Apache Maven (https://maven.apache.org/):3.8.1

    注:Spring 开发环境的搭建,可以参考 “ Spring基础知识(1)- Spring简介、Spring体系结构和开发环境配置 ”。


2. 创建 Spring Boot 基础项目


    项目实例名称:SpringbootExample13
    Spring Boot 版本:2.6.6

    创建步骤:

        (1) 创建 Maven 项目实例 SpringbootExample13;
        (2) Spring Boot Web 配置;
        
    具体操作请参考 “Springboot 系列 (2) - 在 Spring Boot 项目里使用 Thymeleaf、JQuery+Bootstrap 和国际化” 里的项目实例 SpringbootExample02,文末包含如何使用 spring-boot-maven-plugin 插件运行打包的内容。

    SpringbootExample13 和 SpringbootExample02 相比,SpringbootExample13 不导入 Thymeleaf 依赖包,也不配置 jQuery、Bootstrap、模版文件(templates/*.html)和国际化。


3. 配置 Lettuce

    1) 修改 pom.xml,导入 Lettuce 依赖包

复制代码
 1         <project ... >
 2             ...
 3             <dependencies>
 4                 ...
 5 
 6                 <dependency>
 7                     <groupId>io.lettuce</groupId>
 8                     <artifactId>lettuce-core</artifactId>
 9                     <version>6.1.6.RELEASE</version>
10                 </dependency>
11 
12                 ...
13             </dependencies>
14 
15             ...
16         </project>
复制代码


        在IDE中项目列表 -> SpringbootExample13 -> 点击鼠标右键 -> Maven -> Reload Project

    2) 修改 src/main/resources/application.properties 文件,添加如下配置

        # redis
        spring.redis.database=0
        spring.redis.host=localhost
        spring.redis.port=6379
        spring.redis.password=123456
        spring.redis.timeout=5000
        spring.redis.pool.max-active=10
        spring.redis.pool.max-idle=10
        spring.redis.pool.max-wait=-1
        spring.redis.sentinel.master=
        spring.redis.sentinel.nodes=

        注:max-wait 使用负值表示没有限制(或称无穷大)

    3) 创建 src/main/java/com/example/config/LettuceConfig.java 文件

复制代码
 1         package com.example.config;
 2 
 3         import org.springframework.context.annotation.Bean;
 4         import org.springframework.context.annotation.Configuration;
 5         import org.springframework.beans.factory.annotation.Value;
 6 
 7         import io.lettuce.core.RedisURI;
 8         import io.lettuce.core.RedisClient;
 9 
10         @Configuration
11         public class LettuceConfig {
12             @Value("${spring.redis.database}")
13             private Integer database;
14             @Value("${spring.redis.host}")
15             private String host;
16             @Value("${spring.redis.port}")
17             private Integer port;
18             @Value("${spring.redis.password}")
19             private String password;
20             @Value("${spring.redis.timeout}")
21             private Integer timeout;
22             @Value("${spring.redis.pool.max-active}")
23             private Integer maxActive;
24             @Value("${spring.redis.pool.max-idle}")
25             private Integer maxIdle;
26 
27             @Bean
28             public RedisClient redisClientBean(){
29 
30                 RedisURI redisUri = RedisURI.Builder.redis("localhost")
31                                     .withPort(port)
32                                     .withPassword(password)
33                                     .withDatabase(database)
34                                     .build();
35 
36                 return RedisClient.create(redisUri);
37             }
38 
39         }
复制代码


    4) 修改 src/main/java/com/example/controller/IndexController.java 文件

复制代码
 1         package com.example.controller;
 2 
 3         import org.springframework.beans.factory.annotation.Autowired;
 4         import org.springframework.stereotype.Controller;
 5         import org.springframework.web.bind.annotation.RequestMapping;
 6         import org.springframework.web.bind.annotation.ResponseBody;
 7 
 8         import io.lettuce.core.RedisClient;
 9         import io.lettuce.core.api.StatefulRedisConnection;
10         import io.lettuce.core.api.sync.RedisCommands;
11 
12         @Controller
13         public class IndexController {
14             @Autowired
15             private RedisClient redisClient;
16 
17             @ResponseBody
18             @RequestMapping("/test")
19             public String test() {
20 
21                 StatefulRedisConnection<String, String> connection = redisClient.connect();
22                 RedisCommands<String, String> commands = connection.sync();
23 
24                 String str = commands.get("lettuce");
25 
26                 connection.close();
27                 //redisClient.shutdown();
28 
29                 return "Test Page: " + str;
30             }
31 
32         }
复制代码


    5) 运行

        (1) 创建 Redis Key
        
            启动一个 cmd 窗口,运行如下命令。

            C:\> redis-cli.exe -h 127.0.0.1 -p 6379

                127.0.0.1:6379> AUTH "123456"
                OK
                127.0.0.1:6379> SET lettuce "Redis Lettuce Demo"
                OK

        (2) 测试

            访问 http://localhost:9090/test,页面显示:

                Test Page: Redis Lettuce Demo


4. 配置 Security

    1) 修改 pom.xml,导入 Security 依赖包

复制代码
 1         <project ... >
 2             ...
 3             <dependencies>
 4                 ...
 5 
 6                 <!-- Spring security -->
 7                 <dependency>
 8                     <groupId>org.springframework.boot</groupId>
 9                     <artifactId>spring-boot-starter-security</artifactId>
10                 </dependency>
11 
12                 ...
13             </dependencies>
14 
15             ...
16         </project>
复制代码


        在IDE中项目列表 -> SpringbootExample13 -> 点击鼠标右键 -> Maven -> Reload Project

     2) 修改 src/main/resources/application.properties 文件,添加如下配置

        # security
        spring.security.user.name=admin
        spring.security.user.password=123456
        spring.security.user.roles=admin

        运行并访问 http://localhost:9090/test,自动跳转到 http://localhost:9090/login (Spring security 的默认页面),输入上面的用户名和密码登录,登录后跳转到 http://localhost:9090/test。

    3) 创建 src/main/java/com/example/service/RedisUserDetailsService.java 文件

复制代码
 1         package com.example.service;
 2 
 3         import java.util.List;
 4         import java.util.ArrayList;
 5 
 6         import org.springframework.beans.factory.annotation.Autowired;
 7         import org.springframework.context.annotation.Configuration;
 8         import org.springframework.security.core.userdetails.User;
 9         import org.springframework.security.core.userdetails.UserDetails;
10         import org.springframework.security.core.userdetails.UserDetailsService;
11         import org.springframework.security.core.userdetails.UsernameNotFoundException;
12         import org.springframework.security.core.GrantedAuthority;
13 
14         import io.lettuce.core.RedisClient;
15         import io.lettuce.core.api.StatefulRedisConnection;
16         import io.lettuce.core.api.sync.RedisCommands;
17 
18         @Configuration
19         public class RedisUserDetailsService implements UserDetailsService {
20             @Autowired
21             private RedisClient redisClient;
22 
23             @Override
24             public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
25 
26                 StatefulRedisConnection<String, String> connection = redisClient.connect();
27                 RedisCommands<String, String> commands = connection.sync();
28 
29                 String password = commands.get(username);
30 
31                 connection.close();
32 
33                 List<GrantedAuthority> authorities = new ArrayList<>();
34 
35                 User userDetails= new User(username, password, authorities);
36                 return userDetails;
37             }
38         }
复制代码

   
    4) 创建 src/main/java/com/example/config/WebSecurityConfig.java 文件

复制代码
 1        package com.example.config;
 2 
 3         import org.springframework.context.annotation.Bean;
 4         import org.springframework.beans.factory.annotation.Autowired;
 5         import org.springframework.context.annotation.Configuration;
 6         import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 7         import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 8         //import org.springframework.security.core.userdetails.UserDetailsService;
 9         import com.example.service.RedisUserDetailsService;
10         import org.springframework.security.crypto.password.NoOpPasswordEncoder;
11         import org.springframework.security.crypto.password.PasswordEncoder;
12 
13         @Configuration
14         public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
15             @Autowired
16             //private UserDetailsService userDetailsService;
17             private RedisUserDetailsService redisUserDetailsService;
18 
19             @Override
20             protected void configure(AuthenticationManagerBuilder auth) throws Exception {
21                 //auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
22                 auth.userDetailsService(redisUserDetailsService).passwordEncoder(passwordEncoder());
23             }
24 
25             @Bean
26             public PasswordEncoder passwordEncoder(){
27                 return NoOpPasswordEncoder.getInstance();
28             }
29         }
复制代码


    5) 运行

        (1) 创建 Redis Key
        
            启动一个 cmd 窗口,运行如下命令。

            C:\> redis-cli.exe -h 127.0.0.1 -p 6379

                127.0.0.1:6379> AUTH "123456"
                OK
                127.0.0.1:6379> SET user "user"
                OK

        (2) 测试

            运行并访问 http://localhost:9090/test,自动跳转到 http://localhost:9090/login (Spring security 的默认页面),输入用户/密码: user/user,登录后跳转到 http://localhost:9090/test。

            注:此时 application.properties 里设置的用户/密码(admin/123456)无法登录。



posted @   垄山小站  阅读(588)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
点击右上角即可分享
微信分享提示