spring-projects / spring-projects/spring-security

Authorization Granted Events sample cannot work as documented

Open
#19,584 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Summary

The Authorization Granted Events section documents a capability that SpringAuthorizationEventPublisher does not have. The sample also does not compile.

Source: docs/modules/ROOT/pages/servlet/authorization/events.adoc

The sample does not compile

@Bean
AuthorizationEventPublisher authorizationEventPublisher() {
    SpringAuthorizationEventPublisher eventPublisher = new SpringAuthorizationEventPublisher();
    eventPublisher.setShouldPublishEvent((result) -> { ... });
    return eventPublisher;
}

Two issues against main:

  1. new SpringAuthorizationEventPublisher() — the only constructor is SpringAuthorizationEventPublisher(ApplicationEventPublisher).
  2. setShouldPublishEvent(...) — the method is setShouldPublishResult(Predicate<AuthorizationResult>) (@since 7.0). It looks like the rename landed but the docs were not updated.

The bigger problem: the predicate cannot produce granted events

Even with both names corrected, the sample cannot do what the surrounding prose promises — "the following publisher only publishes authorization grants where ROLE_ADMIN was required".

publishAuthorizationEvent only ever constructs AuthorizationDeniedEvent:

public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
        @Nullable AuthorizationResult result) {
    if (result == null) {
        return;
    }
    if (!this.shouldPublishResult.test(result)) {
        return;
    }
    AuthorizationDeniedEvent<T> failure = new AuthorizationDeniedEvent<>(authentication, object, result);
    this.eventPublisher.publishEvent(failure);
}

AuthorizationGrantedEvent is imported but never instantiated. So a predicate that returns true for a granted result publishes an AuthorizationDeniedEvent carrying a granted AuthorizationResult, not an AuthorizationGrantedEvent. A listener on AuthorizationGrantedEvent never fires.

The class Javadoc agrees with the code, and contradicts the reference docs:

Because AuthorizationGrantedEvents typically require additional business logic to decide whether to publish, this implementation only publishes AuthorizationDeniedEvents.

I verified this empirically on 7.1.1: with a corrected predicate returning true for an AuthorityAuthorizationDecision where granted=true, a @RecordApplicationEvents test observed zero AuthorizationGrantedEvents. Implementing AuthorizationEventPublisher directly and publishing AuthorizationGrantedEvent works.

Possible resolutions

Either could be right, hence an issue rather than a PR:

  1. Docs-only — rewrite the section to say granted events require your own AuthorizationEventPublisher, and show that instead. Also fix the constructor and setShouldPublishResult name.
  2. Code — make SpringAuthorizationEventPublisher.publishAuthorizationEvent emit AuthorizationGrantedEvent when result.isGranted() and the predicate passes. That would make the existing documentation correct and give setShouldPublishResult an obvious purpose, since today it can only suppress denied events.

Happy to submit a PR for whichever direction you prefer.

Minor

The same page has a typo in the intro: "It comes publishes authorization events using Spring's ApplicationEventPublisher".

Context

Found while reconciling a Spring Security training lab against the 7.1 reference docs. Related but separate: #19583 fixes two non-compiling calls in the observability docs.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read docs/modules/ROOT/pages/servlet/authorization/events.adoc alongside SpringAuthorizationEventPublisher and its class Javadoc. Reproduce the corrected sample and verify behavior with a @RecordApplicationEvents test, then resolve whether the documented behavior or implementation is authoritative. Done means the sample compiles, the event behavior and prose agree, and the intro typo is fixed.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
backend, documentation, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.