Verweise auf DigitalData.UserManager.Application und DigitalData.UserManager.Domain in DigitalData.UserManager.API.csproj entfernt. Ein Verweis auf DigitalData.UserManager.DependencyInjection wurde hinzugefügt, um die Architektur zu rationalisieren und die Verwaltung von Abhängigkeiten zu verbessern. Program.cs wurde aktualisiert, um den neuen Namespace für Dependency Injection für ein verbessertes Service-Management aufzunehmen.
221 lines
8.4 KiB
C#
221 lines
8.4 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using DigitalData.UserManager.Infrastructure.Repositories;
|
|
using DigitalData.UserManager.Application;
|
|
using DigitalData.Core.Application;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using NLog.Web;
|
|
using NLog;
|
|
using DigitalData.Core.API;
|
|
using DigitalData.UserManager.API.Controllers;
|
|
using DigitalData.UserManager.Application.Services;
|
|
using Microsoft.Data.SqlClient;
|
|
using Newtonsoft.Json;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using DigitalData.UserManager.Application.DTOs.User;
|
|
using DigitalData.UserManager.API.Models;
|
|
using DigitalData.Auth.Client;
|
|
using DigitalData.UserManager.API;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.Extensions.Options;
|
|
using DigitalData.Core.Abstractions.Security.Extensions;
|
|
using Microsoft.OpenApi.Models;
|
|
using DigitalData.UserManager.DependencyInjection;
|
|
|
|
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
|
|
logger.Debug("init main");
|
|
|
|
try {
|
|
var builder = WebApplication.CreateBuilder();
|
|
|
|
var config = builder.Configuration;
|
|
|
|
builder.Services.AddEncryptor(builder.Configuration.GetSection("EncryptionParameters"));
|
|
|
|
if (builder.Configuration.GetValue<bool>("RunAsWindowsService"))
|
|
builder.Host.UseWindowsService();
|
|
|
|
builder.Logging.ClearProviders();
|
|
builder.Host.UseNLog();
|
|
|
|
builder.Services.AddControllers(opt =>
|
|
{
|
|
opt.Conventions.Add(new RemoveIfControllerConvention()
|
|
.AndIf(c => c.ControllerName == nameof(EncryptionController).Replace("Controller", ""))
|
|
.AndIf(c => !config.GetValue<bool>("UseEncryptor")));
|
|
}).AddNewtonsoftJson(options =>
|
|
{
|
|
options.SerializerSettings.DateTimeZoneHandling = config.GetValue<DateTimeZoneHandling>("DateTimeZoneHandling");
|
|
});
|
|
|
|
if (builder.Configuration.GetValue<bool>("UseSwagger"))
|
|
{
|
|
builder.Services.AddEndpointsApiExplorer();
|
|
builder.Services.AddSwaggerGen();
|
|
}
|
|
|
|
builder.Services.AddControllers(opt =>
|
|
{
|
|
opt.Conventions.Add(new RemoveIfControllerConvention()
|
|
.AndIf(c => c.ControllerName == nameof(EncryptionController).Replace("Controller", ""))
|
|
.AndIf(c => !config.GetValue<bool>("UseEncryptor")));
|
|
});
|
|
|
|
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
|
.AddCookie(options =>
|
|
{
|
|
options.Cookie.HttpOnly = true; // Makes the cookie inaccessible to client-side scripts for security
|
|
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; // Ensures cookies are sent over HTTPS only
|
|
options.Cookie.SameSite = SameSiteMode.Strict; // Protects against CSRF attacks by restricting how cookies are sent with requests from external sites
|
|
options.LoginPath = "/api/auth/login";
|
|
options.LogoutPath = "/api/auth/logout";
|
|
});
|
|
|
|
// Once the app is built, the password will be decrypted with Encryptor. lazy loading also acts as a call back method.
|
|
Lazy<string>? cnn_str = null;
|
|
|
|
builder.Services.AddDbContext<UserManagerDbContext>(options => options.UseSqlServer(cnn_str!.Value).EnableSensitiveDataLogging());
|
|
|
|
var allowedOrigins = builder.Configuration.GetSection("AllowedOrigins").Get<string[]>() ?? throw new InvalidOperationException("In appsettings there is no allowed origin.");
|
|
|
|
builder.Services.AddCors(options =>
|
|
{
|
|
options.AddPolicy(name: "DefaultCorsPolicy",
|
|
builder =>
|
|
{
|
|
builder.WithOrigins(allowedOrigins)
|
|
.AllowAnyMethod()
|
|
.AllowAnyHeader()
|
|
.AllowCredentials();
|
|
});
|
|
});
|
|
|
|
//builder.Services.AddAutoMapper(typeof(DirectoryMappingProfile).Assembly);
|
|
builder.Services.AddUserManager<UserManagerDbContext>();
|
|
|
|
builder.ConfigureBySection<DirectorySearchOptions>();
|
|
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)
|
|
});
|
|
|
|
var lazyProvider = new LazyServiceProvider();
|
|
|
|
builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams"));
|
|
|
|
var authTokenKeys = config.GetSection(nameof(AuthTokenKeys)).Get<AuthTokenKeys>() ?? new();
|
|
|
|
builder.Services
|
|
.AddAuthentication(options =>
|
|
{
|
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
})
|
|
.AddJwtBearer(opt =>
|
|
{
|
|
opt.TokenValidationParameters = new TokenValidationParameters
|
|
{
|
|
ValidateIssuerSigningKey = true,
|
|
IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) =>
|
|
{
|
|
var clientParams = lazyProvider.GetRequiredService<IOptions<ClientParams>>()?.Value;
|
|
var publicKey = clientParams!.PublicKeys.Get(authTokenKeys.Issuer, authTokenKeys.Audience);
|
|
return new List<SecurityKey>() { publicKey.SecurityKey };
|
|
},
|
|
ValidateIssuer = true,
|
|
ValidIssuer = authTokenKeys.Issuer,
|
|
ValidateAudience = true,
|
|
ValidAudience = authTokenKeys.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.AddSwaggerGen(setupAct =>
|
|
{
|
|
setupAct.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
|
{
|
|
Description = "JWT Authorization header using the Bearer scheme. Example: \"Bearer {token}\"",
|
|
Name = "Authorization",
|
|
In = ParameterLocation.Header,
|
|
Type = SecuritySchemeType.Http,
|
|
Scheme = "Bearer"
|
|
});
|
|
|
|
setupAct.AddSecurityRequirement(new OpenApiSecurityRequirement
|
|
{
|
|
{
|
|
new OpenApiSecurityScheme
|
|
{
|
|
Reference = new OpenApiReference
|
|
{
|
|
Type = ReferenceType.SecurityScheme,
|
|
Id = "Bearer"
|
|
}
|
|
},
|
|
Array.Empty<string>()
|
|
}
|
|
});
|
|
});
|
|
|
|
builder.Services.AddCookieBasedLocalizer();
|
|
|
|
var app = builder.Build();
|
|
|
|
lazyProvider.Factory = () => app.Services;
|
|
|
|
cnn_str = new(() =>
|
|
{
|
|
var encryptor = app.Services.GetRequiredService<Encryptor>();
|
|
var eCnnStr = config.GetConnectionString("UM_DEF") ?? throw new InvalidOperationException("Connection string 'DD_ECM_Connection' is missing from the configuration.");
|
|
|
|
SqlConnectionStringBuilder cnnStrBuilder = new(eCnnStr);
|
|
cnnStrBuilder.UserID = encryptor.Decrypt(cnnStrBuilder.UserID);
|
|
cnnStrBuilder.Password = encryptor.Decrypt(cnnStrBuilder.Password);
|
|
var dCnnStr = cnnStrBuilder.ConnectionString;
|
|
return dCnnStr;
|
|
});
|
|
|
|
app.UseCors("DefaultCorsPolicy");
|
|
|
|
if (builder.Configuration.GetValue<bool>("UseSwagger"))
|
|
{
|
|
app.UseSwagger();
|
|
app.UseSwaggerUI();
|
|
}
|
|
|
|
app.UseCookieBasedLocalizer("de-DE", "en-US");
|
|
|
|
app.UseDefaultFiles();
|
|
app.UseStaticFiles();
|
|
|
|
app.UseRouting();
|
|
app.UseHttpsRedirection();
|
|
app.UseAuthentication();
|
|
app.UseAuthorization();
|
|
|
|
app.MapControllers();
|
|
|
|
app.MapDefaultControllerRoute();
|
|
|
|
app.Run();
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
logger.Error(exception, "Stopped program because of exception");
|
|
throw;
|
|
} |