Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.micronaut.context.annotation.Parameter;
import io.micronaut.context.annotation.Requires;
import io.micronaut.security.oauth2.configuration.endpoints.AuthorizationEndpointConfiguration;
import io.micronaut.security.oauth2.configuration.endpoints.ClientAssertionConfiguration;
import io.micronaut.security.oauth2.configuration.endpoints.DefaultEndpointConfiguration;
import io.micronaut.security.oauth2.configuration.endpoints.DefaultSecureEndpointConfiguration;
import io.micronaut.security.oauth2.configuration.endpoints.EndSessionEndpointConfiguration;
Expand Down Expand Up @@ -495,8 +496,174 @@ public void setCodeChallengeMethod(@Nullable String codeChallengeMethod) {
* OAuth 2.0 token endpoint configuration.
*/
@ConfigurationProperties("token")
public static class TokenEndpointConfigurationProperties extends DefaultSecureEndpointConfiguration {
@Requires(classes = MediaType.class)
public static class TokenEndpointConfigurationProperties extends AbstractTokenEndpointConfigurationProperties {
/**
* JWT client assertion configuration for token endpoint authentication.
*
* @param clientAssertion JWT client assertion configuration
*/
public void setClientAssertion(@Nullable ClientAssertionConfigurationProperties clientAssertion) {
setClientAssertionConfiguration(clientAssertion);
}

/**
* JWT client assertion configuration.
*/
@ConfigurationProperties("client-assertion")
public static class ClientAssertionConfigurationProperties extends AbstractClientAssertionConfigurationProperties {
}
}

/**
* Shared token endpoint configuration.
*/
abstract static class AbstractTokenEndpointConfigurationProperties extends DefaultSecureEndpointConfiguration implements TokenEndpointConfiguration {
private static final MediaType DEFAULT_CONTENT_TYPE = MediaType.APPLICATION_FORM_URLENCODED_TYPE;

@NonNull
private MediaType contentType = DEFAULT_CONTENT_TYPE;

@Nullable
private ClientAssertionConfiguration clientAssertion;

@NonNull
@Override
public MediaType getContentType() {
return contentType;
}

/**
* The content type of token endpoint requests. Default value (application/x-www-form-urlencoded).
*
* @param contentType The content type
*/
public void setContentType(@NonNull MediaType contentType) {
this.contentType = contentType;
}

@NonNull
@Override
public Optional<ClientAssertionConfiguration> getClientAssertion() {
return Optional.ofNullable(clientAssertion);
}

void setClientAssertionConfiguration(@Nullable ClientAssertionConfiguration clientAssertion) {
this.clientAssertion = clientAssertion;
}
}

/**
* JWT client assertion configuration.
*/
public abstract static class AbstractClientAssertionConfigurationProperties implements ClientAssertionConfiguration {
@NonNull
private Duration lifetime = ClientAssertionConfiguration.DEFAULT_LIFETIME;

@Nullable
private String audience;

@Nullable
private String issuer;

@Nullable
private String subject;

@Nullable
private String signingAlgorithm;

@Nullable
private String signerName;

@NonNull
@Override
public Duration getLifetime() {
return lifetime;
}

/**
* JWT client assertion lifetime. Default value (5 minutes).
*
* @param lifetime JWT client assertion lifetime
*/
public void setLifetime(@NonNull Duration lifetime) {
this.lifetime = lifetime;
}

@NonNull
@Override
public Optional<String> getAudience() {
return Optional.ofNullable(audience);
}

/**
* JWT client assertion audience. Defaults to the token endpoint URL.
*
* @param audience JWT client assertion audience
*/
public void setAudience(@Nullable String audience) {
this.audience = audience;
}

@NonNull
@Override
public Optional<String> getIssuer() {
return Optional.ofNullable(issuer);
}

/**
* JWT client assertion issuer. Defaults to the OAuth client id.
*
* @param issuer JWT client assertion issuer
*/
public void setIssuer(@Nullable String issuer) {
this.issuer = issuer;
}

@NonNull
@Override
public Optional<String> getSubject() {
return Optional.ofNullable(subject);
}

/**
* JWT client assertion subject. Defaults to the OAuth client id.
*
* @param subject JWT client assertion subject
*/
public void setSubject(@Nullable String subject) {
this.subject = subject;
}

@NonNull
@Override
public Optional<String> getSigningAlgorithm() {
return Optional.ofNullable(signingAlgorithm);
}

/**
* JWS signing algorithm used for client_secret_jwt. Defaults to HS256.
*
* @param signingAlgorithm JWS signing algorithm
*/
public void setSigningAlgorithm(@Nullable String signingAlgorithm) {
this.signingAlgorithm = signingAlgorithm;
}

@NonNull
@Override
public Optional<String> getSignerName() {
return Optional.ofNullable(signerName);
}

/**
* Named SignatureGeneratorConfiguration bean used for private_key_jwt.
*
* @param signerName Named SignatureGeneratorConfiguration bean
*/
public void setSignerName(@Nullable String signerName) {
this.signerName = signerName;
}
}

/**
Expand Down Expand Up @@ -820,23 +987,21 @@ public void setAcrValues(@Nullable List<String> acrValues) {
*/
@ConfigurationProperties("token")
@Requires(classes = MediaType.class)
public static class TokenEndpointConfigurationProperties extends DefaultSecureEndpointConfiguration implements TokenEndpointConfiguration {
private static final MediaType DEFAULT_CONTENT_TYPE = MediaType.APPLICATION_FORM_URLENCODED_TYPE;
private MediaType contentType = DEFAULT_CONTENT_TYPE;

@NonNull
@Override
public MediaType getContentType() {
return this.contentType;
public static class TokenEndpointConfigurationProperties extends AbstractTokenEndpointConfigurationProperties {
/**
* JWT client assertion configuration for token endpoint authentication.
*
* @param clientAssertion JWT client assertion configuration
*/
public void setClientAssertion(@Nullable ClientAssertionConfigurationProperties clientAssertion) {
setClientAssertionConfiguration(clientAssertion);
}

/**
* The content type of token endpoint requests. Default value (application/x-www-form-urlencoded).
*
* @param contentType The content type
* JWT client assertion configuration.
*/
public void setContentType(@NonNull MediaType contentType) {
this.contentType = contentType;
@ConfigurationProperties("client-assertion")
public static class ClientAssertionConfigurationProperties extends AbstractClientAssertionConfigurationProperties {
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright 2017-2026 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.security.oauth2.configuration.endpoints;

import org.jspecify.annotations.NonNull;

import java.time.Duration;
import java.util.Optional;

/**
* JWT client assertion configuration for token endpoint authentication.
*
* @since 5.1.0
*/
public interface ClientAssertionConfiguration {

/**
* Default assertion lifetime.
*/
Duration DEFAULT_LIFETIME = Duration.ofMinutes(5);

/**
* Default JWS algorithm used for {@code client_secret_jwt}.
*/
String DEFAULT_SIGNING_ALGORITHM = "HS256";

/**
* @return The assertion lifetime.
*/
@NonNull
Duration getLifetime();

/**
* @return The optional assertion audience. Defaults to the token endpoint URL.
*/
@NonNull
Optional<String> getAudience();

/**
* @return The optional assertion issuer. Defaults to the OAuth client id.
*/
@NonNull
Optional<String> getIssuer();

/**
* @return The optional assertion subject. Defaults to the OAuth client id.
*/
@NonNull
Optional<String> getSubject();

/**
* @return The optional JWS signing algorithm used for {@code client_secret_jwt}.
*/
@NonNull
Optional<String> getSigningAlgorithm();

/**
* @return The optional signer bean name used for {@code private_key_jwt}.
*/
@NonNull
Optional<String> getSignerName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import org.jspecify.annotations.NonNull;
import io.micronaut.http.MediaType;

import java.util.Optional;

/**
* TokenEndpoint Configuration.
*
Expand All @@ -42,4 +44,13 @@ public interface TokenEndpointConfiguration extends SecureEndpointConfiguration
static TokenEndpointConfigurationBuilder builder() {
return new TokenEndpointConfigurationBuilder();
}

/**
* @return The optional JWT client assertion configuration.
* @since 5.1.0
*/
@NonNull
default Optional<ClientAssertionConfiguration> getClientAssertion() {
return Optional.empty();
}
}
Loading
Loading