Skip to content

PrePostTemplateDefaults pick up the ConversionService bean #15721

Closed
@vratojr

Description

@vratojr

Expected Behavior

When a ConversionService bean is defined, it should be picked up by the AuthorizationAnnotationUtils

Current Behavior

AuthorizationAnnotationUtils use a static access to the DefaultConversionService

Context

I have an annotation like:

@Documented
@Target({ METHOD, TYPE })
@Retention(RUNTIME)
@PreAuthorize("@accessControlManager.hasAuthorization(#id)")
@Inherited
public @interface RestrictedAccess {

  AccessRight access();

  Functionality functionality();

  Class<?> entityClass();

  String[] recipes() default {};
}

That always pick the 'id' param of the annotated method. Now I need to make it more generic, in case the id is 'hidden' somewhere else, so following the guide I updated to this version:

@Documented
@Target({ METHOD, TYPE })
@Retention(RUNTIME)
@PreAuthorize("@accessControlManager.hasAuthorization({idPath})")
@Inherited
public @interface RestrictedAccess {

  /* SPEL expression that return the id of the concerned entity. By default it corresponds to a parameter named 'id' */
  String idPath() default "#id";

  AccessRight access();

  Functionality functionality();

  Class<?> entityClass();

  String[] recipes() default {};
}

And I had to add:

  @Bean
  public PrePostTemplateDefaults prePostTemplateDefaults() {
    return new PrePostTemplateDefaults();
  }

In my configuration. The problem is that this last bean activates the AuthorizationAnnotationUtils and this, in turn performs a type check on the parameters of mine annotation and crashes when testing the 'entityClass' attribute since a converter from Class to String is missing. Ok, this is already suspect to me but I started the journey to add a Converter. So I tried to just declare a bean like:

   @Bean
   public ClassToStringConverter classToStringConverter() {
     return new ClassToStringConverter();
   }

The problem is that the bean is picked up by the WebConverter that's not the same instance that's used by the AuthorizationAnnotationUtils. In fact if we look at the code over there we see something like:

String asString = (value instanceof String) ? (String) value
                        : DefaultConversionService.getSharedInstance().convert(value, String.class);

So, the workaround is that I had to force my converter over there with:

  @PostConstruct
  public void setUp() {
    ((GenericConversionService)DefaultConversionService.getSharedInstance()).addConverter(new ClassToStringConverter());
  }

Metadata

Metadata

Assignees

Labels

in: coreAn issue in spring-security-coretype: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions