diff --git a/docs/manual/src/docs/asciidoc/_includes/servlet/saml2/saml2-login.adoc b/docs/manual/src/docs/asciidoc/_includes/servlet/saml2/saml2-login.adoc index 7881ae0ca8..7b7a32f554 100644 --- a/docs/manual/src/docs/asciidoc/_includes/servlet/saml2/saml2-login.adoc +++ b/docs/manual/src/docs/asciidoc/_includes/servlet/saml2/saml2-login.adoc @@ -1,3 +1,4 @@ + [[servlet-saml2login]] == SAML 2.0 Login :figures: images/servlet/saml2 @@ -165,24 +166,27 @@ image:{icondir}/number_2.png[] The <>. If any decryptions fail, authentication fails. +image:{icondir}/number_5.png[] Next, the provider validates the response's `Issuer` and `Destination` values. +If they don't match what's in the `RelyingPartyRegistration`, authentication fails. + image:{icondir}/number_6.png[] After that, the provider verifies the signature of each `Assertion`. If any signature is invalid, authentication fails. Also, if neither the response nor the assertions have signatures, authentication fails. -It is required that either the response or the assertions have signatures. +Either the response or all the assertions must have signatures. -image:{icondir}/number_7.png[] Then, the provider validates each assertion's `ExpiresAt` and `NotBefore` timestamps, the `` and any `` conditions. +image:{icondir}/number_7.png[] Then, the provider <>. +If any decryptions fail, authentication fails. + +image:{icondir}/number_8.png[] Next, the provider validates each assertion's `ExpiresAt` and `NotBefore` timestamps, the `` and any `` conditions. If any validations fail, authentication fails. -image:{icondir}/number_8.png[] Following that, the provider takes the first assertion's `AttributeStatement` and maps it to a `Map>`. +image:{icondir}/number_9.png[] Following that, the provider takes the first assertion's `AttributeStatement` and maps it to a `Map>`. It also grants the `ROLE_USER` granted authority. -image:{icondir}/number_9.png[] And finally, it takes the `NameID` from the first assertion, the `Map` of attributes, and the `GrantedAuthority` and constructs a `Saml2AuthenticatedPrincipal`. +image:{icondir}/number_10.png[] And finally, it takes the `NameID` from the first assertion, the `Map` of attributes, and the `GrantedAuthority` and constructs a `Saml2AuthenticatedPrincipal`. Then, it places that principal and the authorities into a `Saml2Authentication`. The resulting `Authentication#getPrincipal` is a Spring Security `Saml2AuthenticatedPrincipal` object, and `Authentication#getName` maps to the first assertion's `NameID` element. @@ -769,6 +773,7 @@ You can configure this in a number of ways including: 1. Setting a clock skew to timestamp validation 2. Mapping the response to a list of `GrantedAuthority` instances 3. Customizing the strategy for validating assertions +4. Customizing the strategy for decrypting response and assertion elements To configure these, you'll use the `saml2Login#authenticationManager` method in the DSL. @@ -890,6 +895,36 @@ provider.setAssertionValidator(assertionToken -> { While recommended, it's not necessary to call `OpenSamlAuthenticationProvider` 's default assertion validator. A circumstance where you would skip it would be if you don't need it to check the `` or the `` since you are doing those yourself. +[[servlet-saml2login-opensamlauthenticationprovider-decryption]] +==== Customizing Decryption + +Spring Security decrypts ``, ``, and `` elements automatically by using the decryption <> registered in the <>. + +`OpenSamlAuthenticationProvider` exposes <>. +The response decrypter is for decrypting encrypted elements of the ``, like ``. +The assertion decrypter is for decrypting encrypted elements of the ``, like `` and ``. + +You can replace `OpenSamlAuthenticationProvider`'s default decryption strategy with your own. +For example, if you have a separate service that decrypts the assertions in a ``, you can use it instead like so: + +[source,java] +---- +MyDecryptionService decryptionService = ...; +OpenSamlAuthenticationProvider provider = new OpenSamlAuthenticationProvider(); +provider.setResponseElementsDecrypter((responseToken) -> decryptionService.decrypt(responseToken.getResponse())); +---- + +If you are also decrypting individual elements in a ``, you can customize the assertion decrypter, too: + +[source,java] +---- +provider.setAssertionElementsDecrypter((assertionToken) -> decryptionService.decrypt(assertionToken.getAssertion())); +---- + +NOTE: There are two separate decrypters since 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 the response only, then it's safe to decrypt all elements using only the response decrypter. + [[servlet-saml2login-authenticationmanager-custom]] ==== Using a Custom Authentication Manager diff --git a/docs/manual/src/docs/asciidoc/images/servlet/saml2/opensamlauthenticationprovider.odg b/docs/manual/src/docs/asciidoc/images/servlet/saml2/opensamlauthenticationprovider.odg index bb3a44aa64..6a363c132c 100644 Binary files a/docs/manual/src/docs/asciidoc/images/servlet/saml2/opensamlauthenticationprovider.odg and b/docs/manual/src/docs/asciidoc/images/servlet/saml2/opensamlauthenticationprovider.odg differ diff --git a/docs/manual/src/docs/asciidoc/images/servlet/saml2/opensamlauthenticationprovider.png b/docs/manual/src/docs/asciidoc/images/servlet/saml2/opensamlauthenticationprovider.png index aff4d2f823..d4a961dbc6 100644 Binary files a/docs/manual/src/docs/asciidoc/images/servlet/saml2/opensamlauthenticationprovider.png and b/docs/manual/src/docs/asciidoc/images/servlet/saml2/opensamlauthenticationprovider.png differ