Java Spring Boot 应用集成 Spring Security 使用 Redis 存储用户信息

发布于:2025-05-24 ⋅ 阅读:(15) ⋅ 点赞:(0)


在现代 Web 开发中,使用 Redis 存储用户信息不仅可以提高系统的性能,还能有效降低数据库的访问压力。本文将介绍如何在 Spring Boot 应用中集成 Spring Security,并使用 Redis 存储用户信息,实现高效的用户认证和授权。

一、项目依赖

pom.xml 中添加以下依赖:

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

二、配置 Redis

application.properties 文件中添加 Redis 配置:

# Redis 配置
spring.redis.host=localhost
spring.redis.port=6379

三、配置 Spring Security

创建一个配置类 SecurityConfig.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/", "/home", "/login").permitAll()
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/home", true)
            .and()
            .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout");
    }

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

四、配置 Redis 存储用户信息

创建一个 RedisConfig.java 配置类:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return template;
    }
}

五、创建用户详情服务

创建一个 CustomUserDetailsService.java 类:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

@Service
public class CustomUserDetailsService implements UserDetailsService {

    private final RedisTemplate<String, Object> redisTemplate;
    private final PasswordEncoder passwordEncoder;

    @Autowired
    public CustomUserDetailsService(RedisTemplate<String, Object> redisTemplate, PasswordEncoder passwordEncoder) {
        this.redisTemplate = redisTemplate;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 尝试从 Redis 中获取用户信息
        Object user = redisTemplate.opsForValue().get("user:" + username);
        if (user != null) {
            return new org.springframework.security.core.userdetails.User(
                    username,
                    passwordEncoder.encode("123456"),
                    Collections.emptyList());
        }

        // 如果 Redis 中没有用户信息,可以从数据库加载(此处简化为直接返回)
        return new org.springframework.security.core.userdetails.User(
                username,
                passwordEncoder.encode("123456"),
                Collections.emptyList());
    }

    // 可以添加方法将用户信息存储到 Redis
    public void saveUserToRedis(String username, Object user, long expirationInMinutes) {
        redisTemplate.opsForValue().set("user:" + username, user, expirationInMinutes, TimeUnit.MINUTES);
    }
}

六、创建控制器

创建一个 LoginController.java 类:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LoginController {

    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @GetMapping("/home")
    public String home() {
        return "home";
    }
}

七、创建登录页面

src/main/resources/templates 目录下创建 login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <h2>Login</h2>
    <form action="/login" method="post">
        <div>
            <label for="username">Username:</label>
            <input type="text" id="username" name="username">
        </div>
        <div>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password">
        </div>
        <div>
            <button type="submit">Login</button>
        </div>
    </form>
</body>
</html>

八、总结

通过本文的介绍,你已经掌握了如何在 Spring Boot 应用中集成 Spring Security,并使用 Redis 存储用户信息。使用 Redis 存储用户信息可以提高系统的性能和响应速度,特别是在用户数量较多的情况下。希望本文的内容能够帮助你更好地应用 Spring Security 和 Redis,构建高效、安全的 Web 应用。


网站公告

今日签到

点亮在社区的每一天
去签到