128 lines
4.9 KiB
C#
128 lines
4.9 KiB
C#
using WorkFlow.Application;
|
|
using DigitalData.UserManager.Application;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using WorkFlow.Infrastructure;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using DigitalData.Core.API;
|
|
using DigitalData.Core.Application;
|
|
using DigitalData.UserManager.Application.DTOs.User;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using WorkFlow.API.Models;
|
|
using NLog;
|
|
using NLog.Web;
|
|
using WorkFlow.API.Extensions;
|
|
using WorkFlow.API.Filters;
|
|
using Microsoft.OpenApi.Models;
|
|
using DigitalData.Auth.Client;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
|
|
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
|
|
logger.Info("Logging initialized.");
|
|
|
|
try
|
|
{
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
var config = builder.Configuration;
|
|
|
|
// Add NLogger
|
|
builder.Logging.ClearProviders();
|
|
builder.Host.UseNLog();
|
|
|
|
// Add services to the container
|
|
var cnn_str = config.GetConnectionString("Default") ?? throw new("Default connection string not found.");
|
|
builder.Services.AddDbContext<WFDBContext>(options => options.UseSqlServer(cnn_str).EnableDetailedErrors());
|
|
builder.Services.AddWorkFlow().AddUserManager<WFDBContext>();
|
|
builder.Services.AddCookieBasedLocalizer();
|
|
builder.Services.AddDirectorySearchService(config.GetSection("DirectorySearchOptions"));
|
|
builder.Services.AddJWTService<UserReadDto>(user => new SecurityTokenDescriptor()
|
|
{
|
|
Claims = user.ToClaimList().ToDictionary(claim => claim.Type, claim => claim.Value as object)
|
|
});
|
|
|
|
bool disableAPIKeyAuth = config.GetValue<bool>("DisableAPIKeyAuth") && builder.IsDevOrDiP();
|
|
if (disableAPIKeyAuth)
|
|
builder.Services.AddAPIKeyAuth(new APIKeyAuthOptions());
|
|
else
|
|
if (config.GetSection("APIKeyAuth").Get<APIKeyAuthOptions>() is APIKeyAuthOptions options)
|
|
builder.Services.AddAPIKeyAuth(options);
|
|
else
|
|
throw new("The API Key Authorization configuration is not available in the app settings, even though the app is not in development or DiP mode and API Key Authorization is not disabled.");
|
|
|
|
// Created separately from AuthClientParams (added via options) for use in Jwt Bearer configuration
|
|
var authPublicKey = config.GetSection("AuthPublicKey").Get<ClientPublicKey>() ?? throw new InvalidOperationException("The AuthPublicKey configuration is missing or invalid.");
|
|
|
|
builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams"), opt => opt.PublicKeys.Add(authPublicKey));
|
|
|
|
builder.Services.AddControllers();
|
|
|
|
var authTokenKeys = config.GetSection(nameof(AuthTokenKeys)).Get<AuthTokenKeys>() ?? new();
|
|
|
|
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
|
.AddJwtBearer(opt =>
|
|
{
|
|
opt.TokenValidationParameters = new TokenValidationParameters
|
|
{
|
|
ValidateIssuerSigningKey = true,
|
|
IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) =>
|
|
{
|
|
return [authPublicKey.SecurityKey];
|
|
},
|
|
ValidateIssuer = true,
|
|
ValidIssuer = authPublicKey.Issuer,
|
|
ValidateAudience = true,
|
|
ValidAudience = authPublicKey.Audience,
|
|
};
|
|
|
|
opt.Events = new JwtBearerEvents
|
|
{
|
|
OnMessageReceived = context =>
|
|
{
|
|
// if there is no token read related cookie or query string
|
|
if (context.Token is null) // if there is no token
|
|
{
|
|
if (context.Request.Cookies.TryGetValue(authTokenKeys.Cookie, out var cookieToken) && cookieToken is not null)
|
|
context.Token = cookieToken;
|
|
else if (context.Request.Query.TryGetValue(authTokenKeys.QueryString, out var queryStrToken))
|
|
context.Token = queryStrToken;
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
};
|
|
});
|
|
|
|
builder.Services.AddEndpointsApiExplorer();
|
|
builder.Services.AddSwaggerGen(setupAct =>
|
|
{
|
|
if (!disableAPIKeyAuth)
|
|
setupAct.OperationFilter<APIKeyAuthHeaderOpFilter>();
|
|
|
|
if (config.GetSection("OpenApiInfo").Get<OpenApiInfo>() is OpenApiInfo openApiInfo)
|
|
setupAct.SwaggerDoc(openApiInfo?.Version ?? "v1", openApiInfo);
|
|
});
|
|
|
|
var app = builder.Build();
|
|
|
|
// Configure the HTTP request pipeline.
|
|
if (app.IsDevOrDiP() && app.Configuration.GetValue<bool>("EnableSwagger"))
|
|
{
|
|
app.UseSwagger();
|
|
app.UseSwaggerUI();
|
|
}
|
|
|
|
app.UseHttpsRedirection();
|
|
|
|
app.UseAuthentication();
|
|
|
|
app.UseAuthorization();
|
|
|
|
app.UseCookieBasedLocalizer("de-DE");
|
|
|
|
app.MapControllers();
|
|
|
|
app.Run();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error(ex, "Stopped program because of exception.");
|
|
throw;
|
|
} |