Merge branch '5.8.x' into 6.0.x
Closes gh-13406
This commit is contained in:
@@ -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)
|
||||
);
|
||||
----
|
||||
====
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user