Merge branch '5.8.x' into 6.0.x

Closes gh-13406
This commit is contained in:
Rob Winch
2023-06-18 21:33:58 -05:00
116 changed files with 4826 additions and 3206 deletions

View File

@@ -11,7 +11,6 @@ You can use these as a guideline for defining the schema for the database you ar
The standard JDBC implementation of the `UserDetailsService` (`JdbcDaoImpl`) requires tables to load the password, account status (enabled or disabled) and a list of authorities (roles) for the user.
You can use these as a guideline for defining the schema for the database you use.
====
[source]
----
@@ -28,13 +27,11 @@ create table authorities (
);
create unique index ix_auth_username on authorities (username,authority);
----
====
=== For Oracle database
The following listing shows the Oracle variant of the schema creation commands:
====
[source]
----
CREATE TABLE USERS (
@@ -51,14 +48,12 @@ CREATE TABLE AUTHORITIES (
ALTER TABLE AUTHORITIES ADD CONSTRAINT AUTHORITIES_UNIQUE UNIQUE (USERNAME, AUTHORITY);
ALTER TABLE AUTHORITIES ADD CONSTRAINT AUTHORITIES_FK1 FOREIGN KEY (USERNAME) REFERENCES USERS (USERNAME) ENABLE;
----
====
=== Group Authorities
Spring Security 2.0 introduced support for group authorities in `JdbcDaoImpl`.
The table structure if groups are enabled is as follows.
You need to adjust the following schema to match the database dialect you use:
====
[source]
----
@@ -80,7 +75,6 @@ create table group_members (
constraint fk_group_members_group foreign key(group_id) references groups(id)
);
----
====
Remember that these tables are required only if you us the provided JDBC `UserDetailsService` implementation.
If you write your own or choose to implement `AuthenticationProvider` without a `UserDetailsService`, you have complete freedom over how you store the data, as long as the interface contract is satisfied.
@@ -91,7 +85,6 @@ This table is used to store the data used by the more secure <<remember-me-persi
If you use `JdbcTokenRepositoryImpl` either directly or through the namespace, you need this table.
Remember to adjust this schema to match the database dialect you use:
====
[source]
----
@@ -103,7 +96,6 @@ create table persistent_logins (
);
----
====
[[dbschema-acl]]
== ACL Schema
@@ -127,7 +119,6 @@ These schemas are also demonstrated in the following sections.
=== HyperSQL
The default schema works with the embedded HSQLDB database that is used in unit tests within the framework.
====
[source,ddl]
----
create table acl_sid(
@@ -170,7 +161,6 @@ create table acl_entry(
constraint foreign_fk_5 foreign key(sid) references acl_sid(id)
);
----
====
=== PostgreSQL
@@ -179,7 +169,6 @@ For PostgreSQL, you have to set the `classIdentityQuery` and `sidIdentityQuery`
* `select currval(pg_get_serial_sequence('acl_class', 'id'))`
* `select currval(pg_get_serial_sequence('acl_sid', 'id'))`
====
[source,ddl]
----
create table acl_sid(
@@ -222,11 +211,9 @@ create table acl_entry(
constraint foreign_fk_5 foreign key(sid) references acl_sid(id)
);
----
====
=== MySQL and MariaDB
====
[source,ddl]
----
CREATE TABLE acl_sid (
@@ -269,11 +256,9 @@ CREATE TABLE acl_entry (
CONSTRAINT fk_acl_entry_acl FOREIGN KEY (sid) REFERENCES acl_sid (id)
) ENGINE=InnoDB;
----
====
=== Microsoft SQL Server
====
[source,ddl]
----
CREATE TABLE acl_sid (
@@ -316,11 +301,9 @@ CREATE TABLE acl_entry (
CONSTRAINT fk_acl_entry_acl FOREIGN KEY (sid) REFERENCES acl_sid (id)
);
----
====
=== Oracle Database
====
[source,ddl]
----
CREATE TABLE ACL_SID (
@@ -386,14 +369,12 @@ BEGIN
SELECT ACL_ENTRY_SQ.NEXTVAL INTO :NEW.ID FROM DUAL;
END;
----
====
[[dbschema-oauth2-client]]
== OAuth 2.0 Client Schema
The JDBC implementation of xref:servlet/oauth2/client/core.adoc#oauth2Client-authorized-repo-service[ `OAuth2AuthorizedClientService`] (`JdbcOAuth2AuthorizedClientService`) requires a table for persisting `OAuth2AuthorizedClient` instances.
You will need to adjust this schema to match the database dialect you use.
====
[source,ddl]
----
CREATE TABLE oauth2_authorized_client (
@@ -410,4 +391,3 @@ CREATE TABLE oauth2_authorized_client (
PRIMARY KEY (client_registration_id, principal_name)
);
----
====

View File

@@ -150,7 +150,6 @@ From Spring Security 2.0.1 onwards, when you use namespace-based configuration,
This is a debug level message which occurs the first time an anonymous user attempts to access a protected resource.
====
[source]
----
DEBUG [ExceptionTranslationFilter] - Access is denied (user is anonymous); redirecting to authentication entry point
@@ -158,7 +157,6 @@ org.springframework.security.AccessDeniedException: Access is denied
at org.springframework.security.vote.AffirmativeBased.decide(AffirmativeBased.java:68)
at org.springframework.security.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:262)
----
====
It is normal and shouldn't be anything to worry about.
@@ -176,7 +174,6 @@ Note that SSL requests are never cached.
The following listing shows another debug-level message that occurs the first time an anonymous user attempts to access a protected resource. However, this listing shows what happens when you do not have an `AnonymousAuthenticationFilter` in your filter chain configuration:
====
[source]
----
DEBUG [ExceptionTranslationFilter] - Authentication exception occurred; redirecting to authentication entry point
@@ -185,7 +182,6 @@ org.springframework.security.AuthenticationCredentialsNotFoundException:
at org.springframework.security.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:342)
at org.springframework.security.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:254)
----
====
It is normal and is not something to worry about.
@@ -202,8 +198,10 @@ This differs from one company to another, so you have to find it out yourself.
Before adding a Spring Security LDAP configuration to an application, you should write a simple test by using standard Java LDAP code (without Spring Security involved) and make sure you can get that to work first.
For example, to authenticate a user, you could use the following code:
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@@ -222,7 +220,8 @@ public void ldapAuthenticationIsSuccessful() throws Exception {
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
@Test
@@ -236,7 +235,7 @@ fun ldapAuthenticationIsSuccessful() {
val ctx = InitialLdapContext(env, null)
}
----
====
======
=== Session Management
@@ -301,14 +300,12 @@ It is essential to make sure that the Spring Security session registry is notifi
Without it, the session information is not removed from the registry.
The following example adds a listener in a `web.xml` file:
====
[source,xml]
----
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
----
====
[[appendix-faq-unwanted-session-creation]]
=== Spring Security creates a session somewhere, even though I have configured it not to, by setting the create-session attribute to never. What is wrong?
@@ -420,7 +417,6 @@ Any that are marked as "`optional`" in the Spring Security `pom.xml` files have
If you use Maven, you need to add the following to your `pom.xml` file dependencies:
====
[source]
----
@@ -438,7 +434,6 @@ If you use Maven, you need to add the following to your `pom.xml` file dependenc
</dependency>
----
====
The other required jars should be pulled in transitively.
@@ -531,8 +526,10 @@ To load the data from an alternative source, you must use an explicitly declared
You cannot use the namespace.
You would then implement `FilterInvocationSecurityMetadataSource` to load the data as you please for a particular `FilterInvocation`. The `FilterInvocation` object contains the `HttpServletRequest`, so you can obtain the URL or any other relevant information on which to base your decision, based on what the list of returned attributes contains. A basic outline would look something like the following example:
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@@ -561,7 +558,8 @@ You would then implement `FilterInvocationSecurityMetadataSource` to load the da
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
class MyFilterSecurityMetadataSource : FilterInvocationSecurityMetadataSource {
@@ -584,7 +582,7 @@ class MyFilterSecurityMetadataSource : FilterInvocationSecurityMetadataSource {
}
}
----
====
======
For more information, look at the code for `DefaultFilterInvocationSecurityMetadataSource`.
@@ -597,8 +595,10 @@ The `DefaultLdapAuthoritiesPopulator` loads the user authorities from the LDAP d
To use JDBC instead, you can implement the interface yourself, by using whatever SQL is appropriate for your schema:
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@@ -624,7 +624,8 @@ public class MyAuthoritiesPopulator implements LdapAuthoritiesPopulator {
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
class MyAuthoritiesPopulator : LdapAuthoritiesPopulator {
@@ -644,7 +645,7 @@ class MyAuthoritiesPopulator : LdapAuthoritiesPopulator {
}
}
----
====
======
You would then add a bean of this type to your application context and inject it into the `LdapAuthenticationProvider`. This is covered in the section on configuring LDAP by using explicit Spring beans in the LDAP chapter of the reference manual.
Note that you cannot use the namespace for configuration in this case.
@@ -661,8 +662,10 @@ You can find more information in the https://docs.spring.io/spring/docs/3.0.x/sp
Normally, you would add the functionality you require to the `postProcessBeforeInitialization` method of `BeanPostProcessor`. Suppose that you want to customize the `AuthenticationDetailsSource` used by the `UsernamePasswordAuthenticationFilter` (created by the `form-login` element). You want to extract a particular header called `CUSTOM_HEADER` from the request and use it while authenticating the user.
The processor class would look like the following listing:
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
public class CustomBeanPostProcessor implements BeanPostProcessor {
@@ -686,7 +689,8 @@ public class CustomBeanPostProcessor implements BeanPostProcessor {
}
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
class CustomBeanPostProcessor : BeanPostProcessor {
@@ -704,7 +708,7 @@ class CustomBeanPostProcessor : BeanPostProcessor {
}
}
----
====
======
You would then register this bean in your application context.
Spring automatically invoke it on the beans defined in the application context.