-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Add ExpressionTemplateValueProvider #17448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package org.springframework.security.core.annotation; | ||
|
||
/** | ||
* Provides a mechanism for providing custom values from enum types used in security | ||
* meta-annotation expressions. For example: | ||
* | ||
* <pre> | ||
* enum Permission implements ExpressionTemplateValueProvider { | ||
* READ, | ||
* WRITE; | ||
* | ||
* @Override | ||
* public String getExpressionTemplateValue() { | ||
* return switch (this) { | ||
* case READ -> "user.permission-read"; | ||
* case WRITE -> "user.permission-write"; | ||
* } | ||
* } | ||
* | ||
* } | ||
* </pre> | ||
* | ||
* @since 6.5 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will you update this to 7.0 now that that's the target release? |
||
* @author Mike Heath | ||
*/ | ||
public interface ExpressionTemplateValueProvider { | ||
|
||
/** | ||
* Returns the value to be used in an expression template. | ||
* | ||
* @return the value to be used in an expression template | ||
*/ | ||
String getExpressionTemplateValue(); | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,43 @@ void parseMultipleMetaSourceAnnotationParameterWithAliasFor() throws Exception { | |
assertThat(preAuthorize.value()).isEqualTo("check(#name)"); | ||
} | ||
|
||
@Test | ||
void parseMetaSourceAnnotationWithEnumImplementingExpressionTemplateValueProvider() throws Exception { | ||
Method method = MessageService.class.getDeclaredMethod("process"); | ||
PreAuthorize preAuthorize = this.scanner.scan(method, method.getDeclaringClass()); | ||
assertThat(preAuthorize.value()).isEqualTo("hasAnyAuthority(user.READ,user.WRITE)"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The resulting expression may not be useful since SpEL may try and interpret hasAnyAuthority('user.READ','user.WRITE') which I believe you can achieve by placing single quotes in |
||
} | ||
|
||
enum Permission implements ExpressionTemplateValueProvider { | ||
READ, | ||
WRITE; | ||
|
||
@Override | ||
public String getExpressionTemplateValue() { | ||
return switch (this) { | ||
case READ -> "user.READ"; | ||
case WRITE -> "user.WRITE"; | ||
}; | ||
} | ||
} | ||
|
||
@Documented | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.TYPE, ElementType.METHOD }) | ||
@PreAuthorize("hasAnyAuthority({permissions})") | ||
@interface HasAnyCustomPermissions { | ||
|
||
Permission[] permissions(); | ||
|
||
} | ||
|
||
@Documented | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.TYPE, ElementType.METHOD }) | ||
@HasAnyCustomPermissions(permissions = { Permission.READ, Permission.WRITE }) | ||
@interface HasAllCustomPermissions { | ||
} | ||
|
||
@Documented | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.TYPE, ElementType.METHOD }) | ||
|
@@ -86,6 +123,9 @@ void parseMultipleMetaSourceAnnotationParameterWithAliasFor() throws Exception { | |
|
||
private interface MessageService { | ||
|
||
@HasAllCustomPermissions | ||
void process(); | ||
|
||
@HasReadPermission("#name") | ||
String sayHello(String name); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While not a guarantee, I imagine that most folks will want to inject a value as a string, which will mean applying single quotes around it. Because it won't work to do
'{permissions}'
in an expression, it seems preferable to always surround the value in single quotes, thus allowing a template to do{permissions}
or{permission}
and still have the template compile.If you agree with that, will you please place single quotes around each returned value?