Skip to content
Draft
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 @@ -27,6 +27,8 @@
import io.micronaut.security.oauth2.endpoint.SecureEndpoint;
import io.micronaut.security.oauth2.endpoint.endsession.request.AuthorizationServer;
import io.micronaut.security.oauth2.grants.GrantType;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.Duration;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -117,10 +119,29 @@
* @throws ConfigurationException if token endpoint url is not set in configuration
*/
default SecureEndpoint getTokenEndpoint() throws ConfigurationException {
return getToken().map(secureEndpointConfiguration -> new DefaultSecureEndpoint(secureEndpointConfiguration, DEFAULT_AUTH_METHOD))
return getToken().map(secureEndpointConfiguration -> {
secureEndpointConfiguration.getUrl().ifPresent(this::validateTokenEndpointUrl);
return new DefaultSecureEndpoint(secureEndpointConfiguration, DEFAULT_AUTH_METHOD);
})
.orElseThrow(() -> new ConfigurationException("Oauth client " + getName() + " requires the token endpoint configuration to be set in configuration"));
}

private void validateTokenEndpointUrl(String url) {
try {
URI uri = new URI(url);
String scheme = uri.getScheme();
if (scheme == null || !(scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https")) || uri.getHost() == null) {
throw invalidTokenEndpointUrl(url);
}
} catch (URISyntaxException e) {

Check warning on line 136 in security-oauth2/src/main/java/io/micronaut/security/oauth2/configuration/OauthClientConfiguration.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "e" with an unnamed pattern.

See more on https://sonarcloud.io/project/issues?id=micronaut-projects_micronaut-security&issues=AZ9CW-WolAZOktJCHGSh&open=AZ9CW-WolAZOktJCHGSh&pullRequest=2245
throw invalidTokenEndpointUrl(url);
}
}

private ConfigurationException invalidTokenEndpointUrl(String url) {
return new ConfigurationException("Oauth client " + getName() + " has an invalid token endpoint URL configured for property [micronaut.security.oauth2.clients." + getName() + ".token.url]. The value must be an absolute http or https URL. Configured value: [" + url + "]");
}

/**
* @return The {@link AuthorizationServer} used by the OAuth Client.
* @since 4.15.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package io.micronaut.security.oauth2.configuration;

import io.micronaut.context.ApplicationContext;
import io.micronaut.context.annotation.Property;
import io.micronaut.context.exceptions.ConfigurationException;
import io.micronaut.inject.qualifiers.Qualifiers;
import io.micronaut.security.oauth2.configuration.endpoints.SecureEndpointConfiguration;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.junit.jupiter.api.Test;

import java.util.Map;

import static org.junit.jupiter.api.Assertions.*;

@Property(name = "micronaut.security.oauth2.clients.stravanew.scopes", value = "read")
Expand Down Expand Up @@ -45,4 +50,30 @@ void deprecatedAuthMethodConfigurationIsStillSupported() {
assertEquals("client_secret_post", tokenNewEndpoint.getAuthenticationMethod().get());
}

@Test
void validTokenEndpointUrlIsAccepted() {
assertEquals("https://www.strava.com/oauth/token", stravaNewConfiguration.getTokenEndpoint().getUrl());
}

@Test
void tokenEndpointUrlMustBeAbsoluteHttpUrl() {
assertInvalidTokenEndpointUrl("example.com/oauth/token");
assertInvalidTokenEndpointUrl("https:/example.com/oauth/token");
assertInvalidTokenEndpointUrl("/oauth/token");
assertInvalidTokenEndpointUrl("ftp://example.com/oauth/token");
}

private void assertInvalidTokenEndpointUrl(String url) {
try (ApplicationContext context = ApplicationContext.run(Map.of(
"micronaut.security.oauth2.clients.invalid.token.url", url,
"micronaut.security.oauth2.clients.invalid.client-id", "xxx",
"micronaut.security.oauth2.clients.invalid.client-secret", "yyy"))) {
OauthClientConfiguration configuration = context.getBean(OauthClientConfiguration.class, Qualifiers.byName("invalid"));

ConfigurationException exception = assertThrows(ConfigurationException.class, configuration::getTokenEndpoint);

assertEquals("Oauth client invalid has an invalid token endpoint URL configured for property [micronaut.security.oauth2.clients.invalid.token.url]. The value must be an absolute http or https URL. Configured value: [" + url + "]", exception.getMessage());
}
}

}
Loading