Skip to content

Spring security annotatiton PreAuthorize process equals and not equals in the same way #37526

@fedinskiy

Description

@fedinskiy

Describe the bug

I have an application with an endpoint, protected by annotation @PreAuthorize from spring-security. I use expression #person.name == authentication.principal.username" inside the annotation, which works as expected. However, then I change == to !=, it works the same way.

Expected behavior

When I change the expression, it should deny access for requests which were allowed and allow requests, which were denied.

Actual behavior

The same requests are denied and allowed for == and != expressions.

How to Reproduce?

  1. Generate the app:
quarkus create app org.acme:spring-security \
    --extension='spring-web,spring-security,quarkus-elytron-security-properties-file,resteasy-reactive-jackson' \
    --no-code
  1. Add an endpoint:
@Path("/hello")
public class GreetingResource {

    @POST
    @Path("/dear")
    @PreAuthorize("#person.name == authentication.principal.username")
    @Produces(MediaType.TEXT_PLAIN)
    @Consumes(MediaType.APPLICATION_JSON)
    public String greetPerson(Greeting person) {
        return "Hello, dear "+person.title +" "+person.name;
    }
}

DTO:

public class Greeting {

    public final String title;
    public final String name;

    public Greeting(String title, String name) {
        this.title = title;
        this.name = name;
    }

    public String getTitle() {
        return title;
    }

    public String getName() {
        return name;
    }
}

application.properties:

quarkus.security.users.embedded.enabled=true
quarkus.security.users.embedded.plain-text=true
quarkus.security.users.embedded.users.scott=jb0ss
quarkus.security.users.embedded.roles.scott=admin,user
quarkus.security.users.embedded.users.stuart=test
quarkus.security.users.embedded.roles.stuart=user,king

and two tests:

    @Test
    void legit() {
        given().auth().preemptive().basic("scott","jb0ss")
                .body(new Greeting("Mr", "scott"))
                .contentType(ContentType.JSON)
                .when().post("/hello/dear/")
                .then()
                .statusCode(200)
                .body(is("Hello, dear Mr scott"));
    }

    @Test
    void impostor() {
        given().auth().preemptive().basic("stuart","test")
                .body(new Greeting("Mr", "scott"))
                .contentType(ContentType.JSON)
                .when().post("/hello/dear")
                .then()
                .statusCode(403);
    }
  1. Run tests: mvn clean test. Request from a real person is accepted, request from the impostor is rejected.
  2. Change endpoint annotation to @PreAuthorize("#person.name != authentication.principal.username")
  3. Run tests again. Request from a real person is accepted, request from the impostor is rejected, while it should be vice versa

Output of uname -a or ver

6.5.12-300.fc39.x86_64

Output of java -version

17.0.8, vendor: Eclipse Adoptium

Quarkus version or git rev

38ac518

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.7 (b89d5959fcde851dcb1c8946a785a163f14e1e29)

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/securityarea/springIssues relating to the Spring integrationkind/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions