finalizare 1.0
This commit is contained in:
+129
-37
@@ -1,23 +1,30 @@
|
||||
using API.Middlewares;
|
||||
using System.Text;
|
||||
using API;
|
||||
using Domain;
|
||||
using Infrastructure;
|
||||
using Infrastructure.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Infrastructure.Services.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Configure Kestrel with certificate paths from appsettings.json
|
||||
StartupHelper.EnsureKeysGenerated(builder.Configuration, builder.Environment.ContentRootPath);
|
||||
StartupHelper.EnsureMongoDatabaseAndCollectionsExist(builder.Configuration);
|
||||
StartupHelper.EnsurePythonEnvironment(builder.Environment.ContentRootPath);
|
||||
|
||||
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
|
||||
{
|
||||
serverOptions.Configure(context.Configuration.GetSection("Kestrel"), reloadOnChange: true);
|
||||
serverOptions.Configure(context.Configuration.GetSection("Kestrel"), true);
|
||||
});
|
||||
|
||||
builder.Services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy("AllowAll",
|
||||
builder =>
|
||||
corsPolicyBuilder =>
|
||||
{
|
||||
builder.AllowAnyOrigin()
|
||||
corsPolicyBuilder.AllowAnyOrigin()
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyHeader()
|
||||
.WithExposedHeaders("*"); // This exposes all headers
|
||||
@@ -30,30 +37,124 @@ builder.Services.AddInfrastructureServices(builder.Configuration);
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen(c =>
|
||||
{
|
||||
// Add Bearer token authentication
|
||||
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||||
{
|
||||
Description = "JWT Authorization header using the Bearer scheme. Example: 'Authorization: Bearer {token}'",
|
||||
Name = "Authorization",
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.Http,
|
||||
Scheme = "Bearer"
|
||||
});
|
||||
|
||||
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "Bearer"
|
||||
},
|
||||
Scheme = "oauth2",
|
||||
Name = "Bearer",
|
||||
In = ParameterLocation.Header
|
||||
},
|
||||
new List<string>()
|
||||
}
|
||||
});
|
||||
|
||||
// Add API key authentication
|
||||
c.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme
|
||||
{
|
||||
Description = "ApiKey must appear in header",
|
||||
Description = "API key needed to access the endpoints. ApiKey must appear in header",
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
Name = "ApiKey",
|
||||
In = ParameterLocation.Header,
|
||||
Scheme = "ApiKeyScheme"
|
||||
});
|
||||
var key = new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "ApiKey"
|
||||
},
|
||||
In = ParameterLocation.Header
|
||||
};
|
||||
var requirement = new OpenApiSecurityRequirement
|
||||
});
|
||||
|
||||
// Apply the security to all Swagger documents
|
||||
c.AddSecurityRequirement(new OpenApiSecurityRequirement()
|
||||
{
|
||||
{ key, new List<string>() }
|
||||
};
|
||||
c.AddSecurityRequirement(requirement);
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "Bearer"
|
||||
},
|
||||
Scheme = "oauth2",
|
||||
Name = "Bearer",
|
||||
In = ParameterLocation.Header
|
||||
},
|
||||
new List<string>()
|
||||
},
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "ApiKey"
|
||||
},
|
||||
In = ParameterLocation.Header
|
||||
},
|
||||
new List<string>()
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
builder.Services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
})
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
options.Events = new JwtBearerEvents
|
||||
{
|
||||
OnAuthenticationFailed = context =>
|
||||
{
|
||||
Console.WriteLine("Authentication failed: " + context.Exception.Message);
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
Console.WriteLine("Token validated: " + context.SecurityToken);
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
OnChallenge = context =>
|
||||
{
|
||||
Console.WriteLine("OnChallenge error: " + context.ErrorDescription);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuerSigningKey = true,
|
||||
IssuerSigningKey =
|
||||
new SymmetricSecurityKey(Encoding.ASCII.GetBytes(builder.Configuration["Jwt:SecretKey"])),
|
||||
ValidateIssuer = true,
|
||||
ValidateAudience = true,
|
||||
ValidIssuer = builder.Configuration["Jwt:Issuer"],
|
||||
ValidAudience = builder.Configuration["Jwt:Audience"],
|
||||
ClockSkew = TimeSpan.Zero
|
||||
};
|
||||
})
|
||||
.AddScheme<AuthenticationSchemeOptions, ApiKeyAuthenticationHandler>("ApiKey", options => { });
|
||||
|
||||
builder.Services.AddAuthorizationBuilder()
|
||||
.AddPolicy(Policies.AdminPolicy, policy => { policy.RequireRole(UserRoles.Admin); })
|
||||
.AddPolicy(Policies.DoctorPolicy, policy => { policy.RequireRole(UserRoles.Admin, UserRoles.Doctor); })
|
||||
.AddPolicy(Policies.PatientPolicy, policy => { policy.RequireRole(UserRoles.Patient, UserRoles.Admin); })
|
||||
.AddPolicy(Policies.AuthenticatedPolicy,
|
||||
policy => { policy.RequireRole(UserRoles.Patient, UserRoles.Admin, UserRoles.Doctor); })
|
||||
.AddPolicy(Policies.ClientsOnlyPolicy, policy => { policy.RequireRole(UserRoles.Patient, UserRoles.Doctor); })
|
||||
.AddPolicy(Policies.AnonymousPolicy, policy => { policy.RequireAssertion(_ => true); });
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
@@ -63,25 +164,16 @@ if (app.Environment.IsDevelopment())
|
||||
}
|
||||
|
||||
app.UseCors("AllowAll");
|
||||
app.UseHttpsRedirection();
|
||||
app.MapControllers();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
// Middlewares
|
||||
app.UseMiddleware<ApiKeyMiddleware>();
|
||||
app.UseMiddleware<BodyCheckMiddleware>();
|
||||
app.UseMiddleware<JwtMiddleware>();
|
||||
app.MapControllers();
|
||||
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var services = scope.ServiceProvider;
|
||||
var dbContext = services.GetRequiredService<HealthcareManagerDatabase>(); // Directly resolving your DbContext
|
||||
EnsureDatabaseCreated(dbContext);
|
||||
StartupHelper.EnsureDatabaseCreated(dbContext);
|
||||
}
|
||||
|
||||
app.Run();
|
||||
|
||||
static void EnsureDatabaseCreated(HealthcareManagerDatabase dbContext)
|
||||
{
|
||||
// Checking for pending migrations is more efficient than applying migrations unconditionally
|
||||
if (dbContext.Database.GetPendingMigrations().Any()) dbContext.Database.Migrate();
|
||||
}
|
||||
app.Run();
|
||||
Reference in New Issue
Block a user