-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add possibility of authorization to AsyncHttpRegistryClient; implemen…
…t OAuth2TokenProvider; authorization can be configured with properties under edison.serviceregistry.security.oauth2 Co-authored-by: Jan Schawo <[email protected]> Co-authored-by: Yannik Rudolph <[email protected]>
- Loading branch information
1 parent
3cf805a
commit fd5deea
Showing
13 changed files
with
451 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
...in/java/de/otto/edison/registry/configuration/ServiceRegistrySecurityOAuthProperties.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package de.otto.edison.registry.configuration; | ||
|
||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
import org.springframework.boot.context.properties.bind.DefaultValue; | ||
|
||
@ConfigurationProperties(prefix = "edison.serviceregistry.security.oauth2") | ||
public record ServiceRegistrySecurityOAuthProperties(@DefaultValue("false") boolean enabled, | ||
String tokenEndpoint, | ||
String clientId, | ||
String clientSecret, | ||
@DefaultValue("10") int timeoutSeconds) { | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
edison-core/src/main/java/de/otto/edison/registry/security/OAuth2TokenException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package de.otto.edison.registry.security; | ||
|
||
public class OAuth2TokenException extends Exception { | ||
|
||
public OAuth2TokenException() { | ||
super("Error while fetching access token"); | ||
} | ||
|
||
} |
58 changes: 58 additions & 0 deletions
58
edison-core/src/main/java/de/otto/edison/registry/security/OAuth2TokenProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package de.otto.edison.registry.security; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.http.HttpStatus; | ||
|
||
import java.net.URI; | ||
import java.net.http.HttpClient; | ||
import java.net.http.HttpRequest; | ||
import java.net.http.HttpResponse; | ||
import java.time.Duration; | ||
import java.util.concurrent.ExecutionException; | ||
|
||
public class OAuth2TokenProvider { | ||
|
||
private static final Logger LOG = LoggerFactory.getLogger(OAuth2TokenProvider.class); | ||
private final HttpClient httpClient; | ||
private final ObjectMapper objectMapper; | ||
private final String clientId; | ||
private final String clientSecret; | ||
private final String tokenEndpoint; | ||
private final int timeoutSeconds; | ||
|
||
public OAuth2TokenProvider(final String clientId, | ||
final String clientSecret, | ||
final String tokenEndpoint, | ||
final int timeoutSeconds) { | ||
this.httpClient = HttpClient.newBuilder().build(); | ||
this.clientId = clientId; | ||
this.clientSecret = clientSecret; | ||
this.tokenEndpoint = tokenEndpoint; | ||
this.timeoutSeconds = timeoutSeconds; | ||
this.objectMapper = new ObjectMapper(); | ||
} | ||
|
||
public String getAccessToken() throws ExecutionException, InterruptedException, JsonProcessingException, OAuth2TokenException { | ||
try { | ||
final HttpResponse<String> response = httpClient | ||
.sendAsync(HttpRequest.newBuilder() | ||
.timeout(Duration.ofSeconds(timeoutSeconds)) | ||
.POST(HttpRequest.BodyPublishers.ofString("grant_type=client_credentials&client_id=" + clientId + "&client_secret=" + clientSecret)) | ||
.uri(URI.create(tokenEndpoint)) | ||
.header("Accept", "application/json") | ||
.header("Content-Type", "application/x-www-form-urlencoded") | ||
.build(), HttpResponse.BodyHandlers.ofString()) | ||
.get(); | ||
if (response.statusCode() != HttpStatus.OK.value()) { | ||
throw new OAuth2TokenException(); | ||
} | ||
return objectMapper.readValue(response.body(), OAuth2TokenResponse.class).accessToken(); | ||
} catch (final Exception e) { | ||
LOG.error("Error fetching access token", e); | ||
throw e; | ||
} | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
edison-core/src/main/java/de/otto/edison/registry/security/OAuth2TokenProviderFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package de.otto.edison.registry.security; | ||
|
||
import de.otto.edison.registry.configuration.ServiceRegistrySecurityOAuthProperties; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
@EnableConfigurationProperties(ServiceRegistrySecurityOAuthProperties.class) | ||
public class OAuth2TokenProviderFactory { | ||
|
||
private final ServiceRegistrySecurityOAuthProperties properties; | ||
|
||
@Autowired | ||
public OAuth2TokenProviderFactory(final ServiceRegistrySecurityOAuthProperties properties) { | ||
this.properties = properties; | ||
} | ||
|
||
public OAuth2TokenProvider create() { | ||
return new OAuth2TokenProvider(properties.clientId(), properties.clientSecret(), properties.tokenEndpoint(), properties.timeoutSeconds()); | ||
} | ||
|
||
public boolean isEnabled() { | ||
return properties.enabled(); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
edison-core/src/main/java/de/otto/edison/registry/security/OAuth2TokenResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package de.otto.edison.registry.security; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
|
||
public record OAuth2TokenResponse(@JsonProperty("access_token") String accessToken) { | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
edison-core/src/test/java/de/otto/edison/acceptance/SpringTestBaseWithComponentScan.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package de.otto.edison.acceptance; | ||
|
||
import org.springframework.context.annotation.ComponentScan; | ||
|
||
import de.otto.edison.testsupport.applicationdriver.SpringTestBase; | ||
@ComponentScan(basePackages = {"de.otto.edison"}) | ||
public class SpringTestBaseWithComponentScan extends SpringTestBase { | ||
|
||
} |
35 changes: 35 additions & 0 deletions
35
...e/src/test/java/de/otto/edison/acceptance/registry/OAuth2TokenProviderAcceptanceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package de.otto.edison.acceptance.registry; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertFalse; | ||
import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.test.context.ActiveProfiles; | ||
import org.springframework.test.context.junit.jupiter.SpringExtension; | ||
|
||
import de.otto.edison.acceptance.SpringTestBaseWithComponentScan; | ||
import de.otto.edison.registry.client.AsyncHttpRegistryClient; | ||
import de.otto.edison.registry.configuration.ServiceRegistrySecurityOAuthProperties; | ||
|
||
@ExtendWith(SpringExtension.class) | ||
@SpringBootTest(classes = {SpringTestBaseWithComponentScan.class}) | ||
@ActiveProfiles("test") | ||
public class OAuth2TokenProviderAcceptanceTest { | ||
@Autowired | ||
private ServiceRegistrySecurityOAuthProperties serviceRegistrySecurityOAuthProperties; | ||
|
||
@Autowired | ||
private AsyncHttpRegistryClient asyncHttpRegistryClient; | ||
|
||
@Test | ||
public void shouldInstantiateRegistryClientWithoutExistingProperties() { | ||
// then | ||
assertNotNull(asyncHttpRegistryClient); | ||
assertFalse(serviceRegistrySecurityOAuthProperties.enabled()); | ||
assertEquals(serviceRegistrySecurityOAuthProperties.timeoutSeconds(), 10); | ||
} | ||
} |
Oops, something went wrong.