Skip to content

@Secured annotation unintuitive when using expressions #2012

@bastian-schlueter

Description

@bastian-schlueter

Expected Behavior

@Secured({
    SecurityRule.IS_ANONYMOUS,
    "#{ true }"
})

I would expect the annotated endpoint to permit any request, since the first value is a token to allow unauthorized access and even the second value, an expression, evaluates to true.

I would also expect this configuration to be semantically equivalent:

@Secured({
    "#{ true }",
    SecurityRule.IS_ANONYMOUS
})

Actual Behaviour

The following REJECTS all requests:

@Secured({
    SecurityRule.IS_ANONYMOUS,
    "#{ true }"
})

The following PERMITS all requests:

@Secured({
    "#{ true }",
    SecurityRule.IS_ANONYMOUS
})

The following REJECTS all requests, even if the user has some-role in their roles:

@Secured({
    "some-role",
    "#{ true }"
})

Reasons being:

  1. When expressions are used, only the very first result is checked - effectively dropping the OR semantic
    a. https://github.com/micronaut-projects/micronaut-security/blob/4.13.x/security/src/main/java/io/micronaut/security/rules/SecuredAnnotationRule.java#L75-L80
  2. EvaluatedAnnotationValue::booleanValues returns false for anything that is not an expression - making it impossible to mix expressions and roles/tokens within the same @Secured annotation.

Steps To Reproduce

@Controller
public class MyController {

  @Secured({"#{ true }", SecurityRule.IS_ANONYMOUS})
  @Get("/permitted")
  public void permitted() {}

  @Secured({SecurityRule.IS_ANONYMOUS, "#{ true }"})
  @Get("/rejected")
  public void rejected() {}

  @Secured({SecurityRule.IS_ANONYMOUS, "#{ false }"})
  @Get("/also-rejected")
  public void alsoRejected() {}
}
  1. Request GET /permitted
  2. Observe correct HTTP 200
  3. Request GET /rejected
  4. Observe faulty HTTP 403
  5. Request GET /also-rejected
  6. Observe faulty HTTP 403

Environment Information

No response

Example Application

No response

Version

4.8.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions