first commit
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using OpenWarehouse.auth.Common.ApiInterfeiceLib;
|
||||
using OpenWarehouse.auth.lib.Model.Auth;
|
||||
using OpenWarehouse.auth.lib.Model.WellKnow;
|
||||
|
||||
namespace OpenWarehouse.Common.Lib;
|
||||
|
||||
public static class AddAuthServices
|
||||
{
|
||||
public static async Task<T> AddAuthService<T>(this T builder, string authUrl, ILogger logger)
|
||||
where T : IHostApplicationBuilder
|
||||
{
|
||||
var jwks = await builder.GetKey(authUrl, logger);
|
||||
var conf = await builder.GetConfig(authUrl, logger);
|
||||
|
||||
var jwk = jwks.Keys[0];
|
||||
|
||||
var rsaParameters = new RSAParameters
|
||||
{
|
||||
Modulus = Base64UrlEncoder.DecodeBytes(jwk.N),
|
||||
Exponent = Base64UrlEncoder.DecodeBytes(jwk.E)
|
||||
};
|
||||
|
||||
builder.Services.AddSingleton(_ =>
|
||||
{
|
||||
var rsa = RSA.Create();
|
||||
rsa.ImportParameters(rsaParameters);
|
||||
return rsa;
|
||||
});
|
||||
|
||||
builder.Services.AddSingleton<RsaSecurityKey>(provider =>
|
||||
{
|
||||
var rsa = provider.GetRequiredService<RSA>();
|
||||
return new RsaSecurityKey(rsa) { KeyId = jwk.Kid };
|
||||
});
|
||||
|
||||
builder.Services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
})
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
var rsaSecurityKey = builder.Services.BuildServiceProvider().GetRequiredService<RsaSecurityKey>();
|
||||
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuerSigningKey = true,
|
||||
IssuerSigningKey = rsaSecurityKey,
|
||||
TokenDecryptionKey =
|
||||
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:AesKey"] ?? "")),
|
||||
ValidateIssuer = true,
|
||||
ValidIssuer = conf.Issuer,
|
||||
ValidateAudience = true,
|
||||
ValidAudience = builder.Configuration["Jwt:Audience"],
|
||||
ValidateLifetime = true,
|
||||
SaveSigninToken = true
|
||||
};
|
||||
options.Events = new JwtBearerEvents
|
||||
{
|
||||
OnTokenValidated = async context =>
|
||||
{
|
||||
var client = new OpenWarehouseAuthClient(authUrl, new HttpClient());
|
||||
context.Request.Headers.TryGetValue("Authorization", out var token);
|
||||
var result = await client.TokenIsLockAsync(new TokenAskIfIsLockModel { Token = token });
|
||||
if (result)
|
||||
{
|
||||
context.Fail("This token has been revoked.");
|
||||
}
|
||||
},
|
||||
OnAuthenticationFailed = context =>
|
||||
{
|
||||
logger.LogError("Authentication failed: {Exception}", context.Exception);
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
private static async Task<OpenIdConfiguration> GetConfig<T>(this T builder, string url, ILogger logger)
|
||||
where T : IHostApplicationBuilder
|
||||
{
|
||||
try
|
||||
{
|
||||
logger.LogInformation("Requesting OICD from: {Url}", url);
|
||||
|
||||
using var httpClient = new HttpClient();
|
||||
var client = new OpenWarehouseAuthClient(url, httpClient);
|
||||
|
||||
var result = await client.OpenidConfigurationAsync();
|
||||
|
||||
logger.LogInformation("Successfully retrieved OICD from: {Url}", url);
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Failed to retrieve OICD from: {Url}", url);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<JwksResponse> GetKey<T>(this T builder, string url, ILogger logger)
|
||||
where T : IHostApplicationBuilder
|
||||
{
|
||||
try
|
||||
{
|
||||
logger.LogInformation("Requesting JWKS from: {Url}", url);
|
||||
|
||||
using var httpClient = new HttpClient();
|
||||
var client = new OpenWarehouseAuthClient(url, httpClient);
|
||||
|
||||
var result = await client.JwksAsync();
|
||||
|
||||
logger.LogInformation("Successfully retrieved JWKS from: {Url}", url);
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Failed to retrieve JWKS from: {Url}", url);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace OpenWarehouse.Common.Lib;
|
||||
|
||||
public static class BuildLogger
|
||||
{
|
||||
public static ILogger GetBuildLogger<T>(this T builder)
|
||||
where T : IHostApplicationBuilder
|
||||
{
|
||||
using var loggerFactory = LoggerFactory.Create(loggingBuilder => loggingBuilder
|
||||
.SetMinimumLevel(LogLevel.Information)
|
||||
.AddConsole());
|
||||
|
||||
ILogger logger = loggerFactory.CreateLogger<T>();
|
||||
|
||||
|
||||
return logger;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Abstractions" Version="8.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Extensions.Logging.Abstractions">
|
||||
<HintPath>..\..\..\..\..\Program Files\dotnet\shared\Microsoft.AspNetCore.App\8.0.10\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenWarehouse.auth.lib\OpenWarehouse.auth.lib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,49 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OpenWarehouse.auth.Common.ApiInterfeiceLib;
|
||||
|
||||
namespace OpenWarehouse.auth.lib;
|
||||
|
||||
public static class Waiter
|
||||
{
|
||||
public static async Task<T> WaitForAut<T>(this T build, string? url, ILogger? logger)
|
||||
where T : IHostApplicationBuilder
|
||||
{
|
||||
|
||||
if (logger == null)
|
||||
throw new NullReferenceException();
|
||||
|
||||
var client = new OpenWarehouseAuthClient(url, new HttpClient());
|
||||
|
||||
var i = 0;
|
||||
while(true)
|
||||
{
|
||||
try
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var result = await client.PingAsync();
|
||||
|
||||
logger.LogInformation(
|
||||
$"Auth connected with Ping: {(DateTime.FromBinary(result.Time) - now).TotalMilliseconds}");
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (i < 10)
|
||||
{
|
||||
++i;
|
||||
logger.LogDebug($"Try {i} connect to auth fail.");
|
||||
Thread.Sleep(10000);
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
logger.LogError($"Problem with auth service. \n " +
|
||||
$"Mess: {e.Message}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return build;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user