Pārlūkot izejas kodu

Extract SecurityContextHolder Docs

Issue gh-8005
Rob Winch 5 gadi atpakaļ
vecāks
revīzija
702cc1d2bb

+ 67 - 0
docs/manual/src/docs/asciidoc/_includes/servlet/authentication/architecture/security-context-holder.adoc

@@ -0,0 +1,67 @@
+[[servlet-authentication-securitycontextholder]]
+= SecurityContextHolder
+
+:figures: images/servlet/authentication/architecture
+
+At the heart of Spring Security's authentication model is the `SecurityContextHolder`.
+It contains the <<servlet-authentication-securitycontext>>.
+
+image::{figures}/securitycontextholder.png[]
+
+The `SecurityContextHolder` is where Spring Security stores the details of who is <<authentication,authenticated>>.
+Spring Security does not care how the `SecurityContextHolder` is populated.
+If it contains a value, then it is used as the currently authenticated user.
+
+The simplest way to indicate a user is authenticated is to set the `SecurityContextHolder` directly.
+
+.Setting `SecurityContextHolder`
+====
+[source,java]
+----
+SecurityContext context = SecurityContextHolder.createEmptyContext(); // <1>
+Authentication authentication =
+    new TestingAuthenticationToken("username", "password", "ROLE_USER"); // <2>
+context.setAuthentication(authentication);
+
+SecurityContextHolder.setContext(context); // <3>
+----
+====
+
+<1> We start by creating an empty `SecurityContext`.
+It is important to create a new `SecurityContext` instance instead of using `SecurityContextHolder.getContext().setAuthentication(authentication)` to avoid race conditions across multiple threads.
+<2> Next we create a new <<servlet-authentication-authentication,`Authentication`>> object.
+Spring Security does not care what type of `Authentication` implementation is set on the `SecurityContext`.
+Here we use `TestingAuthenticationToken` because it is very simple.
+A more common production scenario is `UsernamePasswordAuthenticationToken(userDetails, password, authorities)`.
+<3> Finally, we set the `SecurityContext` on the `SecurityContextHolder`.
+Spring Security will use this information for <<authorization>>.
+
+If you wish to obtain information about the authenticated principal, you can do so by accessing the `SecurityContextHolder`.
+
+.Access Currently Authenticated User
+====
+[source,java]
+----
+SecurityContext context = SecurityContextHolder.getContext();
+Authentication authentication = context.getAuthentication();
+String username = authentication.getName();
+Object principal = authentication.getPrincipal();
+Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
+----
+====
+
+// FIXME: add links to HttpServletRequest.getRemoteUser() and @CurrentSecurityContext @AuthenticationPrincipal
+
+By default the `SecurityContextHolder` uses a `ThreadLocal` to store these details, which means that the `SecurityContext` is always available to methods in the same thread of execution, even if the `SecurityContext` is not explicitly passed around as an argument to those methods.
+Using a `ThreadLocal` in this way is quite safe if care is taken to clear the thread after the present principal's request is processed.
+Spring Security's <<servlet-filterchainproxy,FilterChainProxy>> ensures that the `SecurityContext` is always cleared.
+
+Some applications aren't entirely suitable for using a `ThreadLocal`, because of the specific way they work with threads.
+For example, a Swing client might want all threads in a Java Virtual Machine to use the same security context.
+`SecurityContextHolder` can be configured with a strategy on startup to specify how you would like the context to be stored.
+For a standalone application you would use the `SecurityContextHolder.MODE_GLOBAL` strategy.
+Other applications might want to have threads spawned by the secure thread also assume the same security identity.
+This is achieved by using `SecurityContextHolder.MODE_INHERITABLETHREADLOCAL`.
+You can change the mode from the default `SecurityContextHolder.MODE_THREADLOCAL` in two ways.
+The first is to set a system property, the second is to call a static method on `SecurityContextHolder`.
+Most applications won't need to change from the default, but if you do, take a look at the JavaDoc for `SecurityContextHolder` to learn more.