Skip to content

Commit

Permalink
Revisit Request and Method Security Docs
Browse files Browse the repository at this point in the history
Issue gh-13088
  • Loading branch information
jzheaux committed May 1, 2023
1 parent 42cd19f commit e5fcf1e
Show file tree
Hide file tree
Showing 15 changed files with 1,794 additions and 1,055 deletions.
Binary file not shown.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions docs/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@
** xref:servlet/authorization/index.adoc[Authorization]
*** xref:servlet/authorization/architecture.adoc[Authorization Architecture]
*** xref:servlet/authorization/authorize-http-requests.adoc[Authorize HTTP Requests]
*** xref:servlet/authorization/authorize-requests.adoc[Authorize HTTP Requests with FilterSecurityInterceptor]
*** xref:servlet/authorization/expression-based.adoc[Expression-Based Access Control]
*** xref:servlet/authorization/secure-objects.adoc[Secure Object Implementations]
*** xref:servlet/authorization/method-security.adoc[Method Security]
*** xref:servlet/authorization/acls.adoc[Domain Object Security ACLs]
*** xref:servlet/authorization/events.adoc[Authorization Events]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ There are no further migrations steps for Java or Kotlin for this feature.
== Use `AuthorizationManager` for Request Security

In 6.0, `<http>` defaults `once-per-request` to `false`, `filter-all-dispatcher-types` to `true`, and `use-authorization-manager` to `true`.
Also, xref:servlet/authorization/authorize-requests.adoc#filtersecurityinterceptor-every-request[`authorizeRequests#filterSecurityInterceptorOncePerRequest`] defaults to `false` and xref:servlet/authorization/authorize-http-requests.adoc[`authorizeHttpRequests#filterAllDispatcherTypes`] defaults to `true`.
Also, {security-api-url}org/springframework/security/config/annotation/web/configurers/AbstractInterceptUrlConfigurer.AbstractInterceptUrlRegistry.html#filterSecurityInterceptorOncePerRequest(boolean)[`authorizeRequests#filterSecurityInterceptorOncePerRequest`] defaults to `false` and xref:servlet/authorization/authorize-http-requests.adoc[`authorizeHttpRequests#filterAllDispatcherTypes`] defaults to `true`.
So, to complete migration, any defaults values can be removed.

For example, if you opted in to the 6.0 default for `filter-all-dispatcher-types` or `authorizeHttpRequests#filterAllDispatcherTypes` like so:
Expand Down
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/servlet/architecture.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ The following is a comprehensive list of Spring Security Filter ordering:
* `OAuth2AuthorizationCodeGrantFilter`
* `SessionManagementFilter`
* <<servlet-exceptiontranslationfilter,`ExceptionTranslationFilter`>>
* xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`]
* xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`]
* `SwitchUserFilter`

[[servlet-exceptiontranslationfilter]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The preceding figure builds off our xref:servlet/architecture.adoc#servlet-secur

image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the resource `/private` for which it is not authorized.

image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`.
image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`.

image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates __Start Authentication__.
The configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`] is an instance of {security-api-url}org/springframework/security/web/authentication/www/BasicAuthenticationEntryPoint.html[`BasicAuthenticationEntryPoint`], which sends a WWW-Authenticate header.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The preceding figure builds off our xref:servlet/architecture.adoc#servlet-secur

image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the resource (`/private`) for which it is not authorized.

image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`.
image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`.

image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates __Start Authentication__ and sends a redirect to the login page with the configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`].
In most cases, the `AuthenticationEntryPoint` is an instance of {security-api-url}org/springframework/security/web/authentication/LoginUrlAuthenticationEntryPoint.html[`LoginUrlAuthenticationEntryPoint`].
Expand Down
68 changes: 59 additions & 9 deletions docs/modules/ROOT/pages/servlet/authorization/architecture.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,76 @@ String getAuthority();
----
====

This method lets an
`AccessDecisionManager` instance to obtain a precise `String` representation of the `GrantedAuthority`.
By returning a representation as a `String`, a `GrantedAuthority` can be easily "`read`" by most `AccessDecisionManager` implementations.
If a `GrantedAuthority` cannot be precisely represented as a `String`, the `GrantedAuthority` is considered "`complex`" and `getAuthority()` must return `null`.
This method is used by an
`AuthorizationManager` instance to obtain a precise `String` representation of the `GrantedAuthority`.
By returning a representation as a `String`, a `GrantedAuthority` can be easily "read" by most `AuthorizationManager` implementations.
If a `GrantedAuthority` cannot be precisely represented as a `String`, the `GrantedAuthority` is considered "complex" and `getAuthority()` must return `null`.

