Skip to content

Make OAuth2AuthorizationConsent customizable #436

@fwollsch

Description

@fwollsch

Expected Behavior
When sending additional parameters from a consent-form, these additional parameters should by accessable by User-Code.
The OAuth2AuthorizationConsent should be customizable by a user-definable component before being passed to the OAuth2AuthorizationService.

Current Behavior
When sending additional parameters from a consent-form, these additional parameters are present inside the OAuth2AuthorizationCodeRequestAuthenticationToken.
The OAuth2AuthorizationConsent is created only using the authorized scopes.

Context
In my OAuth2-Server, a user can create multiple entities.
On the consent-page, the user can review all requested scopes and select which of its entities the client should be given access to.

My consent-page HTML looks like this:

<form method="post" th:action="@{/oauth2/authorize}">
    <input type="hidden" name="client_id" th:value="${clientId}" />
    <input type="hidden" name="state" th:value="${state}" />

    <div th:each="entity : ${entities}">
        <p>
            <input type="checkbox" th:name="${'entity:' + entity.id}" th:text="${entity.displayName}" checked />
        </p>
    </div>

    <hr />

    <div th:each="scope : ${scopes}">
        <input type="hidden" name="scope" th:value="${scope}" />
        <p th:text="${scope}"></p>
    </div>

    <button type="submit">Submit</button>
    <!--<button type="reset">Cancel</button>-->
</form>

I need some way to know which entities have been selected by the user on the consent-page.
In my case, all selected entity-ids are present in the OAuth2AuthorizationCodeRequestAuthenticationToken.getAdditionalParameters(), but these are never passed to any User-Code.

Ideally, I'd like to customize the OAuth2AuthorizationConsent before it's being passed to the OAuth2AuthorizationService with access to the additional parameters.

As a workaround, I currently use a custom OAuth2AuthorizationCodeRequestAuthenticationProvider:

    private static final ThreadLocal<Map<String, Object>> ADDITIONAL_PARAMETERS = new ThreadLocal<>();

    public CustomOAuth2AuthorizationCodeRequestAuthenticationProvider(RegisteredClientRepository registeredClientRepository, OAuth2AuthorizationService authorizationService, OAuth2AuthorizationConsentService authorizationConsentService) {
        super(registeredClientRepository, authorizationService, authorizationConsentService);
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        final OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication = (OAuth2AuthorizationCodeRequestAuthenticationToken) authentication;
        final Map<String, Object> additionalParameters = authorizationCodeRequestAuthentication.getAdditionalParameters();

        ADDITIONAL_PARAMETERS.set(additionalParameters);
        try {
            return super.authenticate(authorizationCodeRequestAuthentication);
        } finally {
            ADDITIONAL_PARAMETERS.remove();
        }
    }

    public static <T> T getAdditionalParameter(String key) {
        final Map<String, Object> additionalParameters = ADDITIONAL_PARAMETERS.get();
        if (additionalParameters == null) {
            throw new IllegalStateException();
        }

        return (T) additionalParameters.get(key);
    }

Side Nodes
The additionalParameters are currently created by passing all Request-Parameters that are not explicitly known (such as scope, client_id and state), but only the first value is actually added to the additionalParameters.

This requires my consent-page to send each selected entity using a different name (like in the example HTML above).
Ideally, I would like to use one name (for example "entity") and send the selected entities with their id as a value (like it works with scope at the moment).

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions