Spring Security 内存中认证

原文链接: Spring Security In-Memory Authentication - 原文作者: Ramesh Fadatare
本文采用的是意译的方式

在这篇 Spring Security 教程中,我们将学习如何配置 Spring Security,以实现在内存认证的功能。

概览

Spring Security 中的 InMemoryUserDetailsManager 实现了 UserDetailsService,以提供存储在内存中的基于用户名/密码的身份验证。InMemoryUserDetailsManager 通过实现 UserDetailsManager 接口提供对 UserDetails 的管理功能。当 Spring Security 被配置为接受用户名和密码进行身份验证时,将使用基于 UserDetails 的身份验证。

译者加:当然,我们可以通过重写 usernamepassword 的方法更改验证的字段。比如将 username 返回值为 email

Maven

Spring Boot 项目中使用 Spring Security,我们需要添加下面 Maven 依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Spring Security 配置

接下来,我们使用内存认证 的方式配置 Spring Security。我们创建名为 SpringSecurityConfig 类,并添加下面代码👇

java 复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SpringSecurityConfig {

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

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http.csrf().disable()
                .authorizeHttpRequests((authorize) -> {
                    authorize.anyRequest().authenticated();
                }).httpBasic(Customizer.withDefaults());
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService(){

        UserDetails ramesh = User.builder()
                .username("ramesh")
                .password(passwordEncoder().encode("password"))
                .roles("USER")
                .build();

        UserDetails admin = User.builder()
                .username("admin")
                .password(passwordEncoder().encode("admin"))
                .roles("ADMIN")
                .build();

        return new InMemoryUserDetailsManager(ramesh, admin);
    }
}

在这里,我们使用了 httpBasic() 方法在 SecurityFilterChain bean 中定义了基本认证。

java 复制代码
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    http.csrf().disable()
            .authorizeHttpRequests((authorize) -> {
                authorize.anyRequest().authenticated();
            }).httpBasic(Customizer.withDefaults());
    return http.build();
}

在下面的 InMemoryUserDetailsManagerJava 配置中,我们创建了两个用户并且将其存放在 InMemoryUserDetailsManager 类对象中。

java 复制代码
@Bean
public UserDetailsService userDetailsService(){

    UserDetails ramesh = User.builder()
            .username("ramesh")
            .password(passwordEncoder().encode("password"))
            .roles("USER")
            .build();

    UserDetails admin = User.builder()
            .username("admin")
            .password(passwordEncoder().encode("admin"))
            .roles("ADMIN")
            .build();

    return new InMemoryUserDetailsManager(ramesh, admin);
}

Spring SecurityInMemoryUserDetailsManager 通过实现 UserDetailsService 接口,提供了基于用户名/密码的身份验证支持,这些验证信息存放在内存中。

需要注意的是,我们使用 PasswordEncoder 来加密密码。Spring Security 中的 PasswordEncoder 接口被用来对密码进行单向转换,以确保密码安全地存储。我们使用的 BCryptPasswordEncoder 类实现了 PasswordEncoder 接口。

BCryptPasswordEncoder 类实现了 bcrypt 算法对密码进行哈希算法。

java 复制代码
@Bean
public static PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
}
java 复制代码
.password(passwordEncoder().encode("password"))

创建 REST API

为了验证上面的 Spring Security 配置,我们创建一个基于 Spring Security 的简单 REST API。嗯,如果我们只是简单添加了 Spring Security 依赖到 Spring Boot 项目中,那么 Spring Security 会默认保护程序的所有 URLs

java 复制代码
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class WelComeController {

    @GetMapping("/greeting")
    public String greeting(Authentication authentication) {

        String userName = authentication.getName();

        return "Spring Security In-memory Authentication Example - Welcome " + userName;
    }
}

使用 Postman 测试 REST API

为了测试 REST APIs,我们在头信息 basic authentication 中输入用户名和密码。

截图中,我们输入了用户名/密码为 admin/admin

总结

在这个教程中,我们学到了怎么配置 Spring Security 6 以在内存中认证。一言蔽之,我们使用了 Spring SecurityInMemoryUserDetailsManager 类,该类实现了 UserDetailsService,以提供在内存中存储用户名/密码的身份认证支持。

相关推荐
只会安静敲代码的 小周2 分钟前
uniapp上传图片时(可选微信头像、相册、拍照)
前端·微信·uni-app
老A技术联盟4 分钟前
聊一聊消息中间件的后起之秀-pulsar及其实践
后端
百锦再10 分钟前
Android Studio 中文字大小的单位详解
android·xml·java·ide·app·android studio
隐-梵14 分钟前
Android studio前沿开发--利用socket服务器连接AI实现前后端交互(全站首发思路)
android·服务器·人工智能·后端·websocket·android studio·交互
uhakadotcom16 分钟前
Langflow:零基础快速上手AI流程可视化开发工具详解与实战案例
后端·面试·github
bobz96516 分钟前
strongswan ipsec 端口使用
后端
kovlistudio19 分钟前
红宝书第四十六讲:Node.js基础与API设计解析
前端·javascript·node.js
陈哥聊测试20 分钟前
这款自研底层框架,你说不定已经用上了
前端·后端·开源
一只叫煤球的猫34 分钟前
分布式-跨服务事务一致性的常见解决方案
java·分布式·后端
蘑菇头爱平底锅36 分钟前
数字孪生-DTS-孪创城市-低空范围
前端·javascript·数据可视化