An example of a "`complex`" `GrantedAuthority` would be an implementation that stores a list of operations and authority thresholds that apply to different customer account numbers.
An example of a complex `GrantedAuthority` would be an implementation that stores a list of operations and authority thresholds that apply to different customer account numbers.
Representing this complex `GrantedAuthority` as a `String` would be quite difficult. As a result, the `getAuthority()` method should return `null`.
This indicates to any `AccessDecisionManager` that it needs to support the specific `GrantedAuthority` implementation to understand its contents.
This indicates to any `AuthorizationManager` that it needs to support the specific `GrantedAuthority` implementation to understand its contents.

Spring Security includes one concrete `GrantedAuthority` implementation: `SimpleGrantedAuthority`.
This implementation lets any user-specified `String` be converted into a `GrantedAuthority`.
All `AuthenticationProvider` instances included with the security architecture use `SimpleGrantedAuthority` to populate the `Authentication` object.

[[jc-method-security-custom-granted-authority-defaults]]
By default, role-based authorization rules include `ROLE_` as a prefix.
This means that if there is an authorization rule that requires a security context to have a role of "USER", Spring Security will by default look for a `GrantedAuthority#getAuthority` that returns "ROLE_USER".

You can customize this with `GrantedAuthorityDefaults`.
`GrantedAuthorityDefaults` exists to allow customizing the prefix to use for role-based authorization rules.

You can configure the authorization rules to use a different prefix by exposing a `GrantedAuthorityDefaults` bean, like so:

.Custom MethodSecurityExpressionHandler
====
.Java
[source,java,role="primary"]
----
@Bean
static GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults("MYPREFIX_");
}
----
.Kotlin
[source,kotlin,role="secondary"]
----
companion object {
@Bean
fun grantedAuthorityDefaults() : GrantedAuthorityDefaults {
return GrantedAuthorityDefaults("MYPREFIX_");
}
}
----
.Xml
[source,xml,role="secondary"]
----
<bean id="grantedAuthorityDefaults" class="org.springframework.security.config.core.GrantedAuthorityDefaults">
<constructor-arg value="MYPREFIX_"/>
</bean>
----
====

[TIP]
====
You expose `GrantedAuthorityDefaults` using a `static` method to ensure that Spring publishes it before it initializes Spring Security's method security `@Configuration` classes
====

[[authz-pre-invocation]]
== Pre-Invocation Handling
== Invocation Handling
Spring Security provides interceptors that control access to secure objects, such as method invocations or web requests.
A pre-invocation decision on whether the invocation is allowed to proceed is made by the `AccessDecisionManager`.
A pre-invocation decision on whether the invocation is allowed to proceed is made by `AuthorizationManager` instances.
Also post-invocation decisions on whether a given value may be returned is made by `AuthorizationManager` instances.

=== The AuthorizationManager
`AuthorizationManager` supersedes both <<authz-legacy-note,`AccessDecisionManager` and `AccessDecisionVoter`>>.

Applications that customize an `AccessDecisionManager` or `AccessDecisionVoter` are encouraged to <<authz-voter-adaptation,change to using `AuthorizationManager`>>.

``AuthorizationManager``s are called by the xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] and are responsible for making final access control decisions.
``AuthorizationManager``s are called by Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[request-based], xref:servlet/authorization/method-security.adoc[method-based], and xref:servlet/integrations/websocket.adoc[message-based] authorization components and are responsible for making final access control decisions.
The `AuthorizationManager` interface contains two methods:

====
Expand Down Expand Up @@ -97,6 +143,10 @@ Another manager is the `AuthenticatedAuthorizationManager`.
It can be used to differentiate between anonymous, fully-authenticated and remember-me authenticated users.
Many sites allow certain limited access under remember-me authentication, but require a user to confirm their identity by logging in for full access.

[[authz-authorization-managers]]
==== AuthorizationManagers
There are also helpful static factories in `AuthenticationManagers` for composing individual ``AuthenticationManager``s into more sophisticated expressions.

[[authz-custom-authorization-manager]]
==== Custom Authorization Managers
Obviously, you can also implement a custom `AuthorizationManager` and you can put just about any access-control logic you want in it.
Expand Down

0 comments on commit e5fcf1e

Please sign in to comment.