|
@@ -193,6 +193,91 @@ To opt into the new Spring Security 6 default, the following configuration can b
|
|
|
|
|
|
include::partial$servlet/architecture/security-context-explicit.adoc[]
|
|
|
|
|
|
+=== Deprecation in SecurityContextRepository
|
|
|
+
|
|
|
+In Spring Security 5.7, a new method was added to xref:servlet/authentication/persistence.adoc#securitycontextrepository[`SecurityContextRepository`] with the signature:
|
|
|
+
|
|
|
+ Supplier<SecurityContext> loadContext(HttpServletRequest request)
|
|
|
+
|
|
|
+With the addition of xref:servlet/authentication/persistence.adoc#delegatingsecuritycontextrepository[`DelegatingSecurityContextRepository`] in Spring Security 5.8, that method was deprecated in favor of a new method with the signature:
|
|
|
+
|
|
|
+ DeferredSecurityContext loadDeferredContext(HttpServletRequest request)
|
|
|
+
|
|
|
+In Spring Security 6, the deprecated method was removed.
|
|
|
+If you have implemented `SecurityContextRepository` yourself and added an implementation of the `loadContext(request)` method, you can prepare for Spring Security 6 by removing the implementation of that method and implementing the new method instead.
|
|
|
+
|
|
|
+To get started implementing the new method, use the following example that adapts a `Supplier<SecurityContext>` to provide a `DeferredSecurityContext`:
|
|
|
+
|
|
|
+[NOTE]
|
|
|
+====
|
|
|
+The adapted `Supplier` should return `null` when no `SecurityContext` is available, which was not the case with the `Supplier` returned from `loadContext(request)`.
|
|
|
+====
|
|
|
+
|
|
|
+.Adapt `Supplier<SecurityContext>` to `DeferredSecurityContext`
|
|
|
+====
|
|
|
+.Java
|
|
|
+[source,java,role="primary"]
|
|
|
+----
|
|
|
+@Override
|
|
|
+public DeferredSecurityContext loadDeferredContext(HttpServletRequest request) {
|
|
|
+ // Adapt a supplier that returns null when the context is not available
|
|
|
+ Supplier<SecurityContext> supplier = () -> getContextOrNull(request);
|
|
|
+ SecurityContextHolderStrategy strategy = SecurityContextHolder.getContextHolderStrategy();
|
|
|
+ return new DeferredSecurityContext() {
|
|
|
+ private SecurityContext securityContext;
|
|
|
+ private boolean isGenerated;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SecurityContext get() {
|
|
|
+ if (this.securityContext == null) {
|
|
|
+ this.securityContext = supplier.get();
|
|
|
+ if (this.securityContext == null) {
|
|
|
+ this.securityContext = strategy.createEmptyContext();
|
|
|
+ this.isGenerated = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return this.securityContext;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean isGenerated() {
|
|
|
+ get();
|
|
|
+ return this.isGenerated;
|
|
|
+ }
|
|
|
+ };
|
|
|
+}
|
|
|
+----
|
|
|
+
|
|
|
+.Kotlin
|
|
|
+[source,kotlin,role="secondary"]
|
|
|
+----
|
|
|
+override fun loadDeferredContext(request: HttpServletRequest): DeferredSecurityContext {
|
|
|
+ // Adapt a supplier that returns null when the context is not available
|
|
|
+ val supplier: Supplier<SecurityContext?> = SingletonSupplier.of {
|
|
|
+ getContextOrNull(request)
|
|
|
+ }
|
|
|
+ val strategy = SecurityContextHolder.getContextHolderStrategy()
|
|
|
+ return object : DeferredSecurityContext {
|
|
|
+ private var securityContext: SecurityContext? = null
|
|
|
+ private var isGenerated = false
|
|
|
+
|
|
|
+ override fun get(): SecurityContext {
|
|
|
+ if (securityContext == null) {
|
|
|
+ securityContext = supplier.get()
|
|
|
+ ?: strategy.createEmptyContext().also { isGenerated = true }
|
|
|
+ }
|
|
|
+ return securityContext!!
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun isGenerated(): Boolean {
|
|
|
+ get()
|
|
|
+ return isGenerated
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+----
|
|
|
+====
|
|
|
+
|
|
|
[[requestcache-query-optimization]]
|
|
|
=== Optimize Querying of `RequestCache`
|
|
|
|