Further changes based on feedback

Mostly restoring the formatting of admonitions.
This commit is contained in:
Jay Bryant 2021-06-04 14:12:59 -05:00
parent 93893ded53
commit 7171521b47
43 changed files with 712 additions and 183 deletions

View File

@ -146,15 +146,15 @@ All of the original passwords are `password`.
----
====
<1> The first password has a `PasswordEncoder` id of `bcrypt` and an encoded password value of `$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG`.
<1> The first password has a `PasswordEncoder` id of `bcrypt` and an `encodedPassword` value of `$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG`.
When matching, it would delegate to `BCryptPasswordEncoder`
<2> The second password has a `PasswordEncoder` id of `noop` and encoded password value of `password`.
<2> The second password has a `PasswordEncoder` id of `noop` and `encodedPassword` value of `password`.
When matching, it would delegate to `NoOpPasswordEncoder`
<3> The third password has a `PasswordEncoder` id of `pbkdf2` and encoded password value of `5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc`.
<3> The third password has a `PasswordEncoder` id of `pbkdf2` and `encodedPassword` value of `5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc`.
When matching, it would delegate to `Pbkdf2PasswordEncoder`
<4> The fourth password has a `PasswordEncoder` id of `scrypt` and encoded password value of `$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=`
<4> The fourth password has a `PasswordEncoder` id of `scrypt` and `encodedPassword` value of `$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=`
When matching, it would delegate to `SCryptPasswordEncoder`
<5> The final password has a `PasswordEncoder` id of `sha256` and encoded password value of `97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0`.
<5> The final password has a `PasswordEncoder` id of `sha256` and `encodedPassword` value of `97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0`.
When matching, it would delegate to `StandardPasswordEncoder`
[NOTE]
@ -487,4 +487,8 @@ fun passwordEncoder(): PasswordEncoder {
----
====
NOTE: XML Configuration requires the `NoOpPasswordEncoder` bean name to be `passwordEncoder`.
[NOTE]
====
XML Configuration requires the `NoOpPasswordEncoder` bean name to be `passwordEncoder`.
====

View File

@ -8,8 +8,11 @@ In the following sections, we explore:
* <<csrf-protection>>
* <<csrf-considerations>>
NOTE: This portion of the documentation discusses the general topic of CSRF protection.
[NOTE]
====
This portion of the documentation discusses the general topic of CSRF protection.
See the relevant sections for specific information on CSRF protection for <<servlet-csrf,servlet>>- and <<webflux-csrf,WebFlux>>-based applications.
====
[[csrf-explained]]
== What is a CSRF Attack?
@ -95,7 +98,10 @@ Spring provides two mechanisms to protect against CSRF attacks:
* The <<Synchronizer Token Pattern>>
* Specifying the <<SameSite Attribute>> on your session cookie
NOTE: Both protections require that <<csrf-protection-idempotent,Safe Methods be Idempotent>>.
[NOTE]
====
Both protections require that <<csrf-protection-idempotent,Safe Methods be Idempotent>>.
====
[[csrf-protection-idempotent]]
=== Safe Methods Must be Idempotent
@ -172,9 +178,12 @@ The evil website cannot provide the correct value for the `_csrf` parameter (whi
An emerging way to protect against <<csrf,CSRF Attacks>> is to specify the https://tools.ietf.org/html/draft-west-first-party-cookies[SameSite Attribute] on cookies.
A server can specify the `SameSite` attribute when setting a cookie to indicate that the cookie should not be sent when coming from external sites.
NOTE: Spring Security does not directly control the creation of the session cookie, so it does not provide support for the SameSite attribute.
[NOTE]
====
Spring Security does not directly control the creation of the session cookie, so it does not provide support for the SameSite attribute.
https://spring.io/projects/spring-session[Spring Session] provides support for the `SameSite` attribute in servlet-based applications.
Spring Framework's https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/server/session/CookieWebSessionIdResolver.html[`CookieWebSessionIdResolver`] provides support for the `SameSite` attribute in WebFlux-based applications.
====
An example of an HTTP response header with the `SameSite` attribute might look like:
@ -207,7 +216,10 @@ The user receives an email at https://email.example.org that includes a link to
If the user clicks on the link, they would rightfully expect to be authenticated to the social media site.
However, if the `SameSite` attribute is `Strict`, the cookie would not be sent and the user would not be authenticated.
NOTE: We could improve the protection and usability of `SameSite` protection against CSRF attacks by implementing https://github.com/spring-projects/spring-security/issues/7537[gh-7537].
[NOTE]
====
We could improve the protection and usability of `SameSite` protection against CSRF attacks by implementing https://github.com/spring-projects/spring-security/issues/7537[gh-7537].
====
Another obvious consideration is that, in order for the `SameSite` attribute to protect users, the browser must support the `SameSite` attribute.
Most modern browsers do https://developer.mozilla.org/en-US/docs/Web/HTTP/headers/Set-Cookie#Browser_compatibility[support the SameSite attribute].
@ -351,8 +363,11 @@ There are two options to using CSRF protection with multipart/form-data:
Each option has its trade-offs.
NOTE: Before you integrate Spring Security's CSRF protection with multipart file upload, you should first ensure that you can upload without the CSRF protection.
[NOTE]
====
Before you integrate Spring Security's CSRF protection with multipart file upload, you should first ensure that you can upload without the CSRF protection.
More information about using multipart forms with Spring, see the https://docs.spring.io/spring/docs/5.2.x/spring-framework-reference/web.html#mvc-multipart[1.1.11. Multipart Resolver] section of the Spring reference and the https://docs.spring.io/spring/docs/5.2.x/javadoc-api/org/springframework/web/multipart/support/MultipartFilter.html[`MultipartFilter` Javadoc].
====
[[csrf-considerations-multipart-body]]
==== Place CSRF Token in the Body

View File

@ -1,8 +1,11 @@
[[headers]]
= Security HTTP Response Headers
NOTE: This portion of the documentation discusses the general topic of Security HTTP Response Headers.
[NOTE]
====
This portion of the documentation discusses the general topic of Security HTTP Response Headers.
See the relevant sections for specific information on Security HTTP Response Headers in <<servlet-headers,servlet>>- and <<webflux-headers,WebFlux>>-based applications.
====
You can use https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#tab=Headers[HTTP response headers] in many ways to increase the security of web applications.
This section is dedicated to the various HTTP response headers for which Spring Security provides explicit support.
@ -11,7 +14,10 @@ If necessary, you can also configure Spring Security to provide <<headers-custom
[[headers-default]]
== Default Security Headers
NOTE: See the relevant sections for how to customize the defaults for both <<servlet-headers-default,servlet>>- and <<webflux-headers-default,webflux>>-based applications.
[NOTE]
====
See the relevant sections for how to customize the defaults for both <<servlet-headers-default,servlet>>- and <<webflux-headers-default,webflux>>-based applications.
====
Spring Security provides a default set of security related HTTP response headers to provide secure defaults.
@ -31,7 +37,10 @@ X-XSS-Protection: 1; mode=block
----
====
NOTE: Strict-Transport-Security is added only on HTTPS requests
[NOTE]
====
Strict-Transport-Security is added only on HTTPS requests
====
If the defaults do not meet your needs, you can easily remove, modify, or add headers from these defaults.
For additional details on each of these headers, see the corresponding sections:
@ -45,7 +54,10 @@ For additional details on each of these headers, see the corresponding sections:
[[headers-cache-control]]
== Cache Control
NOTE: See the relevant sections for how to customize the defaults for both <<servlet-headers-cache-control,servlet>>- and <<webflux-headers-cache-control,webflux>>-based applications.
[NOTE]
====
See the relevant sections for how to customize the defaults for both <<servlet-headers-cache-control,servlet>>- and <<webflux-headers-cache-control,webflux>>-based applications.
====
Spring Security's default is to disable caching to protect the user's content.
@ -70,15 +82,21 @@ This allows for applications to ensure that static resources (such as CSS and Ja
[[headers-content-type-options]]
== Content Type Options
NOTE: See the relevant sections for how to customize the defaults for both <<servlet-headers-content-type-options,servlet>>- and <<webflux-headers-content-type-options,webflux>>-based applications.
[NOTE]
====
See the relevant sections for how to customize the defaults for both <<servlet-headers-content-type-options,servlet>>- and <<webflux-headers-content-type-options,webflux>>-based applications.
====
Historically, browsers, including Internet Explorer, would try to guess the content type of a request by using https://en.wikipedia.org/wiki/Content_sniffing[content sniffing].
This let browsers improve the user experience by guessing the content type on resources that had not specified the content type.
For example, if a browser encountered a JavaScript file that did not have the content type specified, it would be able to guess the content type and then run it.
NOTE: There are many additional things one should do (such as only display the document in a distinct domain, ensure Content-Type header is set, sanitize the document, and others) when allowing content to be uploaded.
[NOTE]
====
There are many additional things one should do (such as only display the document in a distinct domain, ensure Content-Type header is set, sanitize the document, and others) when allowing content to be uploaded.
However, these measures are out of the scope of what Spring Security provides.
It is also important to point out that, when disabling content sniffing, you must specify the content type in order for things to work properly.
====
The problem with content sniffing is that this allowed malicious users to use polyglots (that is, a file that is valid as multiple content types) to perform XSS attacks.
For example, some sites may allow users to submit a valid postscript document to a website and view it.
@ -97,7 +115,10 @@ X-Content-Type-Options: nosniff
[[headers-hsts]]
== HTTP Strict Transport Security (HSTS)
NOTE: Refer to the relevant sections to see how to customize the defaults for both <<servlet-headers-hsts,servlet>> and <<webflux-headers-hsts,webflux>> based applications.
[NOTE]
====
Refer to the relevant sections to see how to customize the defaults for both <<servlet-headers-hsts,servlet>> and <<webflux-headers-hsts,webflux>> based applications.
====
When you type in your bank's website, do you enter `mybank.example.com` or do you enter `https://mybank.example.com`?
If you omit the `https` protocol, you are potentially vulnerable to https://en.wikipedia.org/wiki/Man-in-the-middle_attack[Man-in-the-Middle attacks].
@ -107,8 +128,11 @@ Many users omit the `https` protocol, and this is why https://tools.ietf.org/htm
Once `mybank.example.com` is added as a https://tools.ietf.org/html/rfc6797#section-5.1[HSTS host], a browser can know ahead of time that any request to mybank.example.com should be interpreted as https://mybank.example.com.
This greatly reduces the possibility of a Man-in-the-Middle attack occurring.
NOTE: In accordance with https://tools.ietf.org/html/rfc6797#section-7.2[RFC6797], the HSTS header is injected only into HTTPS responses.
[NOTE]
====
In accordance with https://tools.ietf.org/html/rfc6797#section-7.2[RFC6797], the HSTS header is injected only into HTTPS responses.
For the browser to acknowledge the header, the browser must first trust the CA that signed the SSL certificate used to make the connection (not just the SSL certificate).
====
One way for a site to be marked as a HSTS host is to have the host preloaded into the browser.
Another way is to add the `Strict-Transport-Security` header to the response.
@ -131,7 +155,10 @@ For more details on HSTS preload, see https://hstspreload.org.
[[headers-hpkp]]
== HTTP Public Key Pinning (HPKP)
NOTE: To remain passive, Spring Security still provides <<servlet-headers-hpkp,support for HPKP in servlet environments>>. However, for the reasons listed earlier, HPKP is no longer recommended by the Spring Security team.
[NOTE]
====
To remain passive, Spring Security still provides <<servlet-headers-hpkp,support for HPKP in servlet environments>>. However, for the reasons listed earlier, HPKP is no longer recommended by the Spring Security team.
====
https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning[HTTP Public Key Pinning (HPKP)] specifies to a web client which public key to use with a certain web server to prevent Man-in-the-Middle (MITM) attacks with forged certificates.
When used correctly, HPKP could add additional layers of protection against compromised certificates.
@ -143,14 +170,20 @@ For additional details around why HPKP is no longer recommended, read https://bl
[[headers-frame-options]]
== X-Frame-Options
NOTE: See the relevant sections to see how to customize the defaults for both <<servlet-headers-frame-options,servlet>> and <<webflux-headers-frame-options,webflux>> based applications.
[NOTE]
====
See the relevant sections to see how to customize the defaults for both <<servlet-headers-frame-options,servlet>> and <<webflux-headers-frame-options,webflux>> based applications.
====
Letting your website be added to a frame can be a security issue.
For example, by using clever CSS styling, users could be tricked into clicking on something that they were not intending.
For example, a user that is logged into their bank might click a button that grants access to other users.
This sort of attack is known as https://en.wikipedia.org/wiki/Clickjacking[Clickjacking].
NOTE: Another modern approach to dealing with clickjacking is to use <<headers-csp>>.
[NOTE]
====
Another modern approach to dealing with clickjacking is to use <<headers-csp>>.
====
There are a number ways to mitigate clickjacking attacks.
For example, to protect legacy browsers from clickjacking attacks, you can use https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Best-for-now_Legacy_Browser_Frame_Breaking_Script[frame breaking code].
@ -169,7 +202,10 @@ X-Frame-Options: DENY
[[headers-xss-protection]]
== X-XSS-Protection
NOTE: See the relevant sections to see how to customize the defaults for both <<servlet-headers-xss-protection,servlet>>- and <<webflux-headers-xss-protection,webflux>>-based applications.
[NOTE]
====
See the relevant sections to see how to customize the defaults for both <<servlet-headers-xss-protection,servlet>>- and <<webflux-headers-xss-protection,webflux>>-based applications.
====
Some browsers have built-in support for filtering out https://www.owasp.org/index.php/Testing_for_Reflected_Cross_site_scripting_(OWASP-DV-001)[reflected XSS attacks].
This is by no means foolproof but does assist in XSS protection.
@ -190,14 +226,20 @@ X-XSS-Protection: 1; mode=block
[[headers-csp]]
== Content Security Policy (CSP)
NOTE: See the relevant sections to see how to configure both <<servlet-headers-csp,servlet>>- and <<webflux-headers-csp,webflux>>-based applications.
[NOTE]
====
See the relevant sections to see how to configure both <<servlet-headers-csp,servlet>>- and <<webflux-headers-csp,webflux>>-based applications.
====
https://www.w3.org/TR/CSP2/[Content Security Policy (CSP)] is a mechanism that web applications can use to mitigate content injection vulnerabilities, such as cross-site scripting (XSS).
CSP is a declarative policy that provides a facility for web application authors to declare and ultimately inform the client (user-agent) about the sources from which the web application expects to load resources.
NOTE: Content Security Policy is not intended to solve all content injection vulnerabilities.
[NOTE]
====
Content Security Policy is not intended to solve all content injection vulnerabilities.
Instead, you can use CSP to help reduce the harm caused by content injection attacks.
As a first line of defense, web application authors should validate their input and encode their output.
====
A web application can use CSP by including one of the following HTTP headers in the response:
@ -260,7 +302,10 @@ https://www.w3.org/TR/CSP2/[W3C Candidate Recommendation]
[[headers-referrer]]
== Referrer Policy
NOTE: See the relevant sections to see how to configure both <<servlet-headers-referrer,servlet>>- and <<webflux-headers-referrer,webflux>>-based applications.
[NOTE]
====
See the relevant sections to see how to configure both <<servlet-headers-referrer,servlet>>- and <<webflux-headers-referrer,webflux>>-based applications.
====
https://www.w3.org/TR/referrer-policy[Referrer Policy] is a mechanism that web applications can use to manage the referrer field, which contains the last
page the user was on.
@ -280,7 +325,10 @@ The Referrer-Policy response header instructs the browser to let the destination
[[headers-feature]]
== Feature Policy
NOTE: See the relevant sections to see how to configure both <<servlet-headers-feature,servlet>>- and <<webflux-headers-feature,webflux>>-based applications.
[NOTE]
====
See the relevant sections to see how to configure both <<servlet-headers-feature,servlet>>- and <<webflux-headers-feature,webflux>>-based applications.
====
https://wicg.github.io/feature-policy/[Feature Policy] is a mechanism that lets web developers selectively enable, disable, and modify the behavior of certain APIs and web features in the browser.
@ -299,7 +347,10 @@ These policies restrict what APIs the site can access or modify the browser's de
[[headers-permissions]]
== Permissions Policy
NOTE: See the relevant sections to see how to configure both <<servlet-headers-permissions,servlet>>- and <<webflux-headers-permissions,webflux>>-based applications.
[NOTE]
====
See the relevant sections to see how to configure both <<servlet-headers-permissions,servlet>>- and <<webflux-headers-permissions,webflux>>-based applications.
====
https://w3c.github.io/webappsec-permissions-policy/[Permissions Policy] is a mechanism that lets web developers selectively enable, disable, and modify the behavior of certain APIs and web features in the browser.
@ -318,7 +369,10 @@ These policies restrict what APIs the site can access or modify the browser's de
[[headers-clear-site-data]]
== Clear Site Data
NOTE: See the relevant sections to see how to configure both <<servlet-headers-clear-site-data,servlet>> and <<webflux-headers-clear-site-data,webflux>> based applications.
[NOTE]
====
See the relevant sections to see how to configure both <<servlet-headers-clear-site-data,servlet>> and <<webflux-headers-clear-site-data,webflux>> based applications.
====
https://www.w3.org/TR/clear-site-data/[Clear Site Data] is a mechanism by which any browser-side data (cookies, local storage, and the like) can be removed when an HTTP response contains this header:
@ -335,7 +389,10 @@ This is a nice clean-up action to perform on logout.
[[headers-custom]]
== Custom Headers
NOTE: See the relevant sections to see how to configure both <<servlet-headers-custom,servlet>> based applications.
[NOTE]
====
See the relevant sections to see how to configure both <<servlet-headers-custom,servlet>> based applications.
====
Spring Security has mechanisms to make it convenient to add the more common security headers to your application.
However, it also provides hooks to enable adding custom headers.

View File

@ -145,8 +145,11 @@ The easiest way to resolve this is to use the `spring-framework-bom` within the
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+.
[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

View File

@ -277,7 +277,11 @@ This is the basis of the Spring Security integration.
[[spring-security-openid]]
== OpenID -- `spring-security-openid.jar`
NOTE: The OpenID 1.0 and 2.0 protocols have been deprecated and users are encouraged to migrate to OpenID Connect, which is supported by spring-security-oauth2.
[NOTE]
====
The OpenID 1.0 and 2.0 protocols have been deprecated and users are encouraged to migrate to OpenID Connect, which is supported by spring-security-oauth2.
====
This module contains OpenID web authentication support.
It is used to authenticate users against an external OpenID server.

View File

@ -63,9 +63,12 @@ fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain
-----
====
NOTE: The preceding sample explicitly sets `cookieHttpOnly=false`.
[NOTE]
====
The preceding sample explicitly sets `cookieHttpOnly=false`.
This is necessary to let JavaScript (in this case, AngularJS) to read it.
If you do not need the ability to read the cookie with JavaScript directly, we recommend to omitting `cookieHttpOnly=false` (by using `new CookieServerCsrfTokenRepository()` instead) to improve security.
====
[[webflux-csrf-configure-disable]]
==== Disable CSRF Protection
@ -344,7 +347,10 @@ For details, see the <<webflux-csrf-configure-custom-repository>> section.
We have <<csrf-considerations-multipart,already discussed>> how protecting multipart requests (file uploads) from CSRF attacks causes a https://en.wikipedia.org/wiki/Chicken_or_the_egg[chicken and the egg] problem.
This section discusses how to implement placing the CSRF token in the <<webflux-csrf-considerations-multipart-body,body>> and <<webflux-csrf-considerations-multipart-url,url>> within a WebFlux application.
NOTE: For more information about using multipart forms with Spring, see the https://docs.spring.io/spring/docs/5.2.x/spring-framework-reference/web-reactive.html#webflux-multipart[Multipart Data] section of the Spring reference.
[NOTE]
====
For more information about using multipart forms with Spring, see the https://docs.spring.io/spring/docs/5.2.x/spring-framework-reference/web-reactive.html#webflux-multipart[Multipart Data] section of the Spring reference.
====
[[webflux-csrf-considerations-multipart-body]]
==== Place CSRF Token in the Body

View File

@ -4,8 +4,11 @@
Spring Security supports method security by using https://projectreactor.io/docs/core/release/reference/#context[Reactor's Context], which is set up by `ReactiveSecurityContextHolder`.
The following example shows how to retrieve the currently logged in user's message:
NOTE: For this example to work, the return type of the method must be a `org.reactivestreams.Publisher` (that is, a `Mono` or a `Flux`) or the function must be a Kotlin coroutine function.
[NOTE]
====
For this example to work, the return type of the method must be a `org.reactivestreams.Publisher` (that is, a `Mono` or a `Flux`) or the function must be a Kotlin coroutine function.
This is necessary to integrate with Reactor's `Context`.
====
====
.Java

View File

@ -5,7 +5,10 @@ The OAuth 2.0 Login feature provides an application with the ability to have use
GitHub) or OpenID Connect 1.0 Provider (such as Google).
OAuth 2.0 Login implements the "Login with Google" or "Login with GitHub" use cases.
NOTE: OAuth 2.0 Login is implemented by using the *Authorization Code Grant*, as specified in the https://tools.ietf.org/html/rfc6749#section-4.1[OAuth 2.0 Authorization Framework] and https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[OpenID Connect Core 1.0].
[NOTE]
====
OAuth 2.0 Login is implemented by using the *Authorization Code Grant*, as specified in the https://tools.ietf.org/html/rfc6749#section-4.1[OAuth 2.0 Authorization Framework] and https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[OpenID Connect Core 1.0].
====
[[webflux-oauth2-login-sample]]
== Spring Boot 2.0 Sample
@ -25,7 +28,10 @@ This section shows how to configure the {gh-samples-url}/boot/oauth2login-webflu
To use Google's OAuth 2.0 authentication system for login, you must set up a project in the Google API Console to obtain OAuth 2.0 credentials.
NOTE: https://developers.google.com/identity/protocols/OpenIDConnect[Google's OAuth 2.0 implementation] for authentication conforms to the https://openid.net/connect/[OpenID Connect 1.0] specification and is https://openid.net/certification/[OpenID Certified].
[NOTE]
====
https://developers.google.com/identity/protocols/OpenIDConnect[Google's OAuth 2.0 implementation] for authentication conforms to the https://openid.net/connect/[OpenID Connect 1.0] specification and is https://openid.net/certification/[OpenID Certified].
====
Follow the instructions on the https://developers.google.com/identity/protocols/OpenIDConnect[OpenID Connect] page, starting in the "`Setting up OAuth 2.0`" section.
@ -38,12 +44,19 @@ The redirect URI is the path in the application that the end-user's user-agent i
In the "`Set a redirect URI`" sub-section, ensure that the *Authorized redirect URIs* field is set to `http://localhost:8080/login/oauth2/code/google`.
TIP: The default redirect URI template is `+{baseUrl}/login/oauth2/code/{registrationId}+`.
[TIP]
====
The default redirect URI template is `+{baseUrl}/login/oauth2/code/{registrationId}+`.
The *_registrationId_* is a unique identifier for the <<oauth2Client-client-registration,ClientRegistration>>.
For our example, the `registrationId` is `google`.
====
IMPORTANT: If the OAuth Client runs behind a proxy server, we recommend checking the <<http-proxy-server,Proxy Server Configuration>> to ensure the application is correctly configured.
[IMPORTANT]
====
If the OAuth Client runs behind a proxy server, we recommend checking the <<http-proxy-server,Proxy Server Configuration>> to ensure the application is correctly configured.
Also, see the supported <<oauth2Client-auth-code-redirect-uri,`URI` template variables>> for the `redirect-uri`.
====
[[webflux-oauth2-login-sample-config]]
=== Configure `application.yml`
@ -111,7 +124,10 @@ spring:
The `issuer-uri` instructs Spring Security to query, in series, the following endpoints to discover the configuration: `https://idp.example.com/auth/realms/demo/.well-known/openid-configuration`, `https://idp.example.com/.well-known/openid-configuration/auth/realms/demo`, or `https://idp.example.com/.well-known/oauth-authorization-server/auth/realms/demo`.
NOTE: Spring Security queries the endpoints one at a time, stopping at the first that gives a 200 response.
[NOTE]
====
Spring Security queries the endpoints one at a time, stopping at the first that gives a 200 response.
====
The `client-id` and `client-secret` are linked to the provider because `keycloak` is used for both the provider and the registration.

View File

@ -9,7 +9,10 @@ Spring Security supports protecting endpoints by offering two forms of OAuth 2.0
This is handy in circumstances where an application has delegated its authority management to an https://tools.ietf.org/html/rfc6749[authorization server] (for example, Okta or Ping Identity).
Resource serves can consult this authorization server to authorize requests.
NOTE: A complete working example for {gh-samples-url}/boot/oauth2resourceserver-webflux[JWT] is available in the {gh-samples-url}[Spring Security repository].
[NOTE]
====
A complete working example for {gh-samples-url}/boot/oauth2resourceserver-webflux[JWT] is available in the {gh-samples-url}[Spring Security repository].
====
[[webflux-oauth2resourceserver-jwt-minimaldependencies]]
== Minimal Dependencies for JWT
@ -42,8 +45,11 @@ spring:
Where `https://idp.example.com/issuer` is the value contained in the `iss` claim for JWT tokens that the authorization server issues.
This resource server uses this property to further self-configure, discover the authorization server's public keys, and subsequently validate incoming JWTs.
NOTE: To use the `issuer-uri` property, it must also be true that one of `https://idp.example.com/issuer/.well-known/openid-configuration`, `https://idp.example.com/.well-known/openid-configuration/issuer`, or `https://idp.example.com/.well-known/oauth-authorization-server/issuer` is a supported endpoint for the authorization server.
[NOTE]
====
To use the `issuer-uri` property, it must also be true that one of `https://idp.example.com/issuer/.well-known/openid-configuration`, `https://idp.example.com/.well-known/openid-configuration/issuer`, or `https://idp.example.com/.well-known/oauth-authorization-server/issuer` is a supported endpoint for the authorization server.
This endpoint is referred to as a https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Provider Configuration] endpoint or a https://tools.ietf.org/html/rfc8414#section-3[Authorization Server Metadata] endpoint.
====
=== Startup Expectations
@ -57,7 +63,10 @@ It achieves this through a deterministic startup process:
A consequence of this process is that the authorization server must be receiving requests in order for Resource Server to successfully start up.
NOTE: If the authorization server is down when Resource Server queries it (given appropriate timeouts), then startup fails.
[NOTE]
====
If the authorization server is down when Resource Server queries it (given appropriate timeouts), then startup fails.
====
=== Runtime Expectations
@ -79,7 +88,10 @@ Given a well-formed JWT, Resource Server:
2. Validates the JWTs `exp` and `nbf` timestamps and the JWTs `iss` claim.
3. Maps each scope to an authority with the prefix `SCOPE_`.
NOTE: As the authorization server makes available new keys, Spring Security automatically rotates the keys used to validate the JWT tokens.
[NOTE]
====
As the authorization server makes available new keys, Spring Security automatically rotates the keys used to validate the JWT tokens.
====
By default, the resulting `Authentication#getPrincipal` is a Spring Security `Jwt` object, and `Authentication#getName` maps to the JWT's `sub` property, if one is present.
@ -106,12 +118,18 @@ spring:
----
====
NOTE: The JWK Set uri is not standardized, but you can typically find it in the authorization server's documentation.
[NOTE]
====
The JWK Set uri is not standardized, but you can typically find it in the authorization server's documentation.
====
Consequently, Resource Server does not ping the authorization server at startup.
We still specify the `issuer-uri` so that Resource Server still validates the `iss` claim on incoming JWTs.
NOTE: You can supply this property directly on the <<webflux-oauth2resourceserver-jwt-jwkseturi-dsl,DSL>>.
[NOTE]
====
You can supply this property directly on the <<webflux-oauth2resourceserver-jwt-jwkseturi-dsl,DSL>>.
====
[[webflux-oauth2resourceserver-jwt-sansboot]]
=== Overriding or Replacing Boot Auto Configuration
@ -221,8 +239,11 @@ fun jwtDecoder(): ReactiveJwtDecoder {
----
====
NOTE: Calling `{security-api-url}org/springframework/security/oauth2/jwt/ReactiveJwtDecoders.html#fromIssuerLocation-java.lang.String-[ReactiveJwtDecoders#fromIssuerLocation]` invokes the Provider Configuration or Authorization Server Metadata endpoint to derive the JWK Set URI.
[NOTE]
====
Calling `{security-api-url}org/springframework/security/oauth2/jwt/ReactiveJwtDecoders.html#fromIssuerLocation-java.lang.String-[ReactiveJwtDecoders#fromIssuerLocation]` invokes the Provider Configuration or Authorization Server Metadata endpoint to derive the JWK Set URI.
If the application does not expose a `ReactiveJwtDecoder` bean, Spring Boot exposes the above default one.
====
Its configuration can be overridden by using `jwkSetUri()` or replaced by using `decoder()`.
@ -939,8 +960,11 @@ Where `https://idp.example.com/introspect` is the introspection endpoint hosted
Resource Server uses these properties to further self-configure and subsequently validate incoming JWTs.
NOTE: When using introspection, the authorization server's word is the law.
[NOTE]
====
When using introspection, the authorization server's word is the law.
If the authorization server responses that the token is valid, it is.
====
==== Startup Expectations
@ -1796,8 +1820,11 @@ return http {
In this case, you construct `JwtIssuerReactiveAuthenticationManagerResolver` with a strategy for obtaining the `ReactiveAuthenticationManager` given to the issuer.
This approach lets us add and remove elements from the repository (shown as a `Map` in the preceding snippet) at runtime.
NOTE: It would be unsafe to simply take any issuer and construct an `ReactiveAuthenticationManager` from it.
[NOTE]
====
It would be unsafe to simply take any issuer and construct an `ReactiveAuthenticationManager` from it.
The issuer should be one that the code can verify from a trusted source, such as an allowed list of issuers.
====
[[webflux-oauth2resourceserver-bearertoken-resolver]]
== Bearer Token Resolution
@ -1914,5 +1941,8 @@ rest.get()
In this case, the filter falls back and forwards the request onto the rest of the web filter chain.
NOTE: Unlike the https://docs.spring.io/spring-security/site/docs/current-SNAPSHOT/api/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunction.html[OAuth 2.0 Client filter function], this filter function makes no attempt to renew the token, should it be expired.
[NOTE]
====
Unlike the https://docs.spring.io/spring-security/site/docs/current-SNAPSHOT/api/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunction.html[OAuth 2.0 Client filter function], this filter function makes no attempt to renew the token, should it be expired.
To obtain this level of support, use the OAuth 2.0 Client filter.
====

View File

@ -3,7 +3,10 @@
Spring Security allows resolving an access token by using `@RegisteredOAuth2AuthorizedClient`.
NOTE: You can find a working example in the {gh-samples-url}/boot/oauth2webclient-webflux[OAuth 2.0 WebClient WebFlux sample].
[NOTE]
====
You can find a working example in the {gh-samples-url}/boot/oauth2webclient-webflux[OAuth 2.0 WebClient WebFlux sample].
====
After configuring Spring Security for <<webflux-oauth2-login,OAuth2 Login>> or as an <<webflux-oauth2-client,OAuth2 Client>>, you can resolve an `OAuth2AuthorizedClient` by using the following:

View File

@ -82,8 +82,11 @@ This means that individual users can make requests but not make additional conne
Spring Security has support for the https://github.com/rsocket/rsocket/blob/5920ed374d008abb712cb1fd7c9d91778b2f4a68/Extensions/Security/Simple.md[Simple Authentication Metadata Extension].
NOTE: Basic Authentication evolved into Simple Authentication and is only supported for backward compatibility.
[NOTE]
====
Basic Authentication evolved into Simple Authentication and is only supported for backward compatibility.
See `RSocketSecurity.basicAuthentication(Customizer)` for setting it up.
====
The RSocket receiver can decode the credentials by using `AuthenticationPayloadExchangeConverter`, which is automatically setup by using the `simpleAuthentication` portion of the DSL.
The following example shows an explicit configuration:

View File

@ -1,8 +1,11 @@
[[webclient]]
= WebClient
NOTE: The documentation in this section is for use within Reactive environments.
[NOTE]
====
The documentation in this section is for use within Reactive environments.
For Servlet environments, see <<oauth2Client-webclient-servlet, WebClient for Servlet>>.
====
Spring Framework has built-in support for setting a Bearer token:

View File

@ -259,10 +259,13 @@ This happens because sessions created under HTTPS, for which the session cookie
However, Spring Security's https://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-session-fixation[Session Fixation Protection] can interfere with this because it results in a new session ID cookie being sent back to the user's browser, usually with the secure flag.
To get around this, you can disable session fixation protection. However, in newer Servlet containers, you can also configure session cookies to never use the secure flag.
IMPORTANT: Switching between HTTP and HTTPS is not a good idea in general, as any application that uses HTTP at all is vulnerable to man-in-the-middle attacks.
[IMPORTANT]
====
Switching between HTTP and HTTPS is not a good idea in general, as any application that uses HTTP at all is vulnerable to man-in-the-middle attacks.
To be truly secure, the user should begin accessing your site in HTTPS and continue using it until they log out.
Even clicking on an HTTPS link from a page accessed over HTTP is potentially risky.
If you need more convincing, check out a tool such as https://www.thoughtcrime.org/software/sslstrip/[sslstrip].
====
==== I am not switching between HTTP and HTTPS, but my session is still lost. What happened?

View File

@ -554,7 +554,11 @@ The policy value to write for the `Permissions-Policy` header
[[nsa-xss-protection]]
==== <xss-protection>
The `<xss-protection>` adds the https://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-iv-the-xss-filter.aspx[X-XSS-Protection header] to the response, to assist in protecting against https://en.wikipedia.org/wiki/Cross-site_scripting#Non-Persistent[reflected / Type-1 Cross-Site Scripting (XSS)] attacks.
NOTE: Full protection against XSS attacks is not possible.
[NOTE]
====
Full protection against XSS attacks is not possible.
====
[[nsa-xss-protection-attributes]]
@ -803,8 +807,11 @@ This always takes precedence over other namespace-created entry points.
If no attributes are supplied, a login page is generated automatically at the `/login` URL.
You can customize this behavior by setting the <<nsa-form-login-attributes, `<form-login>` Attributes>>.
NOTE: This feature is provided for convenience and is not intended for production (where a view technology should have been chosen and can be used to render a customized login page).
[NOTE]
====
This feature is provided for convenience and is not intended for production (where a view technology should have been chosen and can be used to render a customized login page).
The class `DefaultLoginPageGeneratingFilter` class is responsible for rendering the login page and provide login forms for both normal form login and OpenID if required.
====
[[nsa-form-login-parents]]
@ -1370,7 +1377,10 @@ If this attribute is present on any `<intercept-url>` element, a `ChannelProcess
If a `<port-mappings>` configuration is added, it is used by the `SecureChannelProcessor` and `InsecureChannelProcessor` beans to determine the ports used for redirecting to HTTP and HTTPS.
NOTE: This property is invalid for <<nsa-filter-security-metadata-source,`filter-security-metadata-source`>>
[NOTE]
====
This property is invalid for <<nsa-filter-security-metadata-source,`filter-security-metadata-source`>>
====
[[nsa-intercept-url-servlet-path]]
`servlet-path`::
@ -1380,7 +1390,10 @@ In addition, the value is only required in the following two use cases:
* Two or more `HttpServlet` instances that have mappings starting with `/` and are different are registered in the `ServletContext`.
* The pattern starts with the same value of a registered `HttpServlet` path, excluding the default (root) `HttpServlet` `/`.
NOTE: This property is invalid for <<nsa-filter-security-metadata-source,`filter-security-metadata-source`>>
[NOTE]
====
This property is invalid for <<nsa-filter-security-metadata-source,`filter-security-metadata-source`>>
====
[[nsa-jee]]
@ -2316,8 +2329,11 @@ The `<password-encoder>` element has the following attributes:
[[nsa-password-encoder-hash]]
`hash`::
Defines the hashing algorithm for user passwords.
IMPORTANT: We recommend strongly against using MD4, as it is a very weak hashing algorithm.
[IMPORTANT]
====
We recommend strongly against using MD4, as it is a very weak hashing algorithm.
====
[[nsa-password-encoder-ref]]
`ref`::
@ -2473,9 +2489,13 @@ mode::
You can set this attribute to `aspectj` to specify that AspectJ should be used instead of the default Spring AOP.
You must weave secured methods with the `AnnotationSecurityAspect` from the `spring-security-aspects` module.
+
NOTE: AspectJ follows Java's rule that annotations on interfaces are not inherited.
[NOTE]
====
AspectJ follows Java's rule that annotations on interfaces are not inherited.
This means that methods that define the Security annotations on the interface are not secured.
Instead, you must place the Security annotation on the class when you use AspectJ.
====
[[nsa-global-method-security-order]]
`order`::

View File

@ -25,7 +25,10 @@ For example, it might redirect to a log in page or send a `WWW-Authenticate` hea
The `AccessDeniedHandler` is invoked to handle access denied.
// FIXME: link to AccessDeniedHandler
NOTE: If the application does not throw an `AccessDeniedException` or an `AuthenticationException`, `ExceptionTranslationFilter` does not do anything.
[NOTE]
====
If the application does not throw an `AccessDeniedException` or an `AuthenticationException`, `ExceptionTranslationFilter` does not do anything.
====
The pseudocode for `ExceptionTranslationFilter` looks something like this:

View File

@ -48,11 +48,14 @@ The filter and authentication provider is defined as follows:
The `key` is shared between the filter and authentication provider so that tokens created by the former are accepted by the latter
NOTE: The use of the `key` property should not be regarded as providing any real security here.
[NOTE]
====
The use of the `key` property should not be regarded as providing any real security here.
It is merely a book-keeping exercise.
If you share a `ProviderManager` that contains an `AnonymousAuthenticationProvider` in a scenario where it is possible for an authenticating client to construct the `Authentication` object (such as with RMI invocations), then a malicious client could submit an `AnonymousAuthenticationToken` that it had created itself (with the chosen username and authority list).
If the `key` is guessable or can be found out, the token would be accepted by the anonymous provider.
This is not a problem with normal usage. However, if you use RMI, you should use a customized `ProviderManager` that omits the anonymous provider rather than sharing the one you use for your HTTP authentication mechanisms.
====
The `userAttribute` is expressed in the form of `usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]`.
The same syntax is used after the equals sign for the `userMap` property of `InMemoryDaoImpl`.

View File

@ -15,7 +15,10 @@ While the CAS web site contains documents that detail the architecture of CAS, w
Spring Security 3.x (and later) supports CAS 3 (and later).
At the time of writing, the CAS server is at version 6.3.3.
NOTE: This section was written about CAS version 3.4, but the material is still current.
[NOTE]
====
This section was written about CAS version 3.4, but the material is still current.
====
Somewhere in your enterprise, you need to setup a CAS server.
The CAS server runs from a standard WAR file.

View File

@ -73,8 +73,11 @@ By default, `SecurityContextLogoutHandler` is added as the last `LogoutHandler`.
<7> Lets specifying the names of cookies be removed on logout success.
This is a shortcut for adding a `CookieClearingLogoutHandler` explicitly.
NOTE: Logouts can also be configured by using the XML Namespace notation.
[NOTE]
====
Logouts can also be configured by using the XML Namespace notation.
See the documentation for the <<nsa-logout,logout element>> in the Spring Security XML Namespace section for further details.
====
Generally, to customize logout functionality, you can add
`{security-api-url}org/springframework/security/web/authentication/logout/LogoutHandler.html[LogoutHandler]`

View File

@ -1,7 +1,10 @@
[[servlet-openid]]
== OpenID Support
NOTE: The OpenID 1.0 and 2.0 protocols have been deprecated. You should migrate to OpenID Connect, which is supported by `spring-security-oauth2`.
[NOTE]
====
The OpenID 1.0 and 2.0 protocols have been deprecated. You should migrate to OpenID Connect, which is supported by `spring-security-oauth2`.
====
The namespace supports https://openid.net/[OpenID] login either instead of or in addition to normal form-based login, with a simple change:

View File

@ -100,8 +100,12 @@ This mechanism is supported by the `RequestHeaderAuthenticationFilter` class, wh
It defaults to using a name of `SM_USER` as the header name.
See the Javadoc for more details.
TIP: When using a system like this, the framework performs no authentication checks at all, and it is _extremely_ important that the external system is configured properly and protects all access to the application.
[TIP]
====
When using a system like this, the framework performs no authentication checks at all, and it is _extremely_ important that the external system is configured properly and protects all access to the application.
If an attacker is able to forge the headers in their original request without this being detected, they could potentially choose any username they wished.
====
===== Siteminder Example Configuration
The following example shows a typical configuration that uses this filter:

View File

@ -127,8 +127,11 @@ See the <<session-mgmt,Session Management>> chapter for additional information.
=== SessionManagementFilter
The `SessionManagementFilter` checks the contents of the `SecurityContextRepository` against the current contents of the `SecurityContextHolder` to determine whether a user has been authenticated during the current request, typically by a non-interactive authentication mechanism, such as pre-authentication or remember-me
NOTE: Authentication by mechanisms that perform a redirect after authenticating (such as form-login) are not detected by `SessionManagementFilter`, as the filter is not invoked during the authenticating request.
[NOTE]
====
Authentication by mechanisms that perform a redirect after authenticating (such as form-login) are not detected by `SessionManagementFilter`, as the filter is not invoked during the authenticating request.
Session-management functionality has to be handled separately in these cases.
====
If the repository contains a security context, the filter does nothing.
If it does not and the thread-local `SecurityContext` contains a (non-anonymous) `Authentication` object, the filter assumes they have been authenticated by a previous filter in the stack.
@ -179,10 +182,13 @@ Sometimes, though, you need to customize things.
The implementation uses a specialized version of `SessionAuthenticationStrategy`, called `ConcurrentSessionControlAuthenticationStrategy`.
NOTE: Previously, the concurrent authentication check was made by the `ProviderManager`, which could be injected with a `ConcurrentSessionController`.
[NOTE]
====
Previously, the concurrent authentication check was made by the `ProviderManager`, which could be injected with a `ConcurrentSessionController`.
The latter would check if the user was attempting to exceed the number of permitted sessions.
However, this approach required that an HTTP session be created in advance, which is undesirable.
In Spring Security 3 and later, the user is first authenticated by the `AuthenticationManager` and once they are successfully authenticated, a session is created and the check is made whether they are allowed to have another session open.
====
To use concurrent session support, you need to add the following to `web.xml`:

View File

@ -3,10 +3,13 @@
This section provides details on how Spring Security provides support for https://tools.ietf.org/html/rfc2617[Digest Authentication], which is provided `DigestAuthenticationFilter`.
WARNING: You should not use Digest Authentication in modern applications, because it is not considered to be secure.
[WARNING]
====
You should not use Digest Authentication in modern applications, because it is not considered to be secure.
The most obvious problem is that you must store your passwords in plaintext or an encrypted or MD5 format.
All of these storage formats are considered insecure.
Instead, you should store credentials by using a one way adaptive password hash (bCrypt, PBKDF2, SCrypt, and others), which is not supported by Digest Authentication.
====
Digest Authentication tries to solve many of the weaknesses of <<servlet-authentication-basic,Basic authentication>>, specifically by ensuring credentials are never sent in clear text across the wire.
Many https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Digest#Browser_compatibility[browsers support Digest Authentication].

View File

@ -23,7 +23,10 @@ You need to adjust the schema to match any customizations to the queries and the
`JdbcDaoImpl` requires tables to load the password, account status (enabled or disabled) and a list of authorities (roles) for the user.
NOTE: The default schema is also exposed as a classpath resource named `org/springframework/security/core/userdetails/jdbc/users.ddl`.
[NOTE]
====
The default schema is also exposed as a classpath resource named `org/springframework/security/core/userdetails/jdbc/users.ddl`.
====
.Default User Schema
====

View File

@ -155,9 +155,12 @@ fun ldapContainer(): UnboundIdContainer {
[[servlet-authentication-ldap-apacheds]]
=== Embedded ApacheDS Server
NOTE: Spring Security uses ApacheDS 1.x, which is no longer maintained.
[NOTE]
====
Spring Security uses ApacheDS 1.x, which is no longer maintained.
Unfortunately, ApacheDS 2.x has only released milestone versions with no stable release.
Once a stable release of ApacheDS 2.x is available, we will consider updating.
====
If you wish to use https://directory.apache.org/apacheds/[Apache DS], specify the following dependencies:
@ -543,8 +546,11 @@ To make this easier, Spring Security has an authentication provider, which is cu
Configuring `ActiveDirectoryLdapAuthenticationProvider` is quite straightforward.
You need only supply the domain name and an LDAP URL that supplies the address of the server.
NOTE: It is also possible to obtain the server's IP address byusing a DNS lookup.
[NOTE]
====
It is also possible to obtain the server's IP address byusing a DNS lookup.
This is not currently supported, but hopefully will be in a future version.
====
The following example configures Active Directory:

View File

@ -7,7 +7,10 @@ Spring Security provides <<servlet-authentication-inmemory,in-memory>> and <<ser
You can define custom authentication by exposing a custom `UserDetailsService` as a bean.
For example, the following listing customizes authentication, assuming that `CustomUserDetailsService` implements `UserDetailsService`:
NOTE: This is only used if the `AuthenticationManagerBuilder` has not been populated and no `AuthenticationProviderBean` is defined.
[NOTE]
====
This is only used if the `AuthenticationManagerBuilder` has not been populated and no `AuthenticationProviderBean` is defined.
====
.Custom UserDetailsService Bean
====

View File

@ -20,7 +20,10 @@ This simplifies reuse and customization.
5. Complies with JSR-250
6. Enables `@PreAuthorize`, `@PostAuthorize`, `@PreFilter`, and `@PostFilter` by default
NOTE: For earlier versions, please read about similar support with <<jc-enable-global-method-security, @EnableGlobalMethodSecurity>>.
[NOTE]
====
For earlier versions, please read about similar support with <<jc-enable-global-method-security, @EnableGlobalMethodSecurity>>.
====
For example, the following would enable Spring Security's `@PreAuthorize` annotation:
@ -772,11 +775,17 @@ public Account post(Account account, double amount);
Expression-based annotations are a good choice if you need to define simple rules that go beyond checking the role names against the user's list of authorities.
NOTE: The annotated methods will only be secured for instances which are defined as Spring beans (in the same application context in which method-security is enabled).
[NOTE]
====
The annotated methods will only be secured for instances which are defined as Spring beans (in the same application context in which method-security is enabled).
If you want to secure instances which are not created by Spring (using the `new` operator, for example) then you need to use AspectJ.
====
NOTE: You can enable more than one type of annotation in the same application, but only one type should be used for any interface or class as the behaviour will not be well-defined otherwise.
[NOTE]
====
You can enable more than one type of annotation in the same application, but only one type should be used for any interface or class as the behaviour will not be well-defined otherwise.
If two annotations are found which apply to a particular method, then only one of them will be applied.
====
[[ns-protect-pointcut]]
=== Adding Security Pointcuts by using protect-pointcut

View File

@ -14,7 +14,11 @@ This class lets you create {security-api-url}org/springframework/security/crypto
You can also construct {security-api-url}org/springframework/security/crypto/encrypt/TextEncryptor.html[TextEncryptor] instances to encrypt text strings.
Encryptors are thread-safe.
NOTE: Both `BytesEncryptor` and `TextEncryptor` are interfaces. `BytesEncryptor` has multiple implementations.
[NOTE]
====
Both `BytesEncryptor` and `TextEncryptor` are interfaces. `BytesEncryptor` has multiple implementations.
====
[[spring-security-crypto-encryption-bytes]]
=== BytesEncryptor

View File

@ -48,9 +48,12 @@ You can configure `CookieCsrfTokenRepository` in XML byusing the following:
----
====
NOTE: The sample explicitly sets `cookieHttpOnly=false`.
[NOTE]
====
The sample explicitly sets `cookieHttpOnly=false`.
This is necessary to allow JavaScript (such as AngularJS) to read it.
If you do not need the ability to read the cookie with JavaScript directly, we recommend omitting `cookieHttpOnly=false` to improve security.
====
You can configure `CookieCsrfTokenRepository` in Java or Kotlin configuration by using:
@ -90,9 +93,12 @@ class SecurityConfig : WebSecurityConfigurerAdapter() {
----
====
NOTE: The sample explicitly sets `cookieHttpOnly=false`.
[NOTE]
====
The sample explicitly sets `cookieHttpOnly=false`.
This is necessary to let JavaScript (such as AngularJS) read it.
If you do not need the ability to read the cookie with JavaScript directly, we recommend omitting `cookieHttpOnly=false` (by using `new CookieCsrfTokenRepository()` instead) to improve security.
====
[[servlet-csrf-configure-disable]]
==== Disable CSRF Protection
@ -375,7 +381,10 @@ For an example of how to customize the `AccessDeniedHandler`, see the provided l
We have <<csrf-considerations-multipart,already discussed>> how protecting multipart requests (file uploads) from CSRF attacks causes a https://en.wikipedia.org/wiki/Chicken_or_the_egg[chicken and the egg] problem.
This section discusses how to implement placing the CSRF token in the <<servlet-csrf-considerations-multipart-body,body>> and <<servlet-csrf-considerations-multipart-url,url>> within a servlet application.
NOTE: You can find more information about using multipart forms with Spring in the https://docs.spring.io/spring/docs/5.2.x/spring-framework-reference/web.html#mvc-multipart[1.1.11. Multipart Resolver] section of the Spring reference and the https://docs.spring.io/spring/docs/5.2.x/javadoc-api/org/springframework/web/multipart/support/MultipartFilter.html[`MultipartFilter` javadoc].
[NOTE]
====
You can find more information about using multipart forms with Spring in the https://docs.spring.io/spring/docs/5.2.x/spring-framework-reference/web.html#mvc-multipart[1.1.11. Multipart Resolver] section of the Spring reference and the https://docs.spring.io/spring/docs/5.2.x/javadoc-api/org/springframework/web/multipart/support/MultipartFilter.html[`MultipartFilter` javadoc].
====
[[servlet-csrf-considerations-multipart-body]]
==== Place CSRF Token in the Body

View File

@ -120,10 +120,13 @@ fun httpFirewall(): StrictHttpFirewall {
----
====
TIP: If you use `new MockHttpServletRequest()`, it currently creates an HTTP method as an empty String (`""`).
[TIP]
====
If you use `new MockHttpServletRequest()`, it currently creates an HTTP method as an empty String (`""`).
This is an invalid HTTP method and is rejected by Spring Security.
You can resolve this by replacing it with `new MockHttpServletRequest("GET", "")`.
See https://jira.spring.io/browse/SPR-16851[SPR_16851] for an issue that requests improving this.
====
If you must allow any HTTP method (not recommended), you can use `StrictHttpFirewall.setUnsafeAllowAnyHttpMethod(true)`.
Doing so entirely disables validation of the HTTP method.
@ -139,7 +142,10 @@ This requirement can be relaxed or adjusted as necessary by using the following
* `StrictHttpFirewall#setAllowedHeaderValues(Predicate)`
* `StrictHttpFirewall#setAllowedParameterNames(Predicate)`
NOTE: Parameter values can be also controlled with `setAllowedParameterValues(Predicate)`.
[NOTE]
====
Parameter values can be also controlled with `setAllowedParameterValues(Predicate)`.
====
For example, to switch off this check, you can wire your `StrictHttpFirewall` with `Predicate` instances that always return `true`:

View File

@ -3,8 +3,11 @@
This section covers the minimum setup for how to use Spring Security with Spring Boot.
NOTE: The completed application can be found at {gh-samples-url}/boot/helloworld[samples/boot/helloworld]
[NOTE]
====
The completed application can be found at {gh-samples-url}/boot/helloworld[samples/boot/helloworld]
For your convenience, you can download 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[a minimal Spring Boot + Spring Security application].
====
[[servlet-hello-dependencies]]
== Updating Dependencies

View File

@ -18,7 +18,10 @@ To use any of the tags, you must have the security taglib declared in your JSP:
This tag is used to determine whether its contents should be evaluated or not.
In Spring Security 3.0, it can be used in two ways.
NOTE: The legacy options from Spring Security 2.0 are also supported, but discouraged.
[NOTE]
====
The legacy options from Spring Security 2.0 are also supported, but discouraged.
====
The first approach uses a <<el-access-web,web-security expression>>, which is specified in the `access` attribute of the tag.
The expression evaluation is delegated to the `SecurityExpressionHandler<FilterInvocation>` defined in the application context (you should have web expressions enabled in your `<http>` namespace configuration to make sure this service is available).
@ -100,8 +103,11 @@ It checks a comma-separated list of required permissions for a specified domain
If the current user has all of those permissions, the tag body is evaluated.
If they do not, it is skipped.
CAUTION: In general this tag should be considered deprecated.
Instead use the <<taglibs-authorize>>.
[CAUTION]
====
In general, this tag should be considered deprecated.
Instead, use the <<taglibs-authorize>>.
====
The following listing shows an example:

View File

@ -7,13 +7,19 @@ This section covers the integration in further detail.
[[mvc-enablewebmvcsecurity]]
=== @EnableWebMvcSecurity
NOTE: As of Spring Security 4.0, `@EnableWebMvcSecurity` is deprecated.
[NOTE]
====
As of Spring Security 4.0, `@EnableWebMvcSecurity` is deprecated.
The replacement is `@EnableWebSecurity`, which adds the Spring MVC features, based upon the classpath.
====
To enable Spring Security integration with Spring MVC, add the `@EnableWebSecurity` annotation to your configuration.
NOTE: Spring Security provides the configuration by using Spring MVC's https://docs.spring.io/spring/docs/5.0.0.RELEASE/spring-framework-reference/web.html#mvc-config-customize[`WebMvcConfigurer`].
[NOTE]
====
Spring Security provides the configuration by using Spring MVC's https://docs.spring.io/spring/docs/5.0.0.RELEASE/spring-framework-reference/web.html#mvc-config-customize[`WebMvcConfigurer`].
This means that, if you use more advanced options, such as integrating with `WebMvcConfigurationSupport` directly, you need to manually provide the Spring Security configuration.
====
[[mvc-requestmatcher]]
=== MvcRequestMatcher
@ -273,8 +279,11 @@ public ModelAndView updateName(@AuthenticationPrincipal(expression = "@jpaEntity
We can further remove our dependency on Spring Security by making `@AuthenticationPrincipal` a meta-annotation on our own annotation.
The next example demonstrates how we could do so on an annotation named `@CurrentUser`.
NOTE: To remove the dependency on Spring Security, it is the consuming application that would create `@CurrentUser`.
[NOTE]
====
To remove the dependency on Spring Security, it is the consuming application that would create `@CurrentUser`.
This step is not strictly required but assists in isolating your dependency to Spring Security to a more central location.
====
====
[source,java]
@ -325,8 +334,12 @@ return new Callable<String>() {
====
.Associating SecurityContext to Callable's
NOTE: More technically speaking, Spring Security integrates with `WebAsyncManager`.
[NOTE]
====
More technically speaking, Spring Security integrates with `WebAsyncManager`.
The `SecurityContext` that is used to process the `Callable` is the `SecurityContext` that exists on the `SecurityContextHolder` when `startCallableProcessing` is invoked.
====
There is no automatic integration with a `DeferredResult` that is returned by controllers.
This is because `DeferredResult` is processed by the users and, thus, there is no way of automatically integrating with it.

View File

@ -37,8 +37,11 @@ String lastName = userDetails.getLastName();
----
====
NOTE: It is typically bad practice to perform logic throughout your application.
[NOTE]
====
It is typically bad practice to perform logic throughout your application.
Instead, you should centralize it to reduce any coupling of Spring Security and the Servlet API.
====
[[servletapi-user-in-role]]
==== HttpServletRequest.isUserInRole(String)
@ -83,7 +86,10 @@ httpServletRequest.login("user","password");
----
====
NOTE: You need not catch the `ServletException` if you want Spring Security to process the failed authentication attempt.
[NOTE]
====
You need not catch the `ServletException` if you want Spring Security to process the failed authentication attempt.
====
[[servletapi-logout]]
==== HttpServletRequest.logout()

View File

@ -6,7 +6,11 @@ Spring Security 3.2 introduced Java configuration to let users configure Spring
If you are familiar with the <<ns-config>>, you should find quite a few similarities between it and Spring Security Java configuration.
NOTE: Spring Security provides https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration[lots of sample applications] to demonstrate the use of Spring Security Java Configuration.
[NOTE]
====
Spring Security provides https://github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration[lots of sample applications] to demonstrate the use of Spring Security Java Configuration.
====
[[jc-hello-wsca]]
== Hello Web Security Java Configuration
@ -273,7 +277,10 @@ public class MyCustomDsl extends AbstractHttpConfigurer<MyCustomDsl, HttpSecurit
----
====
NOTE: This is actually how methods like `HttpSecurity.authorizeRequests()` are implemented.
[NOTE]
====
This is actually how methods like `HttpSecurity.authorizeRequests()` are implemented.
====
You can then use the custom DSL:

View File

@ -4,7 +4,10 @@
Spring Security Kotlin configuration has been available since Spring Security 5.3.
It lets users configure Spring Security by using a native Kotlin DSL.
NOTE: Spring Security provides https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/kotlin/hello-security[a sample application] to demonstrate the use of Spring Security Kotlin Configuration.
[NOTE]
====
Spring Security provides https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/kotlin/hello-security[a sample application] to demonstrate the use of Spring Security Kotlin Configuration.
====
[[kotlin-config-httpsecurity]]
== HttpSecurity

View File

@ -150,9 +150,12 @@ We see later how the interpretation can vary. The interpretation of the comma-se
Since Spring Security 3.0, you can also populate the attribute with an <<el-access,EL expression>>.
NOTE: You can use multiple `<intercept-url>` elements to define different access requirements for different sets of URLs, but they are evaluated in the order listed and the first match is used.
[NOTE]
====
You can use multiple `<intercept-url>` elements to define different access requirements for different sets of URLs, but they are evaluated in the order listed and the first match is used.
So you must put the most specific matches at the top.
You can also add a `method` attribute to limit the match to a particular HTTP method (`GET`, `POST`, `PUT`, and so on).
====
To add users, you can define a set of test data directly in the namespace:
@ -252,9 +255,12 @@ How can you do this with namespace configuration, since the filter chain is not
The order of the filters is always strictly enforced when you use the namespace.
When the application context is being created, the filter beans are sorted by the namespace handling code, and the standard Spring Security filters each have an alias in the namespace and a well-known position.
NOTE: In previous versions, the sorting took place after the filter instances had been created, during post-processing of the application context.
[NOTE]
====
In previous versions, the sorting took place after the filter instances had been created, during post-processing of the application context.
In version 3.0+, the sorting is now done at the bean metadata level, before the classes have been instantiated.
This has implications for how you add your own filters to the stack, as the entire filter list must be known during the parsing of the `<http>` element. As a result, the syntax changed slightly in version 3.0.
====
The filters, aliases, and namespace elements and attributes that create the filters are shown in the following table, in the order in which they occur in the filter chain:

View File

@ -264,12 +264,18 @@ As an alternative, you can use `ClientRegistrations.fromOidcIssuerLocation()` to
The `ClientRegistrationRepository` serves as a repository for OAuth 2.0 / OpenID Connect 1.0 `ClientRegistration`(s).
NOTE: Client registration information is ultimately stored and owned by the associated Authorization Server.
[NOTE]
====
Client registration information is ultimately stored and owned by the associated Authorization Server.
This repository provides the ability to retrieve a subset of the primary client registration information, which is stored with the Authorization Server.
====
Spring Boot 2.x auto-configuration binds each of the properties under `spring.security.oauth2.client.registration._[registrationId]_` to an instance of `ClientRegistration` and then composes each of the `ClientRegistration` instance(s) within a `ClientRegistrationRepository`.
NOTE: The default implementation of `ClientRegistrationRepository` is `InMemoryClientRegistrationRepository`.
[NOTE]
====
The default implementation of `ClientRegistrationRepository` is `InMemoryClientRegistrationRepository`.
====
The auto-configuration also registers the `ClientRegistrationRepository` as a `@Bean` in the `ApplicationContext` so that it is available for dependency injection, if needed by the application.
@ -385,15 +391,20 @@ class OAuth2ClientController {
----
====
NOTE: Spring Boot 2.x auto-configuration registers an `OAuth2AuthorizedClientRepository` or an `OAuth2AuthorizedClientService` `@Bean` in the `ApplicationContext`.
[NOTE]
====
Spring Boot 2.x auto-configuration registers an `OAuth2AuthorizedClientRepository` or an `OAuth2AuthorizedClientService` `@Bean` in the `ApplicationContext`.
However, the application can override and register a custom `OAuth2AuthorizedClientRepository` or `OAuth2AuthorizedClientService` `@Bean`.
====
The default implementation of `OAuth2AuthorizedClientService` is `InMemoryOAuth2AuthorizedClientService`, which stores `OAuth2AuthorizedClient` objects in-memory.
Alternatively, you can configure the JDBC implementation `JdbcOAuth2AuthorizedClientService` to persist `OAuth2AuthorizedClient` instances in a database.
NOTE: `JdbcOAuth2AuthorizedClientService` depends on the table definition described in <<dbschema-oauth2-client, OAuth 2.0 Client Schema>>.
[NOTE]
====
`JdbcOAuth2AuthorizedClientService` depends on the table definition described in <<dbschema-oauth2-client, OAuth 2.0 Client Schema>>.
====
[[oauth2Client-authorized-manager-provider]]
==== OAuth2AuthorizedClientManager and OAuth2AuthorizedClientProvider
@ -616,12 +627,18 @@ This section describes Spring Security's support for authorization grants.
[[oauth2Client-auth-code-grant]]
==== Authorization Code
NOTE: See the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.3.1[Authorization Code] grant.
[NOTE]
====
See the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.3.1[Authorization Code] grant.
====
===== Obtaining Authorization
NOTE: See the https://tools.ietf.org/html/rfc6749#section-4.1.1[Authorization Request/Response] protocol flow for the Authorization Code grant.
[NOTE]
====
See the https://tools.ietf.org/html/rfc6749#section-4.1.1[Authorization Request/Response] protocol flow for the Authorization Code grant.
====
===== Initiating the Authorization Request
@ -656,8 +673,11 @@ spring:
Given the preceding properties, a request with the base path `/oauth2/authorization/okta` initiates the Authorization Request redirect by the `OAuth2AuthorizationRequestRedirectFilter` and ultimately starts the Authorization Code grant flow.
NOTE: The `AuthorizationCodeOAuth2AuthorizedClientProvider` is an implementation of `OAuth2AuthorizedClientProvider` for the Authorization Code grant,
[NOTE]
====
The `AuthorizationCodeOAuth2AuthorizedClientProvider` is an implementation of `OAuth2AuthorizedClientProvider` for the Authorization Code grant,
which also initiates the Authorization Request redirect by the `OAuth2AuthorizationRequestRedirectFilter`.
====
If the OAuth 2.0 Client is a https://tools.ietf.org/html/rfc6749#section-2.1[Public Client], configure the OAuth 2.0 Client registration as follows:
@ -704,7 +724,10 @@ spring:
----
====
NOTE: `+{baseUrl}+` resolves to `+{baseScheme}://{baseHost}{basePort}{basePath}+`
[NOTE]
====
`+{baseUrl}+` resolves to `+{baseScheme}://{baseHost}{basePort}{basePath}+`
====
Configuring the `redirect-uri` with `URI` template variables is especially useful when the OAuth 2.0 Client is running behind a <<http-proxy-server,Proxy Server>>.
Doing so ensures that the `X-Forwarded-*` headers are used when expanding the `redirect-uri`.
@ -716,7 +739,10 @@ One of the primary use cases an `OAuth2AuthorizationRequestResolver` can realize
For example, OpenID Connect defines additional OAuth 2.0 request parameters for the https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest[Authorization Code Flow] extending from the standard parameters defined in the https://tools.ietf.org/html/rfc6749#section-4.1.1[OAuth 2.0 Authorization Framework].
One of those extended parameters is the `prompt` parameter.
NOTE: The `prompt` parameter is optional. Space delimited, case sensitive list of ASCII string values that specifies whether the Authorization Server prompts the End-User for re-authentication and consent. The defined values are: `none`, `login`, `consent`, and `select_account`.
[NOTE]
====
The `prompt` parameter is optional. Space delimited, case sensitive list of ASCII string values that specifies whether the Authorization Server prompts the End-User for re-authentication and consent. The defined values are: `none`, `login`, `consent`, and `select_account`.
====
The following example shows how to configure the `DefaultOAuth2AuthorizationRequestResolver` with a `Consumer<OAuth2AuthorizationRequest.Builder>` that customizes the Authorization Request for `oauth2Login()`, by including the request parameter `prompt=consent`.
@ -825,7 +851,10 @@ spring:
The preceding example shows the common use case of adding a custom parameter on top of the standard parameters.
Alternatively, if your requirements are more advanced, you can take full control in building the Authorization Request URI by overriding the `OAuth2AuthorizationRequest.authorizationRequestUri` property.
TIP: `OAuth2AuthorizationRequest.Builder.build()` constructs the `OAuth2AuthorizationRequest.authorizationRequestUri`, which represents the Authorization Request URI that includes all query parameters that use the `application/x-www-form-urlencoded` format.
[TIP]
====
`OAuth2AuthorizationRequest.Builder.build()` constructs the `OAuth2AuthorizationRequest.authorizationRequestUri`, which represents the Authorization Request URI that includes all query parameters that use the `application/x-www-form-urlencoded` format.
====
The following example shows a variation of `authorizationRequestCustomizer()` from the preceding example and instead overrides the `OAuth2AuthorizationRequest.authorizationRequestUri` property:
@ -860,7 +889,10 @@ private fun authorizationRequestCustomizer(): Consumer<OAuth2AuthorizationReques
The `AuthorizationRequestRepository` is responsible for the persistence of the `OAuth2AuthorizationRequest` from the time the Authorization Request is initiated to the time the Authorization Response is received (the callback).
TIP: The `OAuth2AuthorizationRequest` is used to correlate and validate the Authorization Response.
[TIP]
====
The `OAuth2AuthorizationRequest` is used to correlate and validate the Authorization Response.
====
The default implementation of `AuthorizationRequestRepository` is `HttpSessionOAuth2AuthorizationRequestRepository`, which stores the `OAuth2AuthorizationRequest` in the `HttpSession`.
@ -918,7 +950,10 @@ class OAuth2ClientSecurityConfig : WebSecurityConfigurerAdapter() {
===== Requesting an Access Token
NOTE: See the https://tools.ietf.org/html/rfc6749#section-4.1.3[Access Token Request/Response] protocol flow for the Authorization Code grant.
[NOTE]
====
See the https://tools.ietf.org/html/rfc6749#section-4.1.3[Access Token Request/Response] protocol flow for the Authorization Code grant.
====
The default implementation of `OAuth2AccessTokenResponseClient` for the Authorization Code grant is `DefaultAuthorizationCodeTokenResponseClient`, which uses a `RestOperations` instance to exchange an authorization code for an access token at the Authorization Servers Token Endpoint.
@ -931,7 +966,10 @@ If you need to customize the pre-processing of the Token Request, you can provid
The default implementation (`OAuth2AuthorizationCodeGrantRequestEntityConverter`) builds a `RequestEntity` representation of a standard https://tools.ietf.org/html/rfc6749#section-4.1.3[OAuth 2.0 Access Token Request].
However, providing a custom `Converter` would let you extend the standard Token Request and add custom parameter(s).
IMPORTANT: The custom `Converter` must return a valid `RequestEntity` representation of an OAuth 2.0 Access Token Request that is understood by the intended OAuth 2.0 Provider.
[IMPORTANT]
====
The custom `Converter` must return a valid `RequestEntity` representation of an OAuth 2.0 Access Token Request that is understood by the intended OAuth 2.0 Provider.
====
===== Customizing the Access Token Response
@ -961,7 +999,10 @@ restTemplate.errorHandler = OAuth2ErrorResponseErrorHandler()
----
====
TIP: Spring MVC `FormHttpMessageConverter` is required, as it is used when sending the OAuth 2.0 Access Token Request.
[TIP]
====
Spring MVC `FormHttpMessageConverter` is required, as it is used when sending the OAuth 2.0 Access Token Request.
====
`OAuth2AccessTokenResponseHttpMessageConverter` is an `HttpMessageConverter` for an OAuth 2.0 Access Token Response.
You can provide `OAuth2AccessTokenResponseHttpMessageConverter.setTokenResponseConverter()` with a custom `Converter<Map<String, String>, OAuth2AccessTokenResponse>` that is used for converting the OAuth 2.0 Access Token Response parameters to an `OAuth2AccessTokenResponse`.
@ -1025,12 +1066,18 @@ class OAuth2ClientSecurityConfig : WebSecurityConfigurerAdapter() {
[[oauth2Client-refresh-token-grant]]
==== Refresh Token
NOTE: See the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.5[Refresh Token].
[NOTE]
====
See the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.5[Refresh Token].
====
===== Refreshing an Access Token
NOTE: See the https://tools.ietf.org/html/rfc6749#section-6[Access Token Request/Response] protocol flow for the Refresh Token grant.
[NOTE]
====
See the https://tools.ietf.org/html/rfc6749#section-6[Access Token Request/Response] protocol flow for the Refresh Token grant.
====
The default implementation of `OAuth2AccessTokenResponseClient` for the Refresh Token grant is `DefaultRefreshTokenTokenResponseClient`, which uses a `RestOperations` when refreshing an access token at the Authorization Servers Token Endpoint.
@ -1043,7 +1090,10 @@ If you need to customize the pre-processing of the Token Request, you can provid
The default implementation (`OAuth2RefreshTokenGrantRequestEntityConverter`) builds a `RequestEntity` representation of a standard https://tools.ietf.org/html/rfc6749#section-6[OAuth 2.0 Access Token Request].
However, providing a custom `Converter` would let you extend the standard Token Request and add custom parameter(s).
IMPORTANT: The custom `Converter` must return a valid `RequestEntity` representation of an OAuth 2.0 Access Token Request that is understood by the intended OAuth 2.0 Provider.
[IMPORTANT]
====
The custom `Converter` must return a valid `RequestEntity` representation of an OAuth 2.0 Access Token Request that is understood by the intended OAuth 2.0 Provider.
====
===== Customizing the Access Token Response
@ -1073,7 +1123,10 @@ restTemplate.errorHandler = OAuth2ErrorResponseErrorHandler()
----
====
TIP: Spring MVC `FormHttpMessageConverter` is required, as it is used when sending the OAuth 2.0 Access Token Request.
[TIP]
====
Spring MVC `FormHttpMessageConverter` is required, as it is used when sending the OAuth 2.0 Access Token Request.
====
`OAuth2AccessTokenResponseHttpMessageConverter` is a `HttpMessageConverter` for an OAuth 2.0 Access Token Response.
You can provide `OAuth2AccessTokenResponseHttpMessageConverter.setTokenResponseConverter()` with a custom `Converter<Map<String, String>, OAuth2AccessTokenResponse>` that is used for converting the OAuth 2.0 Access Token Response parameters to an `OAuth2AccessTokenResponse`.
@ -1129,12 +1182,18 @@ If the `OAuth2AuthorizedClient.getRefreshToken()` is available and the `OAuth2Au
[[oauth2Client-client-creds-grant]]
==== Client Credentials
NOTE: See the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.3.4[Client Credentials] grant.
[NOTE]
====
See the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.3.4[Client Credentials] grant.
====
===== Requesting an Access Token
NOTE: See the https://tools.ietf.org/html/rfc6749#section-4.4.2[Access Token Request/Response] protocol flow for the Client Credentials grant.
[NOTE]
====
See the https://tools.ietf.org/html/rfc6749#section-4.4.2[Access Token Request/Response] protocol flow for the Client Credentials grant.
====
The default implementation of `OAuth2AccessTokenResponseClient` for the Client Credentials grant is `DefaultClientCredentialsTokenResponseClient`, which uses a `RestOperations` when requesting an access token at the Authorization Servers Token Endpoint.
@ -1147,7 +1206,10 @@ If you need to customize the pre-processing of the Token Request, you can provid
The default implementation (`OAuth2ClientCredentialsGrantRequestEntityConverter`) builds a `RequestEntity` representation of a standard https://tools.ietf.org/html/rfc6749#section-4.4.2[OAuth 2.0 Access Token Request].
However, providing a custom `Converter` would let you extend the standard Token Request and add custom parameter(s).
IMPORTANT: The custom `Converter` must return a valid `RequestEntity` representation of an OAuth 2.0 Access Token Request that is understood by the intended OAuth 2.0 Provider.
[IMPORTANT]
====
The custom `Converter` must return a valid `RequestEntity` representation of an OAuth 2.0 Access Token Request that is understood by the intended OAuth 2.0 Provider.
====
===== Customizing the Access Token Response
@ -1177,7 +1239,10 @@ restTemplate.errorHandler = OAuth2ErrorResponseErrorHandler()
----
====
TIP: Spring MVC `FormHttpMessageConverter` is required, as it is used when sending the OAuth 2.0 Access Token Request.
[TIP]
====
Spring MVC `FormHttpMessageConverter` is required, as it is used when sending the OAuth 2.0 Access Token Request.
====
`OAuth2AccessTokenResponseHttpMessageConverter` is a `HttpMessageConverter` for an OAuth 2.0 Access Token Response.
You can provide `OAuth2AccessTokenResponseHttpMessageConverter.setTokenResponseConverter()` with a custom `Converter<Map<String, String>, OAuth2AccessTokenResponse>` that is used for converting the OAuth 2.0 Access Token Response parameters to an `OAuth2AccessTokenResponse`.
@ -1220,8 +1285,12 @@ authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider)
----
====
NOTE: `OAuth2AuthorizedClientProviderBuilder.builder().clientCredentials()` configures a `ClientCredentialsOAuth2AuthorizedClientProvider`,
[NOTE]
====
`OAuth2AuthorizedClientProviderBuilder.builder().clientCredentials()` configures a `ClientCredentialsOAuth2AuthorizedClientProvider`,
which is an implementation of an `OAuth2AuthorizedClientProvider` for the Client Credentials grant.
====
===== Using the Access Token
@ -1354,19 +1423,28 @@ class OAuth2ClientController {
----
====
NOTE: `HttpServletRequest` and `HttpServletResponse` are both OPTIONAL attributes.
[NOTE]
====
`HttpServletRequest` and `HttpServletResponse` are both OPTIONAL attributes.
If not provided, they default to `ServletRequestAttributes` by using `RequestContextHolder.getRequestAttributes()`.
====
[[oauth2Client-password-grant]]
==== Resource Owner Password Credentials
NOTE: See the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.3.3[Resource Owner Password Credentials] grant.
[NOTE]
====
See the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.3.3[Resource Owner Password Credentials] grant.
====
===== Requesting an Access Token
NOTE: See the https://tools.ietf.org/html/rfc6749#section-4.3.2[Access Token Request/Response] protocol flow for the Resource Owner Password Credentials grant.
[NOTE]
====
See the https://tools.ietf.org/html/rfc6749#section-4.3.2[Access Token Request/Response] protocol flow for the Resource Owner Password Credentials grant.
====
The default implementation of `OAuth2AccessTokenResponseClient` for the Resource Owner Password Credentials grant is `DefaultPasswordTokenResponseClient`, which uses a `RestOperations` when requesting an access token at the Authorization Servers Token Endpoint.
@ -1379,7 +1457,10 @@ If you need to customize the pre-processing of the Token Request, you can provid
The default implementation (`OAuth2PasswordGrantRequestEntityConverter`) builds a `RequestEntity` representation of a standard https://tools.ietf.org/html/rfc6749#section-4.3.2[OAuth 2.0 Access Token Request].
However, providing a custom `Converter` would let you extend the standard Token Request and add custom parameter(s).
IMPORTANT: The custom `Converter` must return a valid `RequestEntity` representation of an OAuth 2.0 Access Token Request that is understood by the intended OAuth 2.0 Provider.
[IMPORTANT]
====
The custom `Converter` must return a valid `RequestEntity` representation of an OAuth 2.0 Access Token Request that is understood by the intended OAuth 2.0 Provider.
====
===== Customizing the Access Token Response
@ -1409,7 +1490,10 @@ restTemplate.errorHandler = OAuth2ErrorResponseErrorHandler()
----
====
TIP: Spring MVC `FormHttpMessageConverter` is required, as it is used when sending the OAuth 2.0 Access Token Request.
[TIP]
====
Spring MVC `FormHttpMessageConverter` is required, as it is used when sending the OAuth 2.0 Access Token Request.
====
`OAuth2AccessTokenResponseHttpMessageConverter` is a `HttpMessageConverter` for an OAuth 2.0 Access Token Response.
You can provide `OAuth2AccessTokenResponseHttpMessageConverter.setTokenResponseConverter()` with a custom `Converter<Map<String, String>, OAuth2AccessTokenResponse>` that is used to convert the OAuth 2.0 Access Token Response parameters to an `OAuth2AccessTokenResponse`.
@ -1685,7 +1769,10 @@ restTemplate.errorHandler = OAuth2ErrorResponseErrorHandler()
----
====
TIP: Spring MVC `FormHttpMessageConverter` is required as it's used when sending the OAuth 2.0 Access Token Request.
[TIP]
====
Spring MVC `FormHttpMessageConverter` is required as it's used when sending the OAuth 2.0 Access Token Request.
====
`OAuth2AccessTokenResponseHttpMessageConverter` is a `HttpMessageConverter` for an OAuth 2.0 Access Token Response.
You can provide `OAuth2AccessTokenResponseHttpMessageConverter.setTokenResponseConverter()` with a custom `Converter<Map<String, String>, OAuth2AccessTokenResponse>` that is used for converting the OAuth 2.0 Access Token Response parameters to an `OAuth2AccessTokenResponse`.
@ -2246,8 +2333,10 @@ fun webClient(authorizedClientManager: OAuth2AuthorizedClientManager?): WebClien
----
====
WARNING: Be cautious with this feature, since all HTTP requests receive the access token.
[WARNING]
====
Be cautious with this feature, since all HTTP requests receive the access token.
====
Alternatively, if `setDefaultClientRegistrationId("okta")` is configured with a valid `ClientRegistration`, the `OAuth2AccessToken` associated with the `OAuth2AuthorizedClient` is used.
The following code shows the specific configuration:
@ -2281,4 +2370,7 @@ fun webClient(authorizedClientManager: OAuth2AuthorizedClientManager?): WebClien
----
====
WARNING: Be cautious with this feature, since all HTTP requests receive the access token.
[WARNING]
====
Be cautious with this feature, since all HTTP requests receive the access token.
====

View File

@ -4,7 +4,10 @@
The OAuth 2.0 Login feature lets an application have users log in to the application by using their existing account at an OAuth 2.0 Provider (such as GitHub) or OpenID Connect 1.0 Provider (such as Google).
OAuth 2.0 Login implements two use cases: "`Login with Google`" or "`Login with GitHub`".
NOTE: OAuth 2.0 Login is implemented by using the *Authorization Code Grant*, as specified in the https://tools.ietf.org/html/rfc6749#section-4.1[OAuth 2.0 Authorization Framework] and https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[OpenID Connect Core 1.0].
[NOTE]
====
OAuth 2.0 Login is implemented by using the *Authorization Code Grant*, as specified in the https://tools.ietf.org/html/rfc6749#section-4.1[OAuth 2.0 Authorization Framework] and https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[OpenID Connect Core 1.0].
====
[[oauth2login-sample-boot]]
@ -25,7 +28,10 @@ This section shows how to configure the {gh-samples-url}/boot/oauth2login[*OAuth
To use Google's OAuth 2.0 authentication system for login, you must set up a project in the Google API Console to obtain OAuth 2.0 credentials.
NOTE: https://developers.google.com/identity/protocols/OpenIDConnect[Google's OAuth 2.0 implementation] for authentication conforms to the https://openid.net/connect/[OpenID Connect 1.0] specification and is https://openid.net/certification/[OpenID certified].
[NOTE]
====
https://developers.google.com/identity/protocols/OpenIDConnect[Google's OAuth 2.0 implementation] for authentication conforms to the https://openid.net/connect/[OpenID Connect 1.0] specification and is https://openid.net/certification/[OpenID certified].
====
Follow the instructions on the https://developers.google.com/identity/protocols/OpenIDConnect[OpenID Connect] page, starting in the "`Setting up OAuth 2.0`" section.
@ -39,11 +45,17 @@ The redirect URI is the path in the application that the end-user's user-agent i
In the "`Set a redirect URI`" subsection, ensure that the *Authorized redirect URIs* field is set to `http://localhost:8080/login/oauth2/code/google`.
TIP: The default redirect URI template is `+{baseUrl}/login/oauth2/code/{registrationId}+`.
[TIP]
====
The default redirect URI template is `+{baseUrl}/login/oauth2/code/{registrationId}+`.
The `registrationId` is a unique identifier for the <<oauth2Client-client-registration,`ClientRegistration`>>.
====
IMPORTANT: If the OAuth Client runs behind a proxy server, you should check the <<http-proxy-server,Proxy Server Configuration>> to ensure the application is correctly configured.
[IMPORTANT]
====
If the OAuth Client runs behind a proxy server, you should check the <<http-proxy-server,Proxy Server Configuration>> to ensure the application is correctly configured.
Also, see the supported <<oauth2Client-auth-code-redirect-uri,`URI` template variables>> for `redirect-uri`.
====
[[oauth2login-sample-application-config]]
@ -144,7 +156,10 @@ The following table outlines the mapping of the Spring Boot 2.x OAuth Client pro
|`providerDetails.userInfoEndpoint.userNameAttributeName`
|===
TIP: You can initially configure a `ClientRegistration` by using discovery of an OpenID Connect Provider's https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Configuration endpoint] or an Authorization Server's https://tools.ietf.org/html/rfc8414#section-3[Metadata endpoint], by specifying the `spring.security.oauth2.client.provider._[providerId]_.issuer-uri` property.
[TIP]
====
You can initially configure a `ClientRegistration` by using discovery of an OpenID Connect Provider's https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Configuration endpoint] or an Authorization Server's https://tools.ietf.org/html/rfc8414#section-3[Metadata endpoint], by specifying the `spring.security.oauth2.client.provider._[providerId]_.issuer-uri` property.
====
[[oauth2login-common-oauth2-provider]]
@ -732,8 +747,11 @@ The following sections go into more detail on each of the configuration options
By default, the OAuth 2.0 Login Page is auto-generated by the `DefaultLoginPageGeneratingFilter`.
The default login page shows each configured OAuth Client with its `ClientRegistration.clientName` as a link, which is capable of initiating the Authorization Request (or OAuth 2.0 Login).
NOTE: For `DefaultLoginPageGeneratingFilter` to show links for configured OAuth Clients, the registered `ClientRegistrationRepository` needs to also implement `Iterable<ClientRegistration>`.
[NOTE]
====
For `DefaultLoginPageGeneratingFilter` to show links for configured OAuth Clients, the registered `ClientRegistrationRepository` needs to also implement `Iterable<ClientRegistration>`.
See `InMemoryClientRegistrationRepository` for reference.
====
The link's destination for each OAuth Client defaults to the following:
@ -805,7 +823,10 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
----
====
IMPORTANT: You need to provide a `@Controller` with a `@RequestMapping("/login/oauth2")` that is capable of rendering the custom login page.
[IMPORTANT]
====
You need to provide a `@Controller` with a `@RequestMapping("/login/oauth2")` that is capable of rendering the custom login page.
====
[TIP]
=====
@ -828,8 +849,11 @@ The following line shows an example:
The Redirection Endpoint is used by the Authorization Server for returning the Authorization Response (which contains the authorization credentials) to the client through the Resource Owner user-agent.
TIP: OAuth 2.0 Login leverages the Authorization Code Grant.
[TIP]
====
OAuth 2.0 Login leverages the Authorization Code Grant.
Therefore, the authorization credential is the authorization code.
====
The default Authorization Response `baseUri` (redirection endpoint) is `*/login/oauth2/code/**`, which is defined in `OAuth2LoginAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI`.
@ -1191,7 +1215,10 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
`DefaultOAuth2UserService` is an implementation of an `OAuth2UserService` that supports standard OAuth 2.0 Provider's.
NOTE: `OAuth2UserService` obtains the user attributes of the end-user (the resource owner) from the UserInfo Endpoint (by using the access token granted to the client during the authorization flow) and returns an `AuthenticatedPrincipal` in the form of an `OAuth2User`.
[NOTE]
====
`OAuth2UserService` obtains the user attributes of the end-user (the resource owner) from the UserInfo Endpoint (by using the access token granted to the client during the authorization flow) and returns an `AuthenticatedPrincipal` in the form of an `OAuth2User`.
====
`DefaultOAuth2UserService` uses a `RestOperations` instance when requesting the user attributes at the UserInfo Endpoint.
@ -1361,9 +1388,15 @@ fun idTokenDecoderFactory(): JwtDecoderFactory<ClientRegistration?> {
----
====
NOTE: For MAC-based algorithms (such as `HS256`, `HS384`, or `HS512`), the `client-secret` that corresponds to the `client-id` is used as the symmetric key for signature verification.
[NOTE]
====
For MAC-based algorithms (such as `HS256`, `HS384`, or `HS512`), the `client-secret` that corresponds to the `client-id` is used as the symmetric key for signature verification.
====
TIP: If more than one `ClientRegistration` is configured for OpenID Connect 1.0 Authentication, the JWS algorithm resolver may evaluate the provided `ClientRegistration` to determine which algorithm to return.
[TIP]
====
If more than one `ClientRegistration` is configured for OpenID Connect 1.0 Authentication, the JWS algorithm resolver may evaluate the provided `ClientRegistration` to determine which algorithm to return.
====
[[oauth2login-advanced-oidc-logout]]
@ -1433,9 +1466,11 @@ public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
----
====
[subs="none"]
NOTE: `OidcClientInitiatedLogoutSuccessHandler` supports the `{baseUrl}` placeholder.
[NOTE]
====
`OidcClientInitiatedLogoutSuccessHandler` supports the `+{baseUrl}+` placeholder.
If used, the application's base URL, such as `https://app.example.org`, replaces it at request time.
====
.Kotlin
====
@ -1470,6 +1505,8 @@ class OAuth2LoginSecurityConfig : WebSecurityConfigurerAdapter() {
----
====
[subs="none"]
NOTE: `OidcClientInitiatedLogoutSuccessHandler` supports the `{baseUrl}` placeholder.
[NOTE]
====
`OidcClientInitiatedLogoutSuccessHandler` supports the `+{baseUrl}+` placeholder.
If used, the application's base URL, such as `https://app.example.org`, replaces it at request time.
====

View File

@ -13,7 +13,10 @@ This authorization server can be consulted by resource servers to authorize requ
This section details how Spring Security provides support for OAuth 2.0 https://tools.ietf.org/html/rfc6750.html[Bearer Tokens].
NOTE: Working samples for both {gh-samples-url}/boot/oauth2resourceserver[JWTs] and {gh-samples-url}/boot/oauth2resourceserver-opaque[Opaque Tokens] are available in the {gh-samples-url}[Spring Security repository].
[NOTE]
====
Working samples for both {gh-samples-url}/boot/oauth2resourceserver[JWTs] and {gh-samples-url}/boot/oauth2resourceserver-opaque[Opaque Tokens] are available in the {gh-samples-url}[Spring Security repository].
====
Now we can consider how Bearer Token Authentication works within Spring Security.
First, we see that, as with <<servlet-authentication-basic,Basic Authentication>>, the https://tools.ietf.org/html/rfc7235#section-4.1[WWW-Authenticate] header is sent back to an unauthenticated client:
@ -29,7 +32,10 @@ image:{icondir}/number_3.png[] Since the user is not authenticated, <<servlet-ex
The configured <<servlet-authentication-authenticationentrypoint,`AuthenticationEntryPoint`>> is an instance of {security-api-url}org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationEntryPoint.html[`BearerTokenAuthenticationEntryPoint`], which sends a `WWW-Authenticate` header.
The `RequestCache` is typically a `NullRequestCache` that does not save the request, since the client is capable of replaying the requests it originally requested.
NOTE: The preceding figure builds off of our <<servlet-securityfilterchain,`SecurityFilterChain`>> diagram.
[NOTE]
====
The preceding figure builds off of our <<servlet-securityfilterchain,`SecurityFilterChain`>> diagram.
====
When a client receives the `WWW-Authenticate: Bearer` header, it knows it should retry with a bearer token.
The following image shows the flow for the bearer token being processed:
@ -53,7 +59,10 @@ image:{icondir}/number_4.png[] If authentication is successful, then __Success__
* The <<servlet-authentication-authentication>> is set on the <<servlet-authentication-securitycontextholder>>.
* The `BearerTokenAuthenticationFilter` invokes `FilterChain.doFilter(request,response)` to continue with the rest of the application logic.
NOTE: The preceding figure builds off our <<servlet-securityfilterchain,`SecurityFilterChain`>> diagram.
[NOTE]
====
The preceding figure builds off our <<servlet-securityfilterchain,`SecurityFilterChain`>> diagram.
====
[[oauth2resourceserver-jwt-minimaldependencies]]
=== Minimal Dependencies for JWT
@ -88,8 +97,11 @@ spring:
Resource Server uses this property to further self-configure, discover the authorization server's public keys, and, subsequently, validate incoming JWTs.
NOTE: To use the `issuer-uri` property, it must also be true that one of `https://idp.example.com/issuer/.well-known/openid-configuration`, `https://idp.example.com/.well-known/openid-configuration/issuer`, or `https://idp.example.com/.well-known/oauth-authorization-server/issuer` is a supported endpoint for the authorization server.
[NOTE]
====
To use the `issuer-uri` property, it must also be true that one of `https://idp.example.com/issuer/.well-known/openid-configuration`, `https://idp.example.com/.well-known/openid-configuration/issuer`, or `https://idp.example.com/.well-known/oauth-authorization-server/issuer` is a supported endpoint for the authorization server.
This endpoint is referred to as a https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Provider Configuration] endpoint or a https://tools.ietf.org/html/rfc8414#section-3[Authorization Server Metadata] endpoint.
====
==== Startup Expectations
@ -104,7 +116,10 @@ It achieves this through a deterministic startup process:
A consequence of this process is that the authorization server must be up and receiving requests for Resource Server to successfully start up.
NOTE: If the authorization server is down when Resource Server queries it (given appropriate timeouts), startup fails.
[NOTE]
====
If the authorization server is down when Resource Server queries it (given appropriate timeouts), startup fails.
====
==== Runtime Expectations
@ -126,7 +141,10 @@ Given a well-formed JWT, Resource Server:
. Validates the JWT's `exp` and `nbf` timestamps and the JWT's `iss` claim.
. Maps each scope to an authority with the prefix `SCOPE_`.
NOTE: As the authorization server makes available new keys, Spring Security automatically rotates the keys used to validate JWTs.
[NOTE]
====
As the authorization server makes available new keys, Spring Security automatically rotates the keys used to validate JWTs.
====
The resulting `Authentication#getPrincipal`, by default, is a Spring Security `Jwt` object, and `Authentication#getName` maps to the JWT's `sub` property, if one is present.
@ -180,12 +198,19 @@ spring:
----
====
NOTE: The JWK Set URI is not standardized, but you can typically find it in the authorization server's documentation.
[NOTE]
====
The JWK Set URI is not standardized, but you can typically find it in the authorization server's documentation.
====
Consequently, Resource Server does not ping the authorization server at startup.
We still specify the `issuer-uri` so that Resource Server still validates the `iss` claim on incoming JWTs.
NOTE: You can also supply this property directly on the <<oauth2resourceserver-jwt-jwkseturi-dsl,DSL>>.
[NOTE]
====
You can also supply this property directly on the <<oauth2resourceserver-jwt-jwkseturi-dsl,DSL>>.
====
[[oauth2resourceserver-jwt-sansboot]]
=== Overriding or Replacing Boot Auto Configuration
@ -300,7 +325,10 @@ fun jwtDecoder(): JwtDecoder {
----
====
NOTE: Calling `{security-api-url}org/springframework/security/oauth2/jwt/JwtDecoders.html#fromIssuerLocation-java.lang.String-[JwtDecoders#fromIssuerLocation]` invokes the Provider Configuration or Authorization Server Metadata endpoint, to derive the JWK Set URI.
[NOTE]
====
Calling `{security-api-url}org/springframework/security/oauth2/jwt/JwtDecoders.html#fromIssuerLocation-java.lang.String-[JwtDecoders#fromIssuerLocation]` invokes the Provider Configuration or Authorization Server Metadata endpoint, to derive the JWK Set URI.
====
If the application does not expose a `JwtDecoder` bean, Spring Boot exposes the earlier default one.
@ -1074,6 +1102,8 @@ fun jwtDecoder(): JwtDecoder {
[NOTE]
By default, Resource Server configures a clock skew of 60 seconds.
====
[[oauth2resourceserver-jwt-validation-custom]]
==== Configuring a Custom Validator
@ -1426,10 +1456,17 @@ fun jwtDecoder(cacheManager: CacheManager): JwtDecoder {
When given a `Cache`, Resource Server uses the JWK Set URI as the key and the JWK Set JSON as the value.
NOTE: Spring is not a cache provider, so you need to make sure to include the appropriate dependencies, such as `spring-boot-starter-cache` and your favorite caching provider.
[NOTE]
====
Spring is not a cache provider, so you need to make sure to include the appropriate dependencies, such as `spring-boot-starter-cache` and your favorite caching provider.
====
NOTE: Whether it is socket or cache timeouts, you may instead want to work with Nimbus directly.
[NOTE]
====
Whether it is socket or cache timeouts, you may instead want to work with Nimbus directly.
To do so, remember that `NimbusJwtDecoder` ships with a constructor that takes Nimbus's `JWTProcessor`.
====
[[oauth2resourceserver-opaque-minimaldependencies]]
=== Minimal Dependencies for Introspection
@ -1471,8 +1508,12 @@ Where `https://idp.example.com/introspect` is the introspection endpoint hosted
Resource Server uses these properties to further self-configure and subsequently validate incoming JWTs.
NOTE: When using introspection, the authorization server's word is law.
[NOTE]
====
When using introspection, the authorization server's word is law.
If the authorization server responsed that the token is valid, it is.
====
==== Startup Expectations
@ -2377,7 +2418,10 @@ fun tokenAuthenticationManagerResolver(): AuthenticationManagerResolver<HttpServ
----
====
NOTE: The implementation of `useJwt(HttpServletRequest)` likely depends on custom request material, such as the path.
[NOTE]
====
The implementation of `useJwt(HttpServletRequest)` likely depends on custom request material, such as the path.
====
Then you can specify this `AuthenticationManagerResolver` in the DSL:
@ -2546,8 +2590,12 @@ http {
In this case, you construct `JwtIssuerAuthenticationManagerResolver` with a strategy for obtaining the `AuthenticationManager`, given the issuer.
This approach lets you add and remove elements from the repository (shown as a `Map` in the snippet) at runtime.
NOTE: It would be unsafe to take any issuer and construct an `AuthenticationManager` from it.
[NOTE]
====
It would be unsafe to take any issuer and construct an `AuthenticationManager` from it.
The issuer should be one that the code can verify from a trusted source, such as a list of allowed issuers.
====
===== Parsing the Claim Only Once
@ -2644,8 +2692,11 @@ class TenantJWSKeySelector(tenants: TenantRepository) : JWTClaimSetAwareJWSKeySe
The preceding key selector is a composition of many key selectors.
It chooses which key selector to use based on the `iss` claim in the JWT.
NOTE: To use this approach, make sure that the authorization server is configured to include the claim set as part of the token's signature.
[NOTE]
====
To use this approach, make sure that the authorization server is configured to include the claim set as part of the token's signature.
Without this, you have no guarantee that the issuer has not been altered by a bad actor.
====
Next, we can construct a `JWTProcessor`:
@ -2956,8 +3007,11 @@ this.rest.get()
In this case, the filter falls back and forwards the request onto the rest of the web filter chain.
NOTE: Unlike the {security-api-url}org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.html[OAuth 2.0 Client filter function], this filter function makes no attempt to renew the token, should it be expired.
[NOTE]
====
Unlike the {security-api-url}org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.html[OAuth 2.0 Client filter function], this filter function makes no attempt to renew the token, should it be expired.
To obtain this level of support, use the OAuth 2.0 Client filter.
====
==== `RestTemplate` support
@ -3014,8 +3068,11 @@ fun rest(): RestTemplate {
====
NOTE: Unlike the {security-api-url}org/springframework/security/oauth2/client/OAuth2AuthorizedClientManager.html[OAuth 2.0 Authorized Client Manager], this filter interceptor makes no attempt to renew the token, should it be expired.
[NOTE]
====
Unlike the {security-api-url}org/springframework/security/oauth2/client/OAuth2AuthorizedClientManager.html[OAuth 2.0 Authorized Client Manager], this filter interceptor makes no attempt to renew the token, should it be expired.
To obtain this level of support, create an interceptor by using the <<oauth2client,OAuth 2.0 Authorized Client Manager>>.
====
[[oauth2resourceserver-bearertoken-failure]]
=== Bearer Token Failure

View File

@ -5,15 +5,21 @@
The SAML 2.0 Login feature provides an application with the ability to act as a SAML 2.0 relying party, having users https://wiki.shibboleth.net/confluence/display/CONCEPT/FlowsAndConfig[log in] to the application by using their existing account at a SAML 2.0 Asserting Party (Okta, ADFS, and others).
NOTE: SAML 2.0 Login is implemented by using the *Web Browser SSO Profile*, as specified in
[NOTE]
====
SAML 2.0 Login is implemented by using the *Web Browser SSO Profile*, as specified in
https://www.oasis-open.org/committees/download.php/35389/sstc-saml-profiles-errata-2.0-wd-06-diff.pdf#page=15[SAML 2 Profiles].
====
[[servlet-saml2login-spring-security-history]]
Since 2009, support for relying parties has existed as an https://github.com/spring-projects/spring-security-saml/tree/1e013b07a7772defd6a26fcfae187c9bf661ee8f#spring-saml[extension project].
In 2019, the process began to port that into https://github.com/spring-projects/spring-security[Spring Security] proper.
This process is similar to the one started in 2017 for <<oauth2,Spring Security's OAuth 2.0 support>>.
NOTE: A working sample for {gh-samples-url}/boot/saml2login[SAML 2.0 Login] is available in the {gh-samples-url}[Spring Security repository].
[NOTE]
====
A working sample for {gh-samples-url}/boot/saml2login[SAML 2.0 Login] is available in the {gh-samples-url}[Spring Security repository].
====
We start by examining how SAML 2.0 Relying Party Authentication works within Spring Security.
First, we see that, like <<oauth2login, OAuth 2.0 Login>>, Spring Security takes the user to a third party for performing authentication.
@ -22,7 +28,10 @@ It does this through a series of redirects:
.Redirecting to Asserting Party Authentication
image::{figures}/saml2webssoauthenticationrequestfilter.png[]
NOTE: The preceding figure above builds off our <<servlet-securityfilterchain,`SecurityFilterChain`>> and <<servlet-authentication-abstractprocessingfilter, `AbstractAuthenticationProcessingFilter`>> diagrams.
[NOTE]
====
The preceding figure above builds off our <<servlet-securityfilterchain,`SecurityFilterChain`>> and <<servlet-authentication-abstractprocessingfilter, `AbstractAuthenticationProcessingFilter`>> diagrams.
====
image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the `/private` resource, for which it is not authorized.
@ -46,7 +55,10 @@ The following image shows how Spring Security authenticates a `<saml2:Response>`
.Authenticating a `<saml2:Response>`
image::{figures}/saml2webssoauthenticationfilter.png[]
NOTE: The figure builds off our <<servlet-securityfilterchain,`SecurityFilterChain`>> diagram.
[NOTE]
====
The figure builds off our <<servlet-securityfilterchain,`SecurityFilterChain`>> diagram.
====
image:{icondir}/number_1.png[] When the browser submits a `<saml2:Response>` to the application, it <<servlet-saml2login-authenticate-responses, delegates to `Saml2WebSsoAuthenticationFilter`>>.
This filter calls its configured `AuthenticationConverter` to create a `Saml2AuthenticationToken` by extracting the response from the `HttpServletRequest`.
@ -110,8 +122,11 @@ where:
* `classpath:idp.crt` is the location on the classpath for the identity provider's certificate for verifying SAML responses.
* `https://idp.example.com/issuer/sso` is the endpoint where the identity provider is expecting `AuthnRequest` instances.
NOTE: Identity Provider and Asserting Party are synonymous, as are Service Provider and Relying Party.
[NOTE]
====
Identity Provider and Asserting Party are synonymous, as are Service Provider and Relying Party.
These are frequently abbreviated as AP and RP, respectively.
====
==== Runtime Expectations
@ -158,7 +173,10 @@ For example, once your application receives a `SAMLResponse` and delegates to `S
.Authenticating an OpenSAML `Response`
image:{figures}/opensamlauthenticationprovider.png[]
NOTE: This figure builds off of the <<servlet-saml2login-authentication-saml2webssoauthenticationfilter,`Saml2WebSsoAuthenticationFilter` diagram>>.
[NOTE]
====
This figure builds off of the <<servlet-saml2login-authentication-saml2webssoauthenticationfilter,`Saml2WebSsoAuthenticationFilter` diagram>>.
====
image:{icondir}/number_1.png[] The `Saml2WebSsoAuthenticationFilter` formulates the `Saml2AuthenticationToken` and invokes the <<servlet-authentication-providermanager,`AuthenticationManager`>>.
@ -373,7 +391,10 @@ public RelyingPartyRegistrationRepository relyingPartyRegistrations() throws Exc
----
====
NOTE: `X509Support` is an OpenSAML class, used in the preceding snippet for brevity.
[NOTE]
====
`X509Support` is an OpenSAML class, used in the preceding snippet for brevity.
====
[[servlet-saml2login-relyingpartyregistrationrepository-dsl]]
Alternatively, you can directly wire up the repository by using the DSL, which also overrides the auto-configured `WebSecurityConfigurerAdapter`:
@ -418,8 +439,10 @@ class MyCustomSecurityConfiguration : WebSecurityConfigurerAdapter() {
----
====
NOTE: A relying party can be multi-tenant by registering more than one relying party in the `RelyingPartyRegistrationRepository`.
[NOTE]
====
A relying party can be multi-tenant by registering more than one relying party in the `RelyingPartyRegistrationRepository`.
====
[[servlet-saml2login-relyingpartyregistration]]
=== RelyingPartyRegistration
A {security-api-url}org/springframework/security/saml2/provider/service/registration/RelyingPartyRegistration.html[`RelyingPartyRegistration`]
@ -458,10 +481,16 @@ RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistration.wit
----
====
TIP: The top-level metadata methods are details about the relying party.
[TIP]
====
The top-level metadata methods are details about the relying party.
The methods inside `assertingPartyDetails` are details about the asserting party.
====
NOTE: The location where a relying party is expecting SAML Responses is the Assertion Consumer Service Location.
[NOTE]
====
The location where a relying party is expecting SAML Responses is the Assertion Consumer Service Location.
====
The default for the relying party's `entityId` is `+{baseUrl}/saml2/service-provider-metadata/{registrationId}+`.
You need this value when you configure the asserting party to know about your relying party.
@ -543,7 +572,11 @@ try (InputStream is = resource.getInputStream()) {
----
====
TIP: When you specify the locations of these files as the appropriate Spring Boot properties, Spring Boot performs these conversions for you.
[TIP]
====
When you specify the locations of these files as the appropriate Spring Boot properties, Spring Boot performs these conversions for you.
====
[[servlet-saml2login-rpr-relyingpartyregistrationresolver]]
==== Resolving the Relying Party from the Request
@ -576,7 +609,10 @@ public class SingleRelyingPartyRegistrationResolver
Then you can provide this resolver to the appropriate filters that <<servlet-saml2login-sp-initiated-factory, produce `<saml2:AuthnRequest>` instances>>, <<servlet-saml2login-authenticate-responses, authenticate `<saml2:Response>` instances>>, and <<servlet-saml2login-metadata, produce `<saml2:SPSSODescriptor>` metadata>>.
NOTE: Remember that, if you have any placeholders in your `RelyingPartyRegistration`, your resolver implementation should resolve them.
[NOTE]
====
Remember that, if you have any placeholders in your `RelyingPartyRegistration`, your resolver implementation should resolve them.
====
[[servlet-saml2login-rpr-duplicated]]
==== Duplicated Relying Party Configurations
@ -716,9 +752,12 @@ RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistrations.fr
----
====
NOTE: The preceding snippet uses the OpenSAML `SignatureConstants` class to supply the algorithm name.
[NOTE]
====
The preceding snippet uses the OpenSAML `SignatureConstants` class to supply the algorithm name.
However, that is only for convenience.
Since the datatype is `String`, you can supply the name of the algorithm directly.
====
[[servlet-saml2login-sp-initiated-factory-binding]]
Some asserting parties require that the `<saml2:AuthnRequest>` be POSTed.
@ -897,8 +936,11 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
<3> Return a custom authentication that includes the user details
====
NOTE: You need not call the default authentication converter of `OpenSamlAuthenticationProvider`.
[NOTE]
====
You need not call the default authentication converter of `OpenSamlAuthenticationProvider`.
It returns a `Saml2AuthenticatedPrincipal` that contains the attributes it extracted from `AttributeStatement` instances as well as the single `ROLE_USER` authority.
====
[[servlet-saml2login-opensamlauthenticationprovider-additionalvalidation]]
==== Performing Additional Validation
@ -938,8 +980,11 @@ provider.setAssertionValidator(assertionToken -> {
----
====
NOTE: While recommended, you need not call the default assertion validator of `OpenSamlAuthenticationProvider`.
[NOTE]
====
While recommended, you need not call the default assertion validator of `OpenSamlAuthenticationProvider`.
For example, you could skip it if you do not need to check the `<AudienceRestriction>` or the `<SubjectConfirmation>` because you are doing those yourself.
====
[[servlet-saml2login-opensamlauthenticationprovider-decryption]]
==== Customizing Decryption
@ -971,9 +1016,12 @@ provider.setAssertionElementsDecrypter((assertionToken) -> decryptionService.dec
----
====
NOTE: We have two separate decrypters, because assertions can be signed separately from responses.
[NOTE]
====
We have two separate decrypters, because assertions can be signed separately from responses.
Trying to decrypt a signed assertion's elements before signature verification may invalidate the signature.
If your asserting party signs only the response, it is safe to decrypt all elements by using only the response decrypter.
====
[[servlet-saml2login-authenticationmanager-custom]]
==== Using a Custom Authentication Manager
@ -1027,8 +1075,12 @@ public class MainController {
----
====
TIP: Because the SAML 2.0 specification lets each attribute have multiple values, you can either call `getAttribute` to get the list of attributes or `getFirstAttribute` to get the first in the list.
[TIP]
====
Because the SAML 2.0 specification lets each attribute have multiple values, you can either call `getAttribute` to get the list of attributes or `getFirstAttribute` to get the first in the list.
`getFirstAttribute` is handy when you know that there is only one value.
====
[[servlet-saml2login-metadata]]
=== Producing `<saml2:SPSSODescriptor>` Metadata

View File

@ -3,7 +3,10 @@
This section describes the testing support provided by Spring Security.
NOTE: To use the Spring Security test support, you must include `spring-security-test-{spring-security-version}.jar` as a dependency of your project.
[NOTE]
====
To use the Spring Security test support, you must include `spring-security-test-{spring-security-version}.jar` as a dependency of your project.
====
include::method.adoc[]

View File

@ -47,11 +47,14 @@ public class WithMockUserTests {
<2> `@ContextConfiguration` instructs the Spring test configuration to use to create the `ApplicationContext`. Since no configuration is specified, the default configuration locations are tried. This is no different than using the existing Spring test support. For additional information, see the https://docs.spring.io/spring-framework/docs/4.0.x/spring-framework-reference/htmlsingle/#testcontext-ctx-management[Spring Reference].
====
NOTE: Spring Security hooks into Spring Test support through the `WithSecurityContextTestExecutionListener`, which ensures that our tests are run with the correct user.
[NOTE]
====
Spring Security hooks into Spring Test support through the `WithSecurityContextTestExecutionListener`, which ensures that our tests are run with the correct user.
It does this by populating the `SecurityContextHolder` prior to running our tests.
If you use reactive method security, you also need `ReactorContextTestExecutionListener`, which populates `ReactiveSecurityContextHolder`.
After the test is done, it clears out the `SecurityContextHolder`.
If you need only Spring Security related support, you can replace `@ContextConfiguration` with `@SecurityTestExecutionListeners`.
====
Remember, we added the `@PreAuthorize` annotation to our `HelloMessageService`, so it requires an authenticated user to invoke it.
If we run the tests, we expect the following test will pass:

View File

@ -6,7 +6,10 @@ Spring Security provides comprehensive integration with https://docs.spring.io/s
[[test-mockmvc-setup]]
=== Setting Up MockMvc and Spring Security
NOTE: Spring Security's testing support requires spring-test-4.1.3.RELEASE or greater.
[NOTE]
====
Spring Security's testing support requires spring-test-4.1.3.RELEASE or greater.
====
To use Spring Security with Spring MVC Test, add the Spring Security `FilterChainProxy` as a `Filter`.
You also need to add Spring Security's `TestSecurityContextHolderPostProcessor` to support <<running-as-a-user-in-spring-mvc-test-with-annotations,running as a user in Spring MVC test with annotations>>.