فهرست منبع

Add doc and javadoc for CachingUserDetailsService

Close gh-10914
Federico Herrera 1 سال پیش
والد
کامیت
10e0f98d5e

+ 49 - 0
core/src/main/java/org/springframework/security/authentication/CachingUserDetailsService.java

@@ -23,6 +23,55 @@ import org.springframework.security.core.userdetails.cache.NullUserCache;
 import org.springframework.util.Assert;
 
 /**
+ * Implementation of {@link UserDetailsService} that utilizes caching through a
+ * {@link UserCache}
+ * <p>
+ * If a null {@link UserDetails} instance is got from calling
+ * {@link UserCache#getUserFromCache(String)} to the {@link UserCache} got from
+ * {@link #getUserCache()}, the user load is deferred to the {@link UserDetailsService}
+ * provided during construction. Otherwise, the instance got from cache is returned.
+ * <p>
+ * It is initialized with a {@link NullUserCache} by default, so it's strongly recommended
+ * setting your own {@link UserCache} using {@link #setUserCache(UserCache)}, otherwise,
+ * the delegate will be called every time.
+ * <p>
+ * Utilize this class by defining {@link org.springframework.context.annotation.Bean} that
+ * encapsulates an actual implementation of {@link UserDetailsService} and set an
+ * {@link UserCache}.
+ * </p>
+ * For example: <pre>{@code
+ * &#64;Bean
+ * public CachingUserDetailsService cachingUserDetailsService(UserDetailsService delegate,
+ *                                                            UserCache userCache) {
+ *     CachingUserDetailsService service = new CachingUserDetailsService(delegate);
+ *     service.setUserCache(userCache);
+ *     return service;
+ * }
+ * }</pre>
+ *
+ * <p>
+ * However, a preferable approach would be to use
+ * {@link org.springframework.cache.annotation.Cacheable} in your
+ * {@link UserDetailsService#loadUserByUsername(String)} implementation to cache
+ * {@link UserDetails} by <code>username</code>, reducing boilerplate and setup, specially
+ * if you are already using cache in your application.
+ * </p>
+ *
+ * For example:
+ *
+ * <pre>{@code
+ * &#64;Service
+ * public class MyCustomUserDetailsImplementation implements UserDetailsService {
+
+ *     &#64;Override
+ *     &#64;Cacheable
+ *     public UserDetails loadUserByUsername(String username) {
+ *         //some logic here to get the actual user details
+ *         return userDetails;
+ *     }
+ * }
+ * }</pre>
+ *
  * @author Luke Taylor
  * @since 2.0
  */

+ 38 - 0
docs/modules/ROOT/pages/servlet/authentication/passwords/cached.adoc

@@ -0,0 +1,38 @@
+[[servlet-authentication-cached]]
+= CachingUserDetailsService
+
+Spring Security's `CachingUserDetailsService` implements xref:servlet/authentication/passwords/user-details-service.adoc#servlet-authentication-userdetailsservice[UserDetailsService] offering support for caching authentication.
+
+`CachingUserDetailsService` provides caching support for `UserDetails` by delegating the authentication process to the provided `UserDetailsService`. The result is then stored in a `UserCache` to reduce computation in subsequent calls.
+
+Utilize this class by defining a `@Bean` of it that encapsulates a concrete implementation of `UserDetailsService` and set a `UserCache` to cache authenticated `UserDetails`.
+
+For example:
+
+[source,java]
+----
+@Bean
+public CachingUserDetailsService cachingUserDetailsService(UserDetailsService delegate, UserCache userCache) {
+    CachingUserDetailsService service = new CachingUserDetailsService(delegate);
+    service.setUserCache(userCache);
+    return service;
+}
+----
+
+However, a preferable approach would be to use `@Cacheable` in your `UserDetailsService.loadUserByUsername(String)` implementation to cache `UserDetails` by `username`, reducing boilerplate and setup, especially if you are already using cache in your application.
+
+For example:
+
+[source,java]
+----
+@Service
+public class MyCustomUserDetailsImplementation implements UserDetailsService {
+
+    @Override
+    @Cacheable
+    public UserDetails loadUserByUsername(String username) {
+        // some logic here to get the actual user details
+        return userDetails;
+    }
+}
+----

+ 1 - 1
docs/modules/ROOT/pages/servlet/authentication/passwords/user-details-service.adoc

@@ -2,7 +2,7 @@
 = UserDetailsService
 
 {security-api-url}org/springframework/security/core/userdetails/UserDetailsService.html[`UserDetailsService`] is used by xref:servlet/authentication/passwords/dao-authentication-provider.adoc#servlet-authentication-daoauthenticationprovider[`DaoAuthenticationProvider`] for retrieving a username, a password, and other attributes for authenticating with a username and password.
-Spring Security provides xref:servlet/authentication/passwords/in-memory.adoc#servlet-authentication-inmemory[in-memory] and xref:servlet/authentication/passwords/jdbc.adoc#servlet-authentication-jdbc[JDBC] implementations of `UserDetailsService`.
+Spring Security provides xref:servlet/authentication/passwords/in-memory.adoc#servlet-authentication-inmemory[in-memory], xref:servlet/authentication/passwords/jdbc.adoc#servlet-authentication-jdbc[JDBC], and xref:servlet/authentication/passwords/cached.adoc#servlet-authentication-cached[in-cache] implementations of `UserDetailsService`.
 
 You can define custom authentication by exposing a custom `UserDetailsService` as a bean.
 For example, the following listing customizes authentication, assuming that `CustomUserDetailsService` implements `UserDetailsService`: