Spring Security 入门
本节介绍如何使用 Spring Security 与 Spring Boot 进行最小化设置,并指引您后续步骤。
完整的入门应用程序可以在 我们的示例存储库中找到。为方便起见,您可以下载一个由 Spring Initializr 准备的最小 Spring Boot + Spring Security 应用程序。 |
启动 Spring Security Boot 入门程序
将 Spring Security 添加到类路径 后,您现在可以 运行 Spring Boot 应用程序。以下代码片段显示了一些指示 Spring Security 在您的应用程序中启用的输出
-
Maven
-
Gradle
-
Jar
$ ./mvnw spring-boot:run
...
INFO 23689 --- [ restartedMain] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 8e557245-73e2-4286-969a-ff57fe326336
...
$ ./gradlew :bootRun
...
INFO 23689 --- [ restartedMain] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 8e557245-73e2-4286-969a-ff57fe326336
...
$ java -jar target/myapplication-0.0.1.jar
...
INFO 23689 --- [ restartedMain] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 8e557245-73e2-4286-969a-ff57fe326336
...
现在它已经运行,您可以尝试访问一个端点以查看会发生什么。如果您访问没有凭据的端点,如下所示
$ curl -i https://127.0.0.1:8080/some/path
HTTP/1.1 401
...
则 Spring Security 将返回 401 Unauthorized
,拒绝访问。
如果您在浏览器中提供相同的 URL,它将重定向到默认登录页面。 |
如果您使用凭据(在控制台输出中找到)访问端点,如下所示
$ curl -i -u user:8e557245-73e2-4286-969a-ff57fe326336 https://127.0.0.1:8080/some/path
HTTP/1.1 404
...
则 Spring Boot 将服务请求,在此例中返回 404 Not Found
,因为 /some/path
不存在。
接下来,您可以
-
开始配置 身份验证
运行时预期
Spring Boot 和 Spring Security 的默认配置在运行时提供以下行为
-
需要经过身份验证的用户 才能访问任何端点(包括 Boot 的
/error
端点) -
注册一个默认用户,并在启动时生成密码(密码将记录到控制台;在前面的示例中,密码是
8e557245-73e2-4286-969a-ff57fe326336
) -
使用 BCrypt 等方法保护 密码存储
-
提供内容协商;对于 Web 请求,重定向到登录页面;对于服务请求,返回
401 Unauthorized
-
减轻 CSRF 攻击
-
减轻会话固定 攻击
-
写入 X-Content-Type-Options 以减轻 嗅探攻击
-
写入 缓存控制头 以保护经过身份验证的资源
-
写入 X-Frame-Options 以减轻 Clickjacking
-
发布 身份验证成功和失败事件
了解 Spring Boot 如何与 Spring Security 协同工作来实现这一点非常有帮助。查看Boot 的安全自动配置,它执行以下操作(为了说明目的进行了简化)
@EnableWebSecurity (1)
@Configuration
public class DefaultSecurityConfig {
@Bean
@ConditionalOnMissingBean(UserDetailsService.class)
InMemoryUserDetailsManager inMemoryUserDetailsManager() { (2)
String generatedPassword = // ...;
return new InMemoryUserDetailsManager(User.withUsername("user")
.password(generatedPassword).roles("USER").build());
}
@Bean
@ConditionalOnMissingBean(AuthenticationEventPublisher.class)
DefaultAuthenticationEventPublisher defaultAuthenticationEventPublisher(ApplicationEventPublisher delegate) { (3)
return new DefaultAuthenticationEventPublisher(delegate);
}
}
-
添加
@EnableWebSecurity
注解。(除其他事项外,这将Spring Security 的默认Filter
链作为@Bean
发布) -
发布一个带有用户名
user
和随机生成的(并记录到控制台)密码的UserDetailsService
@Bean
-
发布一个用于发布身份验证事件的
AuthenticationEventPublisher
@Bean
Spring Boot 将任何作为@Bean 发布的Filter 添加到应用程序的过滤器链中。这意味着结合使用@EnableWebSecurity 和 Spring Boot 会自动为每个请求注册 Spring Security 的过滤器链。 |
安全用例
您可以从这里继续进行许多操作。为了弄清楚接下来要做什么以及您的应用程序接下来需要什么,请考虑 Spring Security 旨在解决的这些常见用例
-
我正在构建一个 REST API,我需要验证 JWT或其他 Bearer 令牌
-
我正在构建一个 Web 应用程序、API 网关或 BFF,并且
-
我需要管理
-
在LDAP或Active Directory中的用户,使用Spring Data,或使用JDBC
-
如果以上情况都不符合您的需求,请考虑按以下顺序考虑您的应用程序:
-
协议:首先,考虑您的应用程序将使用哪个协议进行通信。对于基于 servlet 的应用程序,Spring Security 支持 HTTP 以及WebSockets。
-
身份验证:接下来,考虑用户将如何进行身份验证,以及该身份验证是状态化的还是无状态的。
-
授权:然后,考虑如何确定用户被授权执行哪些操作
-
防御:最后,与 Spring Security 的默认保护措施集成,并考虑您需要哪些额外的保护措施