Skip to content

Allow custom conversation for enum values in meta annotation expression templates #17447

Open
@mheath

Description

@mheath

Arrays of enums in security meta annotations have limited utility because there's no clean mechanism to convert the enum to a custom value.

If I have an enum that specifies my permissions, such as:

enum Permission {
  READ("permission.read"),
  WRITE("permission.write");

  private final value;

  // constructor implementation

  @Override
  public String toString() {
    return value;
  }
}

I cannot have a working meta annotation with an array of enums such as the following:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@PreAuthorize("hasAnyAuthority({permissions})")
@interface HasAnyPermission {
 Permission[] permissions();
}

The ExpressionTemplateSecurityAnnotationScanner.conversionService includes EnumToStringConverter that will always use Enum.name() instead of my overridden toString() method.

Modifying the static conversionService initializer in ExpressionTemplateSecurityAnnotationScanner to:

static {
	conversionService.addConverter(new ClassToStringConverter());
	conversionService.removeConvertible(Enum.class, String.class);
}

corrects the issue.

Since the default Enum.toString() returns the enum's name, removing the explicit Enum converter would be backwards compatible for most code. I'm sure there's a more clever solution that ensures backwards compatibility.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions