Skip to content

Commit b87d63c

Browse files
committed
Document spring-security-access
Closes gh-17847
1 parent 505631d commit b87d63c

File tree

9 files changed

+134
-18
lines changed

9 files changed

+134
-18
lines changed

docs/modules/ROOT/nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* xref:migration-8/index.adoc[Preparing for 8.0]
66
* xref:migration/index.adoc[Migrating to 7]
77
** xref:migration/servlet/index.adoc[Servlet]
8+
*** xref:migration/servlet/authorization.adoc[Authorization]
89
*** xref:migration/servlet/oauth2.adoc[OAuth 2.0]
910
*** xref:migration/servlet/saml2.adoc[SAML 2.0]
1011
** xref:migration/reactive.adoc[Reactive]
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
= Authorization Changes
2+
3+
== If Using Access API, Add `spring-security-access`
4+
5+
Spring Security 7 moves `AccessDecisionManager`, `AccessDecisionVoter`, and the related Access API to a legacy module, `spring-security-access`.
6+
The Access API is deprecated in favor of the Authorization API as of Spring Security 5.
7+
8+
You can add the dependency like other Spring Security dependencies like so:
9+
10+
[tabs]
11+
======
12+
Maven::
13+
+
14+
[source,xml,role="primary"]
15+
----
16+
<dependency>
17+
<groupId>org.springframework.security</groupId>
18+
<artifactId>spring-security-access</artifactId>
19+
</dependency>
20+
----
21+
22+
Gradle::
23+
+
24+
[source,groovy,role="primary"]
25+
----
26+
implementation('org.springframework.security:spring-security-access')
27+
----
28+
======
29+

docs/modules/ROOT/pages/servlet/appendix/faq.adoc

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,13 @@ If you use hashed passwords, make sure the value stored in your database is _exa
138138
=== My application goes into an "`endless loop`" when I try to log in. What is going on?
139139

140140
A common user problem with infinite loop and redirecting to the login page is caused by accidentally configuring the login page as a "`secured`" resource.
141-
Make sure your configuration allows anonymous access to the login page, either by excluding it from the security filter chain or marking it as requiring `ROLE_ANONYMOUS`.
142-
143-
If your `AccessDecisionManager` includes an `AuthenticatedVoter`, you can use the `IS_AUTHENTICATED_ANONYMOUSLY` attribute. This is automatically available if you use the standard namespace configuration setup.
144-
145-
From Spring Security 2.0.1 onwards, when you use namespace-based configuration, a check is made on loading the application context and a warning message logged if your login page appears to be protected.
141+
Make sure your configuration allows anonymous access to the login page.
142+
You can do so with the xref:servlet/authorization/authorize-http-requests.adoc[`authorizeHttpRequests`] DSL.
146143

144+
[TIP]
145+
====
146+
When you use namespace- or DSL-based configuration, a check is made on loading the application context and a warning message logged if your login page appears to be protected.
147+
====
147148

148149
[[appendix-faq-anon-access-denied]]
149150
=== I get an exception with the message "Access is denied (user is anonymous);". What's wrong?
@@ -382,16 +383,16 @@ You should probably read the chapters on namespace parsing in the standard Sprin
382383

383384

384385
[[appendix-faq-role-prefix]]
385-
=== What does "ROLE_" mean and why do I need it on my role names?
386+
=== What does "ROLE_" mean?
386387

387-
Spring Security has a voter-based architecture, which means that an access decision is made by a series of `AccessDecisionVoter` instances.
388-
The voters act on the "`configuration attributes`", which are specified for a secured resource (such as a method invocation). With this approach, not all attributes may be relevant to all voters, and a voter needs to know when it should ignore an attribute (abstain) and when it should vote to grant or deny access based on the attribute value.
389-
The most common voter is the `RoleVoter`, which, by default, votes whenever it finds an attribute with the `ROLE_` prefix.
390-
It makes a simple comparison of the attribute (such as `ROLE_USER`) with the names of the authorities that the current user has been assigned.
391-
If it finds a match (they have an authority called `ROLE_USER`), it votes to grant access. Otherwise, it votes to deny access.
388+
`ROLE_` is a way to identify the nature of a given authority.
389+
An authority prefixed by `ROLE_` means that this authority is a role, likely derived from an RBAC authorization model.
392390

393-
You can change the prefix by setting the `rolePrefix` property of `RoleVoter`. If you need only to use roles in your application and have no need for other custom voters, you can set the prefix to a blank string. In that case, the `RoleVoter` treats all attributes as roles.
391+
Having a prefix allows for clear differentiation from OAuth 2.0 scopes (which use `SCOPE_`) and authorities granted from other sources as well.
394392

