针对 Spring Security 更新文档
This commit is contained in:
parent
0a8d3cc498
commit
dea7a01d0f
|
@ -3,4 +3,10 @@
|
|||
- [Spring Security 中文文档](index.md)
|
||||
- [要求](prerequisites.md)
|
||||
- [社区](community.md)
|
||||
- [新功能](whats-new.md)
|
||||
- [获取 Spring Security](getting-spring-security.md)
|
||||
- [特性](features/index.md)
|
||||
- [项目模块](modules.md)
|
||||
- [示例应用](samples.md)
|
||||
- [Servlet 应用程序](servlet/index.md)
|
||||
- [联系我们](CONTACT.md)
|
|
@ -0,0 +1,339 @@
|
|||
[[getting]]
|
||||
= Getting Spring Security
|
||||
|
||||
This section discusses all you need to know about getting the Spring Security binaries.
|
||||
See xref:community.adoc#community-source[Source Code] for how to obtain the source code.
|
||||
|
||||
== Release Numbering
|
||||
|
||||
Spring Security versions are formatted as MAJOR.MINOR.PATCH such that:
|
||||
|
||||
* MAJOR versions may contain breaking changes.
|
||||
Typically, these are done to provide improved security to match modern security practices.
|
||||
* MINOR versions contain enhancements but are considered passive updates
|
||||
* PATCH level should be perfectly compatible, forwards and backwards, with the possible exception of changes that fix bugs.
|
||||
|
||||
|
||||
[[maven]]
|
||||
== Usage with Maven
|
||||
|
||||
As most open source projects, Spring Security deploys its dependencies as Maven artifacts.
|
||||
The topics in this section provide detail on how to consume Spring Security when using Maven.
|
||||
|
||||
[[getting-maven-boot]]
|
||||
=== Spring Boot with Maven
|
||||
|
||||
Spring Boot provides a `spring-boot-starter-security` starter that aggregates Spring Security-related dependencies together.
|
||||
The simplest and preferred way to use the starter is to use https://docs.spring.io/initializr/docs/current/reference/html/[Spring Initializr] by using an IDE integration (https://joshlong.com/jl/blogPost/tech_tip_geting_started_with_spring_boot.html[Eclipse], https://www.jetbrains.com/help/idea/spring-boot.html#d1489567e2[IntelliJ], https://github.com/AlexFalappa/nb-springboot/wiki/Quick-Tour[NetBeans]) or through https://start.spring.io.
|
||||
|
||||
Alternatively, you can manually add the starter, as the following example shows:
|
||||
|
||||
|
||||
.pom.xml
|
||||
====
|
||||
[source,xml,subs="verbatim,attributes"]
|
||||
----
|
||||
<dependencies>
|
||||
<!-- ... other dependency elements ... -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
----
|
||||
====
|
||||
|
||||
Since Spring Boot provides a Maven BOM to manage dependency versions, you do not need to specify a version.
|
||||
If you wish to override the Spring Security version, you may do so by providing a Maven property, as the following example shows:
|
||||
|
||||
.pom.xml
|
||||
====
|
||||
[source,xml,subs="verbatim,attributes"]
|
||||
----
|
||||
<properties>
|
||||
<!-- ... -->
|
||||
<spring-security.version>{spring-security-version}</spring-security.version>
|
||||
</properties>
|
||||
----
|
||||
====
|
||||
|
||||
Since Spring Security makes breaking changes only in major releases, it is safe to use a newer version of Spring Security with Spring Boot.
|
||||
However, at times, you may need to update the version of Spring Framework as well.
|
||||
You can do so by adding a Maven property, as the following example shows:
|
||||
|
||||
.pom.xml
|
||||
====
|
||||
[source,xml,subs="verbatim,attributes"]
|
||||
----
|
||||
<properties>
|
||||
<!-- ... -->
|
||||
<spring.version>{spring-core-version}</spring.version>
|
||||
</properties>
|
||||
----
|
||||
====
|
||||
|
||||
If you use additional features (such as LDAP, OpenID, and others), you need to also include the appropriate xref:modules.adoc#modules[Project Modules and Dependencies].
|
||||
|
||||
[[getting-maven-no-boot]]
|
||||
=== Maven Without Spring Boot
|
||||
|
||||
When you use Spring Security without Spring Boot, the preferred way is to use Spring Security's BOM to ensure a consistent version of Spring Security is used throughout the entire project. The following example shows how to do so:
|
||||
|
||||
.pom.xml
|
||||
====
|
||||
[source,xml,ubs="verbatim,attributes"]
|
||||
----
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- ... other dependency elements ... -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-bom</artifactId>
|
||||
<version>{spring-security-version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
----
|
||||
====
|
||||
|
||||
A minimal Spring Security Maven set of dependencies typically looks like the following:
|
||||
|
||||
.pom.xml
|
||||
====
|
||||
[source,xml,subs="verbatim,attributes"]
|
||||
----
|
||||
<dependencies>
|
||||
<!-- ... other dependency elements ... -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
----
|
||||
====
|
||||
|
||||
If you use additional features (such as LDAP, OpenID, and others), you need to also include the appropriate xref:modules.adoc#modules[Project Modules and Dependencies].
|
||||
|
||||
Spring Security builds against Spring Framework {spring-core-version} but should generally work with any newer version of Spring Framework 5.x.
|
||||
Many users are likely to run afoul of the fact that Spring Security's transitive dependencies resolve Spring Framework {spring-core-version}, which can cause strange classpath problems.
|
||||
The easiest way to resolve this is to use the `spring-framework-bom` within the `<dependencyManagement>` section of your `pom.xml` as the following example shows:
|
||||
|
||||
.pom.xml
|
||||
====
|
||||
[source,xml,subs="verbatim,attributes"]
|
||||
----
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- ... other dependency elements ... -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>{spring-core-version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
----
|
||||
====
|
||||
|
||||
The preceding example ensures that all the transitive dependencies of Spring Security use the Spring {spring-core-version} modules.
|
||||
|
||||
NOTE: This approach uses Maven's "`bill of materials`" (BOM) concept and is only available in Maven 2.0.9+.
|
||||
For additional details about how dependencies are resolved, see https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html[Maven's Introduction to the Dependency Mechanism documentation].
|
||||
|
||||
[[maven-repositories]]
|
||||
=== Maven Repositories
|
||||
All GA releases (that is, versions ending in .RELEASE) are deployed to Maven Central, so no additional Maven repositories need to be declared in your pom.
|
||||
|
||||
If you use a SNAPSHOT version, you need to ensure that you have the Spring Snapshot repository defined, as the following example shows:
|
||||
|
||||
.pom.xml
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
<repositories>
|
||||
<!-- ... possibly other repository elements ... -->
|
||||
<repository>
|
||||
<id>spring-snapshot</id>
|
||||
<name>Spring Snapshot Repository</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
----
|
||||
====
|
||||
|
||||
If you use a milestone or release candidate version, you need to ensure that you have the Spring Milestone repository defined, as the following example shows:
|
||||
|
||||
.pom.xml
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
<repositories>
|
||||
<!-- ... possibly other repository elements ... -->
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<name>Spring Milestone Repository</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
----
|
||||
====
|
||||
|
||||
[[getting-gradle]]
|
||||
== Gradle
|
||||
|
||||
As most open source projects, Spring Security deploys its dependencies as Maven artifacts, which allows for first-class Gradle support.
|
||||
The following topics provide detail on how to consume Spring Security when using Gradle.
|
||||
|
||||
[[getting-gradle-boot]]
|
||||
=== Spring Boot with Gradle
|
||||
|
||||
Spring Boot provides a `spring-boot-starter-security` starter that aggregates Spring Security related dependencies together.
|
||||
The simplest and preferred method to use the starter is to use https://docs.spring.io/initializr/docs/current/reference/html/[Spring Initializr] by using an IDE integration (https://joshlong.com/jl/blogPost/tech_tip_geting_started_with_spring_boot.html[Eclipse], https://www.jetbrains.com/help/idea/spring-boot.html#d1489567e2[IntelliJ], https://github.com/AlexFalappa/nb-springboot/wiki/Quick-Tour[NetBeans]) or through https://start.spring.io.
|
||||
|
||||
Alternatively, you can manually add the starter, as the following example shows:
|
||||
|
||||
.build.gradle
|
||||
====
|
||||
[source,groovy]
|
||||
[subs="verbatim,attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile "org.springframework.boot:spring-boot-starter-security"
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
Since Spring Boot provides a Maven BOM to manage dependency versions, you need not specify a version.
|
||||
If you wish to override the Spring Security version, you may do so by providing a Gradle property, as the following example shows:
|
||||
|
||||
.build.gradle
|
||||
====
|
||||
[source,groovy]
|
||||
[subs="verbatim,attributes"]
|
||||
----
|
||||
ext['spring-security.version']='{spring-security-version}'
|
||||
----
|
||||
====
|
||||
|
||||
Since Spring Security makes breaking changes only in major releases, it is safe to use a newer version of Spring Security with Spring Boot.
|
||||
However, at times, you may need to update the version of Spring Framework as well.
|
||||
You can do so by adding a Gradle property, as the following example shows:
|
||||
|
||||
.build.gradle
|
||||
====
|
||||
[source,groovy]
|
||||
[subs="verbatim,attributes"]
|
||||
----
|
||||
ext['spring.version']='{spring-core-version}'
|
||||
----
|
||||
====
|
||||
|
||||
If you use additional features (such as LDAP, OpenID, and others), you need to also include the appropriate xref:modules.adoc#modules[Project Modules and Dependencies].
|
||||
|
||||
=== Gradle Without Spring Boot
|
||||
|
||||
When you use Spring Security without Spring Boot, the preferred way is to use Spring Security's BOM to ensure a consistent version of Spring Security is used throughout the entire project.
|
||||
You can do so by using the https://github.com/spring-gradle-plugins/dependency-management-plugin[Dependency Management Plugin], as the following example shows:
|
||||
|
||||
.build.gradle
|
||||
====
|
||||
[source,groovy]
|
||||
[subs="verbatim,attributes"]
|
||||
----
|
||||
plugins {
|
||||
id "io.spring.dependency-management" version "1.0.6.RELEASE"
|
||||
}
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom 'org.springframework.security:spring-security-bom:{spring-security-version}'
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
A minimal Spring Security Maven set of dependencies typically looks like the following:
|
||||
|
||||
.build.gradle
|
||||
====
|
||||
[source,groovy]
|
||||
[subs="verbatim,attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile "org.springframework.security:spring-security-web"
|
||||
compile "org.springframework.security:spring-security-config"
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
If you use additional features (such as LDAP, OpenID, and others), you need to also include the appropriate xref:modules.adoc#modules[Project Modules and Dependencies].
|
||||
|
||||
Spring Security builds against Spring Framework {spring-core-version} but should generally work with any newer version of Spring Framework 5.x.
|
||||
Many users are likely to run afoul of the fact that Spring Security's transitive dependencies resolve Spring Framework {spring-core-version}, which can cause strange classpath problems.
|
||||
The easiest way to resolve this is to use the `spring-framework-bom` within your `<dependencyManagement>` section of your `pom.xml`.
|
||||
You can do so by using the https://github.com/spring-gradle-plugins/dependency-management-plugin[Dependency Management Plugin], as the following example shows:
|
||||
|
||||
.build.gradle
|
||||
====
|
||||
[source,groovy]
|
||||
[subs="verbatim,attributes"]
|
||||
----
|
||||
plugins {
|
||||
id "io.spring.dependency-management" version "1.0.6.RELEASE"
|
||||
}
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom 'org.springframework:spring-framework-bom:{spring-core-version}'
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
The preceding example ensures that all the transitive dependencies of Spring Security use the Spring {spring-core-version} modules.
|
||||
|
||||
[[gradle-repositories]]
|
||||
=== Gradle Repositories
|
||||
All GA releases (that is, versions ending in .RELEASE) are deployed to Maven Central, so using the mavenCentral() repository is sufficient for GA releases. The following example shows how to do so:
|
||||
|
||||
.build.gradle
|
||||
====
|
||||
[source,groovy]
|
||||
----
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
If you use a SNAPSHOT version, you need to ensure you have the Spring Snapshot repository defined, as the following example shows:
|
||||
|
||||
.build.gradle
|
||||
====
|
||||
[source,groovy]
|
||||
----
|
||||
repositories {
|
||||
maven { url 'https://repo.spring.io/snapshot' }
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
If you use a milestone or release candidate version, you need to ensure that you have the Spring Milestone repository defined, as the following example shows:
|
||||
|
||||
.build.gradle
|
||||
====
|
||||
[source,groovy]
|
||||
----
|
||||
repositories {
|
||||
maven { url 'https://repo.spring.io/milestone' }
|
||||
}
|
||||
----
|
||||
====
|
|
@ -0,0 +1,249 @@
|
|||
[[servlet-architecture]]
|
||||
= Architecture
|
||||
:figures: servlet/architecture
|
||||
|
||||
This section discusses Spring Security's high level architecture within Servlet based applications.
|
||||
We build on this high level understanding within xref:servlet/authentication/index.adoc#servlet-authentication[Authentication], xref:servlet/authorization/index.adoc#servlet-authorization[Authorization], xref:servlet/exploits/index.adoc#servlet-exploits[Protection Against Exploits] sections of the reference.
|
||||
// FIXME: Add links to other sections of architecture
|
||||
|
||||
[[servlet-filters-review]]
|
||||
== A Review of ``Filter``s
|
||||
|
||||
Spring Security's Servlet support is based on Servlet ``Filter``s, so it is helpful to look at the role of ``Filter``s generally first.
|
||||
The picture below shows the typical layering of the handlers for a single HTTP request.
|
||||
|
||||
.FilterChain
|
||||
[[servlet-filterchain-figure]]
|
||||
image::{figures}/filterchain.png[]
|
||||
|
||||
The client sends a request to the application, and the container creates a `FilterChain` which contains the ``Filter``s and `Servlet` that should process the `HttpServletRequest` based on the path of the request URI.
|
||||
In a Spring MVC application the `Servlet` is an instance of {spring-framework-reference-url}web.html#mvc-servlet[`DispatcherServlet`].
|
||||
At most one `Servlet` can handle a single `HttpServletRequest` and `HttpServletResponse`.
|
||||
However, more than one `Filter` can be used to:
|
||||
|
||||
* Prevent downstream ``Filter``s or the `Servlet` from being invoked.
|
||||
In this instance the `Filter` will typically write the `HttpServletResponse`.
|
||||
* Modify the `HttpServletRequest` or `HttpServletResponse` used by the downstream ``Filter``s and `Servlet`
|
||||
|
||||
The power of the `Filter` comes from the `FilterChain` that is passed into it.
|
||||
|
||||
.`FilterChain` Usage Example
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
|
||||
// do something before the rest of the application
|
||||
chain.doFilter(request, response); // invoke the rest of the application
|
||||
// do something after the rest of the application
|
||||
}
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
|
||||
// do something before the rest of the application
|
||||
chain.doFilter(request, response) // invoke the rest of the application
|
||||
// do something after the rest of the application
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
Since a `Filter` only impacts downstream ``Filter``s and the `Servlet`, the order each `Filter` is invoked is extremely important.
|
||||
|
||||
|
||||
[[servlet-delegatingfilterproxy]]
|
||||
== DelegatingFilterProxy
|
||||
|
||||
Spring provides a `Filter` implementation named {spring-framework-api-url}org/springframework/web/filter/DelegatingFilterProxy.html[`DelegatingFilterProxy`] that allows bridging between the Servlet container's lifecycle and Spring's `ApplicationContext`.
|
||||
The Servlet container allows registering ``Filter``s using its own standards, but it is not aware of Spring defined Beans.
|
||||
`DelegatingFilterProxy` can be registered via standard Servlet container mechanisms, but delegate all the work to a Spring Bean that implements `Filter`.
|
||||
|
||||
Here is a picture of how `DelegatingFilterProxy` fits into the <<servlet-filters-review,``Filter``s and the `FilterChain`>>.
|
||||
|
||||
.DelegatingFilterProxy
|
||||
[[servlet-delegatingfilterproxy-figure]]
|
||||
image::{figures}/delegatingfilterproxy.png[]
|
||||
|
||||
`DelegatingFilterProxy` looks up __Bean Filter~0~__ from the `ApplicationContext` and then invokes __Bean Filter~0~__.
|
||||
The pseudo code of `DelegatingFilterProxy` can be seen below.
|
||||
|
||||
.`DelegatingFilterProxy` Pseudo Code
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary",subs="+quotes,+macros"]
|
||||
----
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
|
||||
// Lazily get Filter that was registered as a Spring Bean
|
||||
// For the example in <<servlet-delegatingfilterproxy-figure>> `delegate` is an instance of __Bean Filter~0~__
|
||||
Filter delegate = getFilterBean(someBeanName);
|
||||
// delegate work to the Spring Bean
|
||||
delegate.doFilter(request, response);
|
||||
}
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary",subs="+quotes,+macros"]
|
||||
----
|
||||
fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
|
||||
// Lazily get Filter that was registered as a Spring Bean
|
||||
// For the example in <<servlet-delegatingfilterproxy-figure>> `delegate` is an instance of __Bean Filter~0~__
|
||||
val delegate: Filter = getFilterBean(someBeanName)
|
||||
// delegate work to the Spring Bean
|
||||
delegate.doFilter(request, response)
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
Another benefit of `DelegatingFilterProxy` is that it allows delaying looking `Filter` bean instances.
|
||||
This is important because the container needs to register the `Filter` instances before the container can startup.
|
||||
However, Spring typically uses a `ContextLoaderListener` to load the Spring Beans which will not be done until after the `Filter` instances need to be registered.
|
||||
|
||||
[[servlet-filterchainproxy]]
|
||||
== FilterChainProxy
|
||||
|
||||
Spring Security's Servlet support is contained within `FilterChainProxy`.
|
||||
`FilterChainProxy` is a special `Filter` provided by Spring Security that allows delegating to many `Filter` instances through <<servlet-securityfilterchain,`SecurityFilterChain`>>.
|
||||
Since `FilterChainProxy` is a Bean, it is typically wrapped in a <<servlet-delegatingfilterproxy>>.
|
||||
|
||||
.FilterChainProxy
|
||||
[[servlet-filterchainproxy-figure]]
|
||||
image::{figures}/filterchainproxy.png[]
|
||||
|
||||
[[servlet-securityfilterchain]]
|
||||
== SecurityFilterChain
|
||||
|
||||
{security-api-url}org/springframework/security/web/SecurityFilterChain.html[`SecurityFilterChain`] is used by <<servlet-filterchainproxy>> to determine which Spring Security ``Filter``s should be invoked for this request.
|
||||
|
||||
.SecurityFilterChain
|
||||
[[servlet-securityfilterchain-figure]]
|
||||
image::{figures}/securityfilterchain.png[]
|
||||
|
||||
The <<servlet-security-filters,Security Filters>> in `SecurityFilterChain` are typically Beans, but they are registered with `FilterChainProxy` instead of <<servlet-delegatingfilterproxy>>.
|
||||
`FilterChainProxy` provides a number of advantages to registering directly with the Servlet container or <<servlet-delegatingfilterproxy>>.
|
||||
First, it provides a starting point for all of Spring Security's Servlet support.
|
||||
For that reason, if you are attempting to troubleshoot Spring Security's Servlet support, adding a debug point in `FilterChainProxy` is a great place to start.
|
||||
|
||||
Second, since `FilterChainProxy` is central to Spring Security usage it can perform tasks that are not viewed as optional.
|
||||
// FIXME: Add a link to SecurityContext
|
||||
For example, it clears out the `SecurityContext` to avoid memory leaks.
|
||||
It also applies Spring Security's xref:servlet/exploits/firewall.adoc#servlet-httpfirewall[`HttpFirewall`] to protect applications against certain types of attacks.
|
||||
|
||||
In addition, it provides more flexibility in determining when a `SecurityFilterChain` should be invoked.
|
||||
In a Servlet container, ``Filter``s are invoked based upon the URL alone.
|
||||
// FIXME: Link to RequestMatcher
|
||||
However, `FilterChainProxy` can determine invocation based upon anything in the `HttpServletRequest` by leveraging the `RequestMatcher` interface.
|
||||
|
||||
In fact, `FilterChainProxy` can be used to determine which `SecurityFilterChain` should be used.
|
||||
This allows providing a totally separate configuration for different _slices_ of your application.
|
||||
|
||||
.Multiple SecurityFilterChain
|
||||
[[servlet-multi-securityfilterchain-figure]]
|
||||
image::{figures}/multi-securityfilterchain.png[]
|
||||
|
||||
In the <<servlet-multi-securityfilterchain-figure>> Figure `FilterChainProxy` decides which `SecurityFilterChain` should be used.
|
||||
Only the first `SecurityFilterChain` that matches will be invoked.
|
||||
If a URL of `/api/messages/` is requested, it will first match on ``SecurityFilterChain~0~``'s pattern of `+/api/**+`, so only `SecurityFilterChain~0~` will be invoked even though it also matches on ``SecurityFilterChain~n~``.
|
||||
If a URL of `/messages/` is requested, it will not match on ``SecurityFilterChain~0~``'s pattern of `+/api/**+`, so `FilterChainProxy` will continue trying each `SecurityFilterChain`.
|
||||
Assuming that no other, `SecurityFilterChain` instances match `SecurityFilterChain~n~` will be invoked.
|
||||
// FIXME add link to pattern matching
|
||||
|
||||
Notice that `SecurityFilterChain~0~` has only three security ``Filter``s instances configured.
|
||||
However, `SecurityFilterChain~n~` has four security ``Filter``s configured.
|
||||
It is important to note that each `SecurityFilterChain` can be unique and configured in isolation.
|
||||
In fact, a `SecurityFilterChain` might have zero security ``Filter``s if the application wants Spring Security to ignore certain requests.
|
||||
// FIXME: add link to configuring multiple `SecurityFilterChain` instances
|
||||
|
||||
[[servlet-security-filters]]
|
||||
== Security Filters
|
||||
|
||||
The Security Filters are inserted into the <<servlet-filterchainproxy>> with the <<servlet-securityfilterchain>> API.
|
||||
The <<servlet-filters-review,order of ``Filter``>>s matters.
|
||||
It is typically not necessary to know the ordering of Spring Security's ``Filter``s.
|
||||
However, there are times that it is beneficial to know the ordering
|
||||
|
||||
Below is a comprehensive list of Spring Security Filter ordering:
|
||||
|
||||
* xref:servlet/authentication/session-management.adoc#session-mgmt-force-session-creation[`ForceEagerSessionCreationFilter`]
|
||||
* ChannelProcessingFilter
|
||||
* WebAsyncManagerIntegrationFilter
|
||||
* SecurityContextPersistenceFilter
|
||||
* HeaderWriterFilter
|
||||
* CorsFilter
|
||||
* CsrfFilter
|
||||
* LogoutFilter
|
||||
* OAuth2AuthorizationRequestRedirectFilter
|
||||
* Saml2WebSsoAuthenticationRequestFilter
|
||||
* X509AuthenticationFilter
|
||||
* AbstractPreAuthenticatedProcessingFilter
|
||||
* CasAuthenticationFilter
|
||||
* OAuth2LoginAuthenticationFilter
|
||||
* Saml2WebSsoAuthenticationFilter
|
||||
* xref:servlet/authentication/passwords/form.adoc#servlet-authentication-usernamepasswordauthenticationfilter[`UsernamePasswordAuthenticationFilter`]
|
||||
* OpenIDAuthenticationFilter
|
||||
* DefaultLoginPageGeneratingFilter
|
||||
* DefaultLogoutPageGeneratingFilter
|
||||
* ConcurrentSessionFilter
|
||||
* xref:servlet/authentication/passwords/digest.adoc#servlet-authentication-digest[`DigestAuthenticationFilter`]
|
||||
* BearerTokenAuthenticationFilter
|
||||
* xref:servlet/authentication/passwords/basic.adoc#servlet-authentication-basic[`BasicAuthenticationFilter`]
|
||||
* RequestCacheAwareFilter
|
||||
* SecurityContextHolderAwareRequestFilter
|
||||
* JaasApiIntegrationFilter
|
||||
* RememberMeAuthenticationFilter
|
||||
* AnonymousAuthenticationFilter
|
||||
* OAuth2AuthorizationCodeGrantFilter
|
||||
* SessionManagementFilter
|
||||
* <<servlet-exceptiontranslationfilter,`ExceptionTranslationFilter`>>
|
||||
* xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`]
|
||||
* SwitchUserFilter
|
||||
|
||||
[[servlet-exceptiontranslationfilter]]
|
||||
== Handling Security Exceptions
|
||||
|
||||
|
||||
The {security-api-url}org/springframework/security/web/access/ExceptionTranslationFilter.html[`ExceptionTranslationFilter`] allows translation of {security-api-url}org/springframework/security/access/AccessDeniedException.html[`AccessDeniedException`] and {security-api-url}/org/springframework/security/core/AuthenticationException.html[`AuthenticationException`] into HTTP responses.
|
||||
|
||||
`ExceptionTranslationFilter` is inserted into the <<servlet-filterchainproxy>> as one of the <<servlet-security-filters>>.
|
||||
|
||||
image::{figures}/exceptiontranslationfilter.png[]
|
||||
|
||||
|
||||
* image:{icondir}/number_1.png[] First, the `ExceptionTranslationFilter` invokes `FilterChain.doFilter(request, response)` to invoke the rest of the application.
|
||||
* image:{icondir}/number_2.png[] If the user is not authenticated or it is an `AuthenticationException`, then __Start Authentication__.
|
||||
** The xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder] is cleared out
|
||||
** The `HttpServletRequest` is saved in the {security-api-url}org/springframework/security/web/savedrequest/RequestCache.html[`RequestCache`].
|
||||
When the user successfully authenticates, the `RequestCache` is used to replay the original request.
|
||||
// FIXME: add link to authentication success
|
||||
** The `AuthenticationEntryPoint` is used to request credentials from the client.
|
||||
For example, it might redirect to a log in page or send a `WWW-Authenticate` header.
|
||||
// FIXME: link to AuthenticationEntryPoint
|
||||
* image:{icondir}/number_3.png[] Otherwise if it is an `AccessDeniedException`, then __Access Denied__.
|
||||
The `AccessDeniedHandler` is invoked to handle access denied.
|
||||
// FIXME: link to AccessDeniedHandler
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
If the application does not throw an `AccessDeniedException` or an `AuthenticationException`, then `ExceptionTranslationFilter` does not do anything.
|
||||
====
|
||||
|
||||
The pseudocode for `ExceptionTranslationFilter` looks something like this:
|
||||
|
||||
.ExceptionTranslationFilter pseudocode
|
||||
[source,java]
|
||||
----
|
||||
try {
|
||||
filterChain.doFilter(request, response); // <1>
|
||||
} catch (AccessDeniedException | AuthenticationException ex) {
|
||||
if (!authenticated || ex instanceof AuthenticationException) {
|
||||
startAuthentication(); // <2>
|
||||
} else {
|
||||
accessDenied(); // <3>
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> You will recall from <<servlet-filters-review>> that invoking `FilterChain.doFilter(request, response)` is the equivalent of invoking the rest of the application.
|
||||
This means that if another part of the application, (i.e. xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] or method security) throws an `AuthenticationException` or `AccessDeniedException` it will be caught and handled here.
|
||||
<2> If the user is not authenticated or it is an `AuthenticationException`, then __Start Authentication__.
|
||||
<3> Otherwise, __Access Denied__
|
|
@ -1,36 +1,15 @@
|
|||
[[getting-started]]
|
||||
= Getting Started with WebFlux Applications
|
||||
# Hello Spring Security
|
||||
|
||||
This section covers the minimum setup for how to use Spring Security with Spring Boot in a reactive application.
|
||||
本节介绍了如何把 Spring Security 与 Spring Boot 结合使用的最小设置。
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
The completed application can be found {gh-samples-url}/reactive/webflux/java/hello-security[in our samples repository].
|
||||
For your convenience, you can download a minimal Reactive Spring Boot + Spring Security application by https://start.spring.io/starter.zip?type=maven-project&language=java&packaging=jar&jvmVersion=1.8&groupId=example&artifactId=hello-security&name=hello-security&description=Hello%20Security&packageName=example.hello-security&dependencies=webflux,security[clicking here].
|
||||
====
|
||||
?> The completed application can be found {gh-samples-url}/servlet/spring-boot/java/hello-security[in our samples repository].
|
||||
For your convenience, you can download a minimal Spring Boot + Spring Security application by https://start.spring.io/starter.zip?type=maven-project&language=java&packaging=jar&jvmVersion=1.8&groupId=example&artifactId=hello-security&name=hello-security&description=Hello%20Security&packageName=example.hello-security&dependencies=web,security[clicking here].
|
||||
|
||||
[[dependencies]]
|
||||
== Updating Dependencies
|
||||
|
||||
You can add Spring Security to your Spring Boot project by adding `spring-boot-starter-security`.
|
||||
|
||||
====
|
||||
.Maven
|
||||
[source,xml,role="primary"]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
.Gradle
|
||||
[source,groovy,role="secondary"]
|
||||
----
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||
----
|
||||
====
|
||||
[[servlet-hello-dependencies]]
|
||||
## 更新依赖
|
||||
|
||||
The only step you need to do is update the dependencies by using xref:getting-spring-security.adoc#getting-maven-boot[Maven] or xref:getting-spring-security.adoc#getting-gradle-boot[Gradle].
|
||||
|
||||
[[servlet-hello-starting]]
|
||||
== Starting Hello Spring Security Boot
|
||||
|
@ -39,24 +18,10 @@ You can now https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle
|
|||
The following example shows how to do so (and the beginning of the output from doing so):
|
||||
|
||||
.Running Spring Boot Application
|
||||
|
||||
====
|
||||
.Maven
|
||||
[source,bash,role="primary"]
|
||||
[source,bash]
|
||||
----
|
||||
$ ./mvnw spring-boot:run
|
||||
...
|
||||
INFO 23689 --- [ restartedMain] .s.s.UserDetailsServiceAutoConfiguration :
|
||||
|
||||
Using generated security password: 8e557245-73e2-4286-969a-ff57fe326336
|
||||
|
||||
...
|
||||
----
|
||||
|
||||
.Gradle
|
||||
[source,bash,role="secondary"]
|
||||
----
|
||||
$ ./gradlew bootRun
|
||||
$ ./mvn spring-boot:run
|
||||
...
|
||||
INFO 23689 --- [ restartedMain] .s.s.UserDetailsServiceAutoConfiguration :
|
||||
|
||||
|
@ -66,14 +31,40 @@ Using generated security password: 8e557245-73e2-4286-969a-ff57fe326336
|
|||
----
|
||||
====
|
||||
|
||||
[[authenticating]]
|
||||
== Authenticating
|
||||
|
||||
You can access the application at http://localhost:8080/ which will redirect the browser to the default log in page. You can provide the default username of `user` with the randomly generated password that is logged to the console. The browser is then taken to the orginally requested page.
|
||||
|
||||
To log out you can visit http://localhost:8080/logout and then confirming you wish to log out.
|
||||
|
||||
[[auto-configuration]]
|
||||
[[servlet-hello-auto-configuration]]
|
||||
== Spring Boot Auto Configuration
|
||||
|
||||
Spring Boot automatically adds Spring Security which requires all requests be authenticated. It also generates a user with a randomly generated password that is logged to the console which can be used to authenticate using form or basic authentication.
|
||||
// FIXME: Link to relevant portions of documentation
|
||||
// FIXME: Link to Spring Boot's Security Auto configuration classes
|
||||
// FIXME: Add a links for what user's should do next
|
||||
|
||||
Spring Boot automatically:
|
||||
|
||||
* Enables Spring Security's default configuration, which creates a servlet `Filter` as a bean named `springSecurityFilterChain`.
|
||||
This bean is responsible for all the security (protecting the application URLs, validating submitted username and passwords, redirecting to the log in form, and so on) within your application.
|
||||
* Creates a `UserDetailsService` bean with a username of `user` and a randomly generated password that is logged to the console.
|
||||
* Registers the `Filter` with a bean named `springSecurityFilterChain` with the Servlet container for every request.
|
||||
|
||||
Spring Boot is not configuring much, but it does a lot.
|
||||
A summary of the features follows:
|
||||
|
||||
* Require an authenticated user for any interaction with the application
|
||||
* Generate a default login form for you
|
||||
* Let the user with a username of `user` and a password that is logged to the console to authenticate with form-based authentication (in the preceding example, the password is `8e557245-73e2-4286-969a-ff57fe326336`)
|
||||
* Protects the password storage with BCrypt
|
||||
* Lets the user log out
|
||||
* https://en.wikipedia.org/wiki/Cross-site_request_forgery[CSRF attack] prevention
|
||||
* https://en.wikipedia.org/wiki/Session_fixation[Session Fixation] protection
|
||||
* Security Header integration
|
||||
** https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security[HTTP Strict Transport Security] for secure requests
|
||||
** https://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx[X-Content-Type-Options] integration
|
||||
** Cache Control (can be overridden later by your application to allow caching of your static resources)
|
||||
** https://msdn.microsoft.com/en-us/library/dd565647(v=vs.85).aspx[X-XSS-Protection] integration
|
||||
** X-Frame-Options integration to help prevent https://en.wikipedia.org/wiki/Clickjacking[Clickjacking]
|
||||
* Integrate with the following Servlet API methods:
|
||||
** https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getRemoteUser()[`HttpServletRequest#getRemoteUser()`]
|
||||
** https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getUserPrincipal()[`HttpServletRequest.html#getUserPrincipal()`]
|
||||
** https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#isUserInRole(java.lang.String)[`HttpServletRequest.html#isUserInRole(java.lang.String)`]
|
||||
** https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#login(java.lang.String,%20java.lang.String)[`HttpServletRequest.html#login(java.lang.String, java.lang.String)`]
|
||||
** https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#logout()[`HttpServletRequest.html#logout()`]
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# Servlet 应用程序
|
||||
|
||||
Spring Security 使用标准的 Servlet `过滤器(Filter)` 并与 Servlet 容器集成。
|
||||
这个意味着 Spring Security 可以在任何运行运行在 Servlet 容器(Servlet Container)中的应用上使用。
|
||||
更具体地说,你可以不使用 Spring,而是基于 Servlet 的应用程序中使用 Spring Security。
|
||||
|
||||
因为我们都知道,Spring 是可以通过 Spring Boot 启动的,实际上启动的时候 Spring 也会启动一个嵌入式 Tomcat。
|
||||
|
||||
Spring Security 的这种设计意味着,我们可以不使用 Spring Boot 启动的容器,而直接使用一个 Tomcat 容器。
|
||||
|
||||
[](getting-started.md ':include')
|
||||
|
||||
[](architecture.md ':include')
|
|
@ -0,0 +1,37 @@
|
|||
# Spring Security 新功能
|
||||
|
||||
Spring Security 5.7 提供了一系列行的特性。
|
||||
|
||||
下面为特别值得指出的一些新特性。
|
||||
|
||||
|
||||
## Servlet
|
||||
|
||||
* Web
|
||||
|
||||
** 新增 xref:servlet/authentication/persistence.adoc#requestattributesecuritycontextrepository[`RequestAttributeSecurityContextRepository`]
|
||||
** 新增 xref:servlet/authentication/persistence.adoc#securitycontextholderfilter[`SecurityContextHolderFilter`] - Ability to require explicit saving of the `SecurityContext`
|
||||
** 针对 xref:servlet/exploits/headers.adoc#servlet-headers-cross-origin-policies[Cross Origin Policies headers] 新增 DSL 支持
|
||||
|
||||
* OAuth 2.0 客户端
|
||||
|
||||
** 允许对 https://github.com/spring-projects/spring-security/issues/6548[PKCE for confidential clients] 进行配置
|
||||
** Allow 在 `JwtBearerOAuth2AuthorizedClientProvider` 中配置一个 https://github.com/spring-projects/spring-security/issues/9812[JWT assertion resolver]
|
||||
** 允许在 https://github.com/spring-projects/spring-security/issues/9855[JWT client assertions] 自定义 claims
|
||||
|
||||
* SAML 2.0
|
||||
|
||||
** 新增 xref:servlet/appendix/namespace/http.adoc#nsa-saml2-login[SAML 2.0 Login & Single Logout XML support]
|
||||
|
||||
|
||||
## WebFlux
|
||||
|
||||
* Web
|
||||
|
||||
** 允许在 `ServerHttpBasicAuthenticationConverter` 中自定义 customizing https://github.com/spring-projects/spring-security/issues/10903[charset]
|
||||
** 针对 xref:reactive/exploits/headers.adoc#webflux-headers-cross-origin-policies[Cross Origin Policies headers] 新增 DSL 支持
|
||||
|
||||
* OAuth 2.0 客户端
|
||||
|
||||
** 允许配置 https://github.com/spring-projects/spring-security/issues/6548[PKCE for confidential clients]
|
||||
** 允许在 `JwtBearerReactiveOAuth2AuthorizedClientProvider` 中配置一个 https://github.com/spring-projects/spring-security/issues/9812[JWT assertion resolver]
|
Loading…
Reference in New Issue