diff --git a/docs/modules/ROOT/pages/servlet/authentication/anonymous.adoc b/docs/modules/ROOT/pages/servlet/authentication/anonymous.adoc index 3438b5ef37..197b32f77c 100644 --- a/docs/modules/ROOT/pages/servlet/authentication/anonymous.adoc +++ b/docs/modules/ROOT/pages/servlet/authentication/anonymous.adoc @@ -137,7 +137,8 @@ fun method(authentication: Authentication?): String { will always return "not anonymous", even for anonymous requests. The reason is that Spring MVC resolves the parameter using `HttpServletRequest#getPrincipal`, which is `null` when the request is anonymous. -If you'd like to obtain the `Authentication` in anonymous requests, use `@CurrentSecurityContext` instead: +If you'd like to obtain the `Authentication` in anonymous requests, use +xref:servlet/integrations/mvc.adoc#mvc-current-security-context[`@CurrentSecurityContext`] instead: .Use CurrentSecurityContext for Anonymous requests [tabs] diff --git a/docs/modules/ROOT/pages/servlet/authentication/architecture.adoc b/docs/modules/ROOT/pages/servlet/authentication/architecture.adoc index 259ede2376..39c25bba40 100644 --- a/docs/modules/ROOT/pages/servlet/authentication/architecture.adoc +++ b/docs/modules/ROOT/pages/servlet/authentication/architecture.adoc @@ -97,7 +97,11 @@ val authorities = authentication.authorities ---- ====== -// FIXME: Add links to and relevant description of HttpServletRequest.getRemoteUser() and @CurrentSecurityContext @AuthenticationPrincipal +In Spring MVC, you can resolve the current principal with +xref:servlet/integrations/mvc.adoc#mvc-authentication-principal[`@AuthenticationPrincipal`] +and the full `SecurityContext` with +xref:servlet/integrations/mvc.adoc#mvc-current-security-context[`@CurrentSecurityContext`]. +For Servlet API access, use `HttpServletRequest#getRemoteUser`. By default, `SecurityContextHolder` uses a `ThreadLocal` to store these details, which means that the `SecurityContext` is always available to methods in the same thread, 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 you take care to clear the thread after the present principal's request is processed. diff --git a/docs/modules/ROOT/pages/servlet/integrations/mvc.adoc b/docs/modules/ROOT/pages/servlet/integrations/mvc.adoc index 5c5e4dd27d..a4ce825cfc 100644 --- a/docs/modules/ROOT/pages/servlet/integrations/mvc.adoc +++ b/docs/modules/ROOT/pages/servlet/integrations/mvc.adoc @@ -448,6 +448,72 @@ open fun findMessagesForUser(@CurrentUser("user_id") userId: String?): ModelAndV ---- ====== +[[mvc-current-security-context]] +== @CurrentSecurityContext + +Spring Security provides `CurrentSecurityContextArgumentResolver`, which can automatically resolve the current `SecurityContext` for Spring MVC arguments. +By using `@EnableWebSecurity`, you automatically have this added to your Spring MVC configuration. +If you use XML-based configuration, you must add this yourself: + +[source,xml] +---- + + + + + +---- + +Once `CurrentSecurityContextArgumentResolver` is configured, you can access the `SecurityContext` directly: + +[tabs] +====== +Java:: ++ +[source,java,role="primary"] +---- +@GetMapping("/me") +public String me(@CurrentSecurityContext SecurityContext context) { + return context.getAuthentication().getName(); +} +---- + +Kotlin:: ++ +[source,kotlin,role="secondary"] +---- +@GetMapping("/me") +fun me(@CurrentSecurityContext context: SecurityContext): String { + return context.authentication.name +} +---- +====== + +You can also use a SpEL expression that is rooted at the `SecurityContext`: + +[tabs] +====== +Java:: ++ +[source,java,role="primary"] +---- +@GetMapping("/me") +public String me(@CurrentSecurityContext(expression = "authentication") Authentication authentication) { + return authentication.getName(); +} +---- + +Kotlin:: ++ +[source,kotlin,role="secondary"] +---- +@GetMapping("/me") +fun me(@CurrentSecurityContext(expression = "authentication") authentication: Authentication): String { + return authentication.name +} +---- +====== + [[mvc-async]] == Spring MVC Async Integration