393+
You may choose to not prefix your authorities.
394+
Modern Spring Security authorization components either allow you to supply the entire authority name, rendering the prefix unnecessary.
395+
An example of this is how xref:servlet/authorization/authorize-http-requests.adoc[`authorizeHttpRequests`] and xref:servlet/authorization/method-security.adoc[`@PreAuthorize`] allow you to call `hasAuthority` or `hasRole`.
395396

396397
[[appendix-faq-what-dependencies]]
397398
=== How do I know which dependencies to add to my application to work with Spring Security?

docs/modules/ROOT/pages/servlet/appendix/namespace/method-security.adoc

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ Methods can be secured by the use of annotations (defined at the interface or cl
5656
[[nsa-global-method-security-attributes]]
5757
=== <global-method-security> Attributes
5858

59+
[NOTE]
60+
=====
61+
`<global-method-security>` is deprecated in favor of `<method-security>`.
62+
If you need to use `<global-method-security>`, please include the `spring-security-access` dependency in your build configuration.
63+
=====
5964

6065
[[nsa-global-method-security-access-decision-manager-ref]]
6166
* **access-decision-manager-ref**
@@ -145,6 +150,11 @@ You can define zero or more of these within the `global-method-security` element
145150
[[nsa-after-invocation-provider-attributes]]
146151
=== <after-invocation-provider> Attributes
147152

153+
[NOTE]
154+
=====
155+
`<after-invocation-provider>` is deprecated in favor of `<method-security>` and xref:servlet/authorization/method-security.adoc[`@PostFilter` and `@PostAuthorize`].
156+
If you need to use `<after-invocation-provider>`, please include the `spring-security-access` dependency in your build configuration while planning to migrate to a modern option.
157+
=====
148158

149159
[[nsa-after-invocation-provider-ref]]
150160
* **ref**
@@ -179,6 +189,11 @@ Only applies if these annotations are enabled.
179189
== <invocation-attribute-factory>
180190
Defines the PrePostInvocationAttributeFactory instance which is used to generate pre and post invocation metadata from the annotated methods.
181191

192+
[NOTE]
193+
=====
194+
`<invocation-attribute-factory>` is deprecated in favor of `<method-security>` and xref:servlet/authorization/method-security.adoc[`@PostFilter` and `@PostAuthorize`].
195+
If you need to use `<invocation-attribute-factory>`, please include the `spring-security-access` dependency in your build configuration while planning to migrate to a modern option.
196+
=====
182197

183198
[[nsa-invocation-attribute-factory-parents]]
184199
=== Parent Elements of <invocation-attribute-factory>
@@ -201,6 +216,11 @@ Defines a reference to a Spring bean Id.
201216
== <post-invocation-advice>
202217
Customizes the `PostInvocationAdviceProvider` with the ref as the `PostInvocationAuthorizationAdvice` for the <pre-post-annotation-handling> element.
203218

219+
[NOTE]
220+
=====
221+
`<post-invocation-advice>` is deprecated in favor of `<method-security>` and xref:servlet/authorization/method-security.adoc[`@PostFilter` and `@PostAuthorize`].
222+
If you need to use `<post-invocation-advice>`, please include the `spring-security-access` dependency in your build configuration while planning to migrate to a modern option.
223+
=====
204224

205225
[[nsa-post-invocation-advice-parents]]
206226
=== Parent Elements of <post-invocation-advice>
@@ -223,6 +243,11 @@ Defines a reference to a Spring bean Id.
223243
== <pre-invocation-advice>
224244
Customizes the `PreInvocationAuthorizationAdviceVoter` with the ref as the `PreInvocationAuthorizationAdviceVoter` for the <pre-post-annotation-handling> element.
225245

246+
[NOTE]
247+
=====
248+
`<pre-invocation-advice>` is deprecated in favor of `<method-security>` and xref:servlet/authorization/method-security.adoc[`@PreFilter` and `@PreAuthorize`].
249+
If you need to use `<pre-invocation-advice>`, please include the `spring-security-access` dependency in your build configuration while planning to migrate to a modern option.
250+
=====
226251

227252
[[nsa-pre-invocation-advice-parents]]
228253
=== Parent Elements of <pre-invocation-advice>
@@ -247,7 +272,6 @@ Defines a reference to a Spring bean Id.
247272
Rather than defining security attributes on an individual method or class basis using the `@Secured` annotation, you can define cross-cutting security constraints across whole sets of methods and interfaces in your service layer using the `<protect-pointcut>` element.
248273
You can find an example in the xref:servlet/authorization/method-security.adoc#ns-protect-pointcut[namespace introduction].
249274

250-
251275
[[nsa-protect-pointcut-parents]]
252276
=== Parent Elements of <protect-pointcut>
253277

@@ -293,7 +317,6 @@ Optional AuthorizationManager bean ID to be used instead of the default (superse
293317
* **access-decision-manager-ref**
294318
Optional AccessDecisionManager bean ID to be used by the created method security interceptor.
295319

296-
297320
[[nsa-intercept-methods-children]]
298321
=== Child Elements of <intercept-methods>
299322

@@ -306,6 +329,11 @@ Optional AccessDecisionManager bean ID to be used by the created method security
306329
== <method-security-metadata-source>
307330
Creates a MethodSecurityMetadataSource instance
308331

332+
[NOTE]
333+
=====
334+
`<method-security-metadata-source>` is deprecated in favor of xref:servlet/authorization/method-security.adoc[`<method-security>`].
335+
If you need to use `<method-security-metadata-source>`, please include the `spring-security-access` dependency in your build configuration while planning to migrate to a modern option.
336+
=====
309337

310338
[[nsa-method-security-metadata-source-attributes]]
311339
=== <method-security-metadata-source> Attributes

docs/modules/ROOT/pages/servlet/authorization/acls.adoc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ When you use Spring Security as the foundation, you have several possible approa
1717
* Write your business methods to enforce the security.
1818
You could consult a collection within the `Customer` domain object instance to determine which users have access.
1919
By using `SecurityContextHolder.getContext().getAuthentication()`, you can access the `Authentication` object.
20-
* Write an `AccessDecisionVoter` to enforce the security from the `GrantedAuthority[]` instances stored in the `Authentication` object.
20+
* Write an `AuthorizationManager` to enforce the security from the `GrantedAuthority[]` instances stored in the `Authentication` object.
2121
This means that your `AuthenticationManager` needs to populate the `Authentication` with custom `GrantedAuthority[]` objects to represent each of the `Customer` domain object instances to which the principal has access.
22-
* Write an `AccessDecisionVoter` to enforce the security and open the target `Customer` domain object directly.
22+
* Write an `AuthorizationManager` to enforce the security and open the target `Customer` domain object directly.
2323
This would mean your voter needs access to a DAO that lets it retrieve the `Customer` object.
2424
It can then access the `Customer` object's collection of approved users and make the appropriate decision.
2525

@@ -29,7 +29,7 @@ The main problems with this include the enhanced difficulty of unit testing and
2929
Obtaining the `GrantedAuthority[]` instances from the `Authentication` object is also fine but will not scale to large numbers of `Customer` objects.
3030
If a user can access 5,000 `Customer` objects (unlikely in this case, but imagine if it were a popular vet for a large Pony Club!) the amount of memory consumed and the time required to construct the `Authentication` object would be undesirable.
3131
The final method, opening the `Customer` directly from external code, is probably the best of the three.
32-
It achieves separation of concerns and does not misuse memory or CPU cycles, but it is still inefficient in that both the `AccessDecisionVoter` and the eventual business method itself perform a call to the DAO responsible for retrieving the `Customer` object.
32+
It achieves separation of concerns and does not misuse memory or CPU cycles, but it is still inefficient in that both the `AuthorizationManager` and the eventual business method itself perform a call to the DAO responsible for retrieving the `Customer` object.
3333
Two accesses per method invocation is clearly undesirable.
3434
In addition, with every approach listed, you need to write your own access control list (ACL) persistence and business logic from scratch.
3535

@@ -40,6 +40,11 @@ Fortunately, there is another alternative, which we discuss later.
4040
Spring Security's ACL services are shipped in the `spring-security-acl-xxx.jar`.
4141
You need to add this JAR to your classpath to use Spring Security's domain object instance security capabilities.
4242

43+
[NOTE]
44+
====
45+
If you need access to the legacy Access API that includes `AclEntryVoter`, please also include `spring-security-access-xxx.jar`.
46+
====
47+
4348
Spring Security's domain object instance security capabilities center on the concept of an access control list (ACL).
4449
Every domain object instance in your system has its own ACL, and the ACL records details of who can and cannot work with that domain object.
4550
With this in mind, Spring Security provides three main ACL-related capabilities to your application:

docs/modules/ROOT/pages/servlet/authorization/architecture.adoc

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This section describes the Spring Security architecture that applies to authoriz
1010
== Authorities
1111
xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[`Authentication`] discusses how all `Authentication` implementations store a list of `GrantedAuthority` objects.
1212
These represent the authorities that have been granted to the principal.
13-
The `GrantedAuthority` objects are inserted into the `Authentication` object by the `AuthenticationManager` and are later read by `AccessDecisionManager` instances when making authorization decisions.
13+
The `GrantedAuthority` objects are inserted into the `Authentication` object by the `AuthenticationManager` and are later read by `AuthorizationManager` instances when making authorization decisions.
1414

1515
The `GrantedAuthority` interface has only one method:
1616

@@ -347,6 +347,28 @@ Spring Security contains some legacy components.
347347
Since they are not yet removed, documentation is included for historical purposes.
348348
Their recommended replacements are above.
349349

350+
When accessing legacy authorization components, please also include the `spring-security-access` dependency like so:
351+
352+
[tabs]
353+
======
354+
Maven::
355+
+
356+
[source,xml,role="primary"]
357+
----
358+
<dependency>
359+
<groupId>org.springframework.security</groupId>
360+
<artifactId>spring-security-access</artifactId>
361+
</dependency>
362+
----
363+
364+
Gradle::
365+
+
366+
[source,groovy,role="primary"]
367+
----
368+
implementation('org.springframework.security:spring-security-access')
369+
----
370+
======
371+
350372
[[authz-access-decision-manager]]
351373
=== The AccessDecisionManager
352374
The `AccessDecisionManager` is called by the `AbstractSecurityInterceptor` and is responsible for making final access control decisions.

docs/modules/ROOT/pages/servlet/authorization/index.adoc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,11 @@ You should consider attaching authorization rules to xref:servlet/authorization/
1111
In either case, you can listen and react to xref:servlet/authorization/events.adoc[authorization events] that each authorization check publishes.
1212
Below there is also wealth of detail about xref:servlet/authorization/architecture.adoc[how Spring Security authorization works] and how, having established a basic model, it can be fine-tuned.
1313

14+
[NOTE]
15+
====
16+
As of Spring Security 7, the Access API (`AccessDecisionManager`, `AccessDecisionVoter`, etc.) are moved to a legacy module, `spring-security-access`.
17+
For new applications, there is no need to include the dependency.
18+
For older applications that have not yet migrated to the Authorization API, this module is available to assist your continued migration efforts.
19+
====
20+
1421

docs/modules/ROOT/pages/servlet/authorization/method-security.adoc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3089,6 +3089,28 @@ Make sure to read the <<meta-annotations,Meta Annotations Support>> section for
30893089

30903090
If you are using `@EnableGlobalMethodSecurity`, you should migrate to `@EnableMethodSecurity`.
30913091

3092+
If you cannot migrate at this time, please include the `spring-security-access` module as a dependency like so:
3093+
3094+
[tabs]
3095+
======
3096+
Maven::
3097+
+
3098+
[source,xml,role="primary"]
3099+
----
3100+
<dependency>
3101+
<groupId>org.springframework.security</groupId>
3102+
<artifactId>spring-security-access</artifactId>
3103+
</dependency>
3104+
----
3105+
3106+
Gradle::
3107+
+
3108+
[source,groovy,role="primary"]
3109+
----
3110+
implementation('org.springframework.security:spring-security-access')
3111+
----
3112+
======
3113+
30923114
[[servlet-replace-globalmethodsecurity-with-methodsecurity]]
30933115
=== Replace xref:servlet/authorization/method-security.adoc#jc-enable-global-method-security[global method security] with xref:servlet/authorization/method-security.adoc#jc-enable-method-security[method security]
30943116

docs/modules/ROOT/pages/whats-new.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Each section that follows will indicate the more notable removals as well as the
1414
* Removed `AuthorizationManager#check` in favor of `AuthorizationManager#authorize`
1515
* Added xref:servlet/authorization/architecture.adoc#authz-authorization-manager-factory[`AuthorizationManagerFactory`] for creating `AuthorizationManager` instances in xref:servlet/authorization/authorize-http-requests.adoc#customizing-authorization-managers[request-based] and xref:servlet/authorization/method-security.adoc#customizing-authorization-managers[method-based] authorization components
1616
* Added `Authentication.Builder` for mutating and merging `Authentication` instances
17+
* Moved Access API (`AccessDecisionManager`, `AccessDecisionVoter`, etc.) to a new module, `spring-security-access`
1718

1819
== Config
1920

0 commit comments

Comments
 (0)