Files
WatchIt/WatchIt.WebAPI/WatchIt.WebAPI/Program.cs

177 lines
6.6 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.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>();
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
}