Servlet 应用(Servlet Applications)
SpringSecurity 通过使用标准的 Servlet 过滤器与 Servlet 容器集成。这意味着它适用于运行在 Servlet 容器中的任何应用程序。具体地说,您不需要在基于 Servlet 的应用程序中使用 Spring 来利用 Spring Security。
Hello Spring Security
本节介绍如何使用 SpringSecurity 和 SpringBoot 的最低设置,然后为您指出后面的步骤。
更新依赖(Updating Dependencies)
您首先需要将 SpringSecurity 添加到应用程序的类路径中; 有两种方法可以实现这一点: 使用 Maven 或 Gradle。
Starting Hello Spring Security Boot
可以查看我的博客:SpringBoot整和SpringSecurity-Hello
在类路径上有了 SpringSecurity 之后,现在就可以运行 SpringBoot 应用程序了。
下面的代码片段显示了在应用程序中启用 Spring Security 的一些输出:
Running Spring Boot Application
$ ./mvnw spring-boot:run
...
INFO 23689 --- [ restartedMain] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: 8e557245-73e2-4286-969a-ff57fe326336
现在您已经运行了它,您可以尝试命中一个端点,看看会发生什么。如果您在没有凭据的情况下访问端点,如下所示:
Querying a Secured Boot Application
$ curl -i http://localhost:8080/some/path
HTTP/1.1 401
...
那么 Spring Security使用401 Unauthorized
拒绝访问。
如果您在浏览器中提供相同的 URL,它将重定向到默认登录页面。
如果使用凭据(在控制台输出中找到)命中端点,则如下所示:
Querying with Credentials
$ curl -i -u user:8e557245-73e2-4286-969a-ff57fe326336
http://localhost:8080/some/path
HTTP/1.1 404
...
然后 Spring Boot 将为请求提供服务,在这种情况下返回一个404 Not Found,因为/some/path 不存在。
从这里,你可以:
- 更好地理解 SpringSecurity 默认情况下启动了什么(Better understand what Spring Boot enables in Spring Security by default)
- 阅读 SpringSecurity 帮助解决的常见用例(Read about common use cases that Spring Security helps with)
- 开始配置身份验证(Start configuring authentication)
Runtime Expectations
Spring Boot 和 Spring Security 的默认配置在运行时提供了以下行为:
- 任何访问端口都需要一个已经认证的用户(Requires an authenticated user for any endpoint (including Boot’s
/error
endpoint)) - 在启动时用生成的密码注册默认用户(Registers a default user with a generated password at startup (密码被记录到控制台; 在上面的例子中, the password is
8e557245-73e2-4286-969a-ff57fe326336
)) - 使用 BCrypt 和其他方法保护密码存储(Protects password storage with BCrypt as well as others)
- 提供基于表单的登录和注销流(Provides form-based login and logout flows)
- 对基于表单的登录和 HTTPBasic 进行身份验证(Authenticates form-based login as well as HTTP Basic)
- 提供内容协商; 对于 Web 请求,重定向到登录页; 对于服务请求,返回一个
401 Unauthorized
(Provides content negotiation; for web requests, redirects to the login page; for service requests, returns a401 Unauthorized
) - 减轻 CSRF 的攻击(Mitigates CSRF attacks)
- 减轻会话固定攻击(Mitigates Session Fixation attacks)
- 编写 HTTP严格传输安全以确保 HTTPS(Writes Strict-Transport-Security to ensure HTTPS)
- 写入 X-Content-Type-Options 以减轻嗅探攻击(Writes X-Content-Type-Options to mitigate sniffing attacks)
- 写入保护经过身份验证的资源的缓存控件标头(Writes Cache Control headers that protect authenticated resources)
- 写入 X-Frame-选项以减轻点击劫持(Writes X-Frame-Options to mitigate Clickjacking)
- 与 HttpServletRequest 的身份验证方法集成(Integrates with
HttpServletRequest
’s authentication methods) - 发布身份验证成功和失败事件(Publishes authentication success and failure events)
了解 SpringBoot 如何与 SpringSecurity 协调以实现这一点可能会有所帮助。查看 Boot 的 security auto configuration,它执行以下操作(简化为插图) :
Spring Boot Security Auto Configuration
@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
注解. (除此之外, 使用@Bean发布Spring Security’s defaultFilter
chain) - 发布一个
UserDetailsService
@Bean
使用用户名为user和记录到控制台的随机生成的密码(Publishes aUserDetailsService
@Bean
with a username ofuser
and a randomly generated password that is logged to the console) - 发布用于发布身份验证事件的 AuthenticationEventPublisher@Bean(Publishes an
AuthenticationEventPublisher
@Bean
for publishing authentication events)
Spring Boot 将任何发布为@Bean 的 Filter 添加到应用程序的筛选器链中。这意味着结合使用@EnableWebSecurity 和 Spring Boot 会自动为每个请求注册 Spring Security 的过滤器链。
Security Use Cases
有很多地方你可能想从这里去。为了弄清楚您和您的应用程序的下一步是什么,考虑一下 Spring Security 构建时要解决的这些常见用例:
- I am building a REST API, and I need to authenticate a JWT or other bearer token
- I am building a Web Application, API Gateway, or BFF and
- I need to login using OAuth 2.0 or OIDC
- I need to login using SAML 2.0
- I need to login using CAS
- I need to manage
- Users in LDAP or Active Directory, with Spring Data, or with JDBC
- Passwords
如果没有一个符合你的要求,你可以按照以下顺序来考虑你的申请:
- 协议(Protocol): 首先,考虑应用程序将用于通信的协议。 对于基于 servlet 的应用程序,SpringSecurity 支持 HTTP 和 Websockets。
- 认证(Authentication): 接下来,考虑用户将如何进行身份验证,以及该身份验证是有状态的还是无状态的(Next, consider how users will authenticate and if that authentication will be stateful or stateless)
- 授权(Authorization): 然后,考虑如何确定用户被授权做什么(Then, consider how you will determine what a user is authorized to do)。
- 防御(Defense): 最后,与 SpringSecurity 的默认保护集成,并考虑您需要哪些额外的保护(Finally, integrate with Spring Security’s default protections and consider which additional protections you need)