181 lines
6.9 KiB
C#
181 lines
6.9 KiB
C#
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using FluentValidation;
|
|
using FluentValidation.AspNetCore;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.IdentityModel.JsonWebTokens;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using WatchIt.Database;
|
|
using WatchIt.WebAPI.Services.Controllers.Accounts;
|
|
using WatchIt.WebAPI.Services.Controllers.Genres;
|
|
using WatchIt.WebAPI.Services.Controllers.Media;
|
|
using WatchIt.WebAPI.Services.Controllers.Movies;
|
|
using WatchIt.WebAPI.Services.Controllers.Persons;
|
|
using WatchIt.WebAPI.Services.Controllers.Photos;
|
|
using WatchIt.WebAPI.Services.Controllers.Series;
|
|
using WatchIt.WebAPI.Services.Utility.Configuration;
|
|
using WatchIt.WebAPI.Services.Utility.Tokens;
|
|
using WatchIt.WebAPI.Services.Utility.User;
|
|
using WatchIt.WebAPI.Validators;
|
|
using WatchIt.WebAPI.WorkerServices;
|
|
|
|
namespace WatchIt.WebAPI;
|
|
|
|
public static class Program
|
|
{
|
|
#region PUBLIC METHODS
|
|
|
|
public static void Main(string[] args)
|
|
{
|
|
WebApplication app = WebApplication.CreateBuilder(args)
|
|
.SetupAuthentication()
|
|
.SetupDatabase()
|
|
.SetupWorkerServices()
|
|
.SetupServices()
|
|
.SetupApplication()
|
|
.Build();
|
|
|
|
using (IServiceScope scope = app.Services.CreateScope())
|
|
{
|
|
scope.ServiceProvider.GetService<DatabaseContext>().Database.Migrate();
|
|
}
|
|
|
|
if (app.Environment.IsDevelopment())
|
|
{
|
|
app.UseSwagger();
|
|
app.UseSwaggerUI();
|
|
}
|
|
|
|
app.UseHttpsRedirection();
|
|
|
|
app.UseAuthentication();
|
|
app.UseAuthorization();
|
|
|
|
app.MapControllers();
|
|
|
|
app.Run();
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region PRIVATE METHODS
|
|
|
|
private static WebApplicationBuilder SetupAuthentication(this WebApplicationBuilder builder)
|
|
{
|
|
JsonWebTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
|
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
|
|
|
AuthenticationBuilder authenticationBuilder = builder.Services.AddAuthentication(x =>
|
|
{
|
|
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
});
|
|
authenticationBuilder.AddJwtBearer(x =>
|
|
{
|
|
x.RequireHttpsMetadata = false;
|
|
x.SaveToken = true;
|
|
x.TokenValidationParameters = new TokenValidationParameters
|
|
{
|
|
ValidateIssuerSigningKey = true,
|
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration.GetValue<string>("Authentication:Key")!)),
|
|
ValidateAudience = true,
|
|
ValidAudience = "access",
|
|
ValidIssuer = builder.Configuration.GetValue<string>("Authentication:Issuer"),
|
|
ValidateLifetime = true,
|
|
ClockSkew = TimeSpan.FromMinutes(1),
|
|
};
|
|
x.Events = new JwtBearerEvents
|
|
{
|
|
OnAuthenticationFailed = context =>
|
|
{
|
|
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
|
|
{
|
|
context.Response.Headers.Append("Token-Expired", "true");
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
},
|
|
};
|
|
});
|
|
authenticationBuilder.AddJwtBearer("refresh", x =>
|
|
{
|
|
x.RequireHttpsMetadata = false;
|
|
x.SaveToken = true;
|
|
x.TokenValidationParameters = new TokenValidationParameters
|
|
{
|
|
ValidateIssuerSigningKey = true,
|
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration.GetValue<string>("Authentication:Key")!)),
|
|
ValidateAudience = true,
|
|
ValidIssuer = builder.Configuration.GetValue<string>("Authentication:Issuer"),
|
|
ValidAudience = "refresh",
|
|
ValidateLifetime = true,
|
|
ClockSkew = TimeSpan.FromMinutes(1)
|
|
};
|
|
x.Events = new JwtBearerEvents
|
|
{
|
|
OnAuthenticationFailed = context =>
|
|
{
|
|
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
|
|
{
|
|
context.Response.Headers.Append("Token-Expired", "true");
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
};
|
|
});
|
|
builder.Services.AddAuthorization();
|
|
|
|
return builder;
|
|
}
|
|
|
|
private static WebApplicationBuilder SetupDatabase(this WebApplicationBuilder builder)
|
|
{
|
|
builder.Services.AddDbContext<DatabaseContext>(x => x.UseLazyLoadingProxies().UseNpgsql(builder.Configuration.GetConnectionString("Default")), ServiceLifetime.Transient);
|
|
return builder;
|
|
}
|
|
|
|
private static WebApplicationBuilder SetupWorkerServices(this WebApplicationBuilder builder)
|
|
{
|
|
builder.Services.AddHostedService<DeleteExpiredRefreshTokensService>();
|
|
return builder;
|
|
}
|
|
|
|
private static WebApplicationBuilder SetupServices(this WebApplicationBuilder builder)
|
|
{
|
|
// Utility
|
|
builder.Services.AddTransient<IConfigurationService, ConfigurationService>();
|
|
builder.Services.AddTransient<ITokensService, TokensService>();
|
|
builder.Services.AddTransient<IUserService, UserService>();
|
|
|
|
// Controller
|
|
builder.Services.AddTransient<IAccountsControllerService, AccountsControllerService>();
|
|
builder.Services.AddTransient<IGenresControllerService, GenresControllerService>();
|
|
builder.Services.AddTransient<IMoviesControllerService, MoviesControllerService>();
|
|
builder.Services.AddTransient<IMediaControllerService, MediaControllerService>();
|
|
builder.Services.AddTransient<ISeriesControllerService, SeriesControllerService>();
|
|
builder.Services.AddTransient<IPhotosControllerService, PhotosControllerService>();
|
|
builder.Services.AddTransient<IPersonsControllerService, PersonsControllerService>();
|
|
|
|
return builder;
|
|
}
|
|
|
|
private static WebApplicationBuilder SetupApplication(this WebApplicationBuilder builder)
|
|
{
|
|
builder.Services.AddValidatorsFromAssembly(Assembly.GetAssembly(typeof(CustomValidators)));
|
|
builder.Services.AddFluentValidationAutoValidation();
|
|
builder.Services.AddHttpContextAccessor();
|
|
builder.Services.AddControllers();
|
|
builder.Services.AddEndpointsApiExplorer();
|
|
builder.Services.AddSwaggerGen();
|
|
|
|
return builder;
|
|
}
|
|
|
|
#endregion
|
|
}
|