فهرست منبع

Document @AuthenticationPrincipal meta-annotations

Issue gh-15286
Josh Cummings 1 سال پیش
والد
کامیت
f4d9d0d54f
1فایلهای تغییر یافته به همراه120 افزوده شده و 0 حذف شده
  1. 120 0
      docs/modules/ROOT/pages/servlet/integrations/mvc.adoc

+ 120 - 0
docs/modules/ROOT/pages/servlet/integrations/mvc.adoc

@@ -503,6 +503,126 @@ open fun findMessagesForUser(@CurrentUser customUser: CustomUser?): ModelAndView
 ----
 ======
 
+Once it is a meta-annotation, parameterization is also available to you.
+
+For example, consider when you have a JWT as your principal and you want to say which claim to retrieve.
+As a meta-annotation, you might do:
+
+[tabs]
+======
+Java::
++
+[source,java,role="primary"]
+----
+@Target({ElementType.PARAMETER, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@AuthenticationPrincipal(expression = "claims['sub']")
+public @interface CurrentUser {}
+----
+
+Kotlin::
++
+[source,kotlin,role="secondary"]
+----
+@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.TYPE)
+@Retention(AnnotationRetention.RUNTIME)
+@MustBeDocumented
+@AuthenticationPrincipal(expression = "claims['sub']")
+annotation class CurrentUser
+----
+======
+
+which is already quite powerful.
+But, it is also limited to retrieving the `sub` claim.
+
+To make this more flexible, first publish the `AnnotationTemplateExpressionDefaults` bean like so:
+
+[tabs]
+======
+Java::
++
+[source,java,role="primary"]
+----
+@Bean
+public AnnotationTemplateExpressionDefaults templateDefaults() {
+	return new AnnotationTemplateExpressionDeafults();
+}
+----
+
+Kotlin::
++
+[source,kotlin,role="secondary"]
+----
+@Bean
+fun templateDefaults(): AnnotationTemplateExpressionDefaults {
+	return AnnotationTemplateExpressionDeafults()
+}
+----
+
+Xml::
++
+[source,xml,role="secondary"]
+----
+<b:bean name="annotationExpressionTemplateDefaults" class="org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults"/>
+----
+======
+
+and then you can supply a parameter to `@CurrentUser` like so:
+
+[tabs]
+======
+Java::
++
+[source,java,role="primary"]
+----
+@Target({ElementType.PARAMETER, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@AuthenticationPrincipal(expression = "claims['{claim}']")
+public @interface CurrentUser {
+	String claim() default 'sub';
+}
+----
+
+Kotlin::
++
+[source,kotlin,role="secondary"]
+----
+@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.TYPE)
+@Retention(AnnotationRetention.RUNTIME)
+@MustBeDocumented
+@AuthenticationPrincipal(expression = "claims['{claim}']")
+annotation class CurrentUser(val claim: String = "sub")
+----
+======
+
+This will allow you more flexibility across your set of applications in the following way:
+
+[tabs]
+======
+Java::
++
+[source,java,role="primary"]
+----
+@RequestMapping("/messages/inbox")
+public ModelAndView findMessagesForUser(@CurrentUser("user_id") String userId) {
+
+	// .. find messages for this user and return them ...
+}
+----
+
+Kotlin::
++
+[source,kotlin,role="secondary"]
+----
+@RequestMapping("/messages/inbox")
+open fun findMessagesForUser(@CurrentUser("user_id") userId: String?): ModelAndView {
+
+    // .. find messages for this user and return them ...
+}
+----
+======
 
 [[mvc-async]]
 == Spring MVC Async Integration