-
Notifications
You must be signed in to change notification settings - Fork 0
🔒Enable Authentication #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
033c843
🔒Enable Authentication
hf-kklein 7c20429
restructure
hf-kklein a9aec36
format
hf-kklein d65118a
boms
hf-kklein f9c19ab
typo and docs
hf-kklein ec7deb8
reanme
hf-kklein 8704eea
more docs
hf-kklein 417c28e
try?
hf-kklein ac42692
so?
hf-kklein 39ae8c6
s
hf-kklein a6f80a3
better
hf-kklein 4c92dab
rename
hf-kklein be5fb8a
wip
hf-kklein File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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
33 changes: 33 additions & 0 deletions
33
TransformerBeeClient/TransformerBeeClient.IntegrationTest/GithubActionClientFixture.cs
This file contains hidden or 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,33 @@ | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using Xunit; | ||
|
|
||
| namespace TransformerBeeClient.IntegrationTest; | ||
|
|
||
| /// <summary> | ||
| /// A fixture that sets up the http client factory and an injectable service collection. | ||
| /// It's thought to be used in the Github action. | ||
| /// </summary> | ||
| public class GithubActionClientFixture : IClassFixture<GithubActionClientFixture> | ||
| { | ||
| public readonly IHttpClientFactory? HttpClientFactory; | ||
|
|
||
| public readonly ServiceCollection? ServiceCollection; | ||
|
|
||
| public readonly ITransformerBeeAuthenticator? AuthenticationProvider; | ||
|
|
||
| public GithubActionClientFixture() | ||
| { | ||
| var clientId = Environment.GetEnvironmentVariable("CLIENT_ID"); | ||
| var clientSecret = Environment.GetEnvironmentVariable("CLIENT_SECRET"); | ||
| if (clientSecret is null && clientId is null) | ||
| { | ||
| return; | ||
| } | ||
| var services = new ServiceCollection(); | ||
| services.AddHttpClient("TransformerBee", client => { client.BaseAddress = new Uri("http://transformerstage.utilibee.io"); }); | ||
| var serviceProvider = services.BuildServiceProvider(); | ||
| ServiceCollection = services; | ||
| HttpClientFactory = serviceProvider.GetService<IHttpClientFactory>(); | ||
| AuthenticationProvider = new ClientIdClientSecretAuthenticator(clientId: clientId, clientSecret: clientSecret); | ||
| } | ||
| } |
This file contains hidden or 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 hidden or 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 was deleted.
Oops, something went wrong.
136 changes: 136 additions & 0 deletions
136
TransformerBeeClient/TransformerBeeClient/ClientIdClientSecretAuthenticator.cs
This file contains hidden or 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,136 @@ | ||
| namespace TransformerBeeClient; | ||
|
|
||
| using System.Security.Authentication; | ||
| using IdentityModel.Client; | ||
| using System.IdentityModel.Tokens.Jwt; | ||
|
|
||
| /// <summary> | ||
| /// a <see cref="ITransformerBeeAuthenticator"/> that is based on a client secret and a client id | ||
| /// </summary> | ||
| public class ClientIdClientSecretAuthenticator : ITransformerBeeAuthenticator | ||
| { | ||
| protected const string Auth0Domain = "https://hochfrequenz.eu.auth0.com"; | ||
| protected const string TransformerBeeScope = "client:default"; | ||
| protected const string TransformerAudience = "https://transformer.bee"; | ||
|
|
||
| /// <summary> | ||
| /// JWT token | ||
| /// </summary> | ||
| private string? _token; | ||
|
|
||
| private readonly string? _clientSecret; | ||
| private readonly string? _clientId; | ||
|
|
||
| /// <summary> | ||
| /// true iff the client should use authentication | ||
| /// </summary> | ||
| private readonly bool _useAuthentication; | ||
|
|
||
| /// <summary> | ||
| /// <inheritdoc cref="ITransformerBeeAuthenticator.UseAuthentication"/> | ||
| /// </summary> | ||
| public bool UseAuthentication() => _useAuthentication; | ||
|
|
||
| /// <summary> | ||
| /// prevents us from requesting multiple tokens at the same time | ||
| /// </summary> | ||
| private readonly SemaphoreSlim _tokenRequestSemaphore = new(1, 1); | ||
|
|
||
| /// <summary>A <see cref="ITransformerBeeAuthenticator"/> that is based on a client secret and a client id</summary> | ||
| /// <param name="clientId">OAuth2 client secret (ask Hochfrequenz)</param> | ||
| /// <param name="clientSecret">OAuth2 client ID (ask Hochfrequenz)</param> | ||
| public ClientIdClientSecretAuthenticator(string? clientId, string? clientSecret) | ||
| { | ||
| if (!string.IsNullOrWhiteSpace(clientId) && string.IsNullOrWhiteSpace(clientSecret)) | ||
| { | ||
| throw new ArgumentNullException(nameof(clientSecret), $"If you provide a {nameof(clientId)} you must also provide a {nameof(clientSecret)}"); | ||
| } | ||
|
|
||
| if (!string.IsNullOrWhiteSpace(clientSecret) && string.IsNullOrWhiteSpace(clientId)) | ||
| { | ||
| throw new ArgumentNullException(nameof(clientId), $"If you provide a {nameof(clientSecret)} you must also provide a {nameof(clientId)}"); | ||
| } | ||
|
|
||
| _useAuthentication = !string.IsNullOrWhiteSpace(clientId) && !string.IsNullOrWhiteSpace(clientSecret); | ||
| if (_useAuthentication) | ||
| { | ||
| _clientId = clientId; | ||
| _clientSecret = clientSecret; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// returns true if the <see cref="token"/> will expire in the next 5 minutes | ||
| /// </summary> | ||
| /// <param name="token">jwt</param> | ||
| /// <returns>true if the token should be refreshed</returns> | ||
| private static bool TokenNeedsToBeRefreshed(string token) | ||
| { | ||
| ArgumentNullException.ThrowIfNull(token); | ||
| var handler = new JwtSecurityTokenHandler(); | ||
| var jwtToken = handler.ReadToken(token) as JwtSecurityToken; | ||
| if (jwtToken == null) return true; // Assume renewal if token cannot be read | ||
| var expiry = jwtToken.ValidTo; | ||
| // Consider a buffer to renew the token a bit before it actually expires | ||
| var buffer = TimeSpan.FromMinutes(5); | ||
| return DateTime.UtcNow.Add(buffer) >= expiry; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// gets the oauth2 discovery document from the respective auth0 domain | ||
| /// </summary> | ||
| /// <returns></returns> | ||
| /// <exception cref="AuthenticationException"></exception> | ||
| private static async Task<DiscoveryDocumentResponse> GetDiscoveryDocument(HttpClient client) | ||
| { | ||
| var discoveryDocument = await client.GetDiscoveryDocumentAsync(Auth0Domain); | ||
| if (discoveryDocument.IsError) | ||
| { | ||
| throw new AuthenticationException($"Could not get discovery document from auth0: {discoveryDocument.Error}"); | ||
| } | ||
|
|
||
| return discoveryDocument; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// fetch a token to talk to the transformer bee | ||
| /// </summary> | ||
| /// <returns>the token</returns> | ||
| /// <exception cref="AuthenticationException">if something goes wrong</exception> | ||
| public async Task<string> Authenticate(HttpClient client) | ||
| { | ||
| using (_tokenRequestSemaphore) | ||
| { | ||
| if (!UseAuthentication()) | ||
| { | ||
| throw new AuthenticationException("You must provide a client id and a client secret to the constructor to authenticate with the transformer bee"); | ||
| } | ||
|
|
||
| if (!string.IsNullOrWhiteSpace(_token) && !TokenNeedsToBeRefreshed(_token)) | ||
| { | ||
| return _token; | ||
| } | ||
|
|
||
| var discoveryDocument = await GetDiscoveryDocument(client); | ||
| var tokenRequest = new ClientCredentialsTokenRequest | ||
| { | ||
| Address = discoveryDocument.TokenEndpoint, | ||
| ClientId = _clientId!, | ||
| ClientSecret = _clientSecret!, | ||
| GrantType = "client_credentials", | ||
| Scope = TransformerBeeScope, | ||
| }; | ||
| tokenRequest.Parameters.AddOptional("audience", TransformerAudience); | ||
|
|
||
| var tokenResponse = await client.RequestClientCredentialsTokenAsync(tokenRequest); | ||
| if (tokenResponse.IsError) | ||
| { | ||
| throw new AuthenticationException($"Could not get token from auth0: {tokenResponse.Error}"); | ||
| } | ||
|
|
||
| _token = tokenResponse.AccessToken!; | ||
| } | ||
|
|
||
| return _token; | ||
| } | ||
| } |
This file contains hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
das kommt dan in #12