using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Text; using Microsoft.AspNetCore.Identity; using bitforum.Models; using bitforum.Models.User; namespace bitforum.Extensions { public static class ServiceExtensions { // CORS 구성 public static void ConfigureCors(this IServiceCollection services, IConfiguration configuration) { services.AddCors(options => { options.AddPolicy("AllowFrontend", builder => { builder.WithOrigins("https://localhost:3000").AllowAnyHeader().AllowAnyMethod().AllowCredentials(); }); }); } // 관리자단 비밀번호 정책 구성 public static void ConfigureIdentity(this IServiceCollection services, IConfiguration configuration) { services.AddIdentity(options => { options.SignIn.RequireConfirmedAccount = true; // 이메일 확인 비활성화 // Password settings. options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireNonAlphanumeric = true; options.Password.RequireUppercase = true; options.Password.RequiredLength = 6; options.Password.RequiredUniqueChars = 1; // Lockout settings. options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = true; // User settings. options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; options.User.RequireUniqueEmail = false; }) .AddEntityFrameworkStores() // 사용자 계정 저장소 .AddDefaultUI() // 기본 UI 사용 .AddDefaultTokenProviders(); // 기본 토큰 제공자 사용 services.ConfigureApplicationCookie(options => { // Cookie settings options.ExpireTimeSpan = TimeSpan.FromMinutes(30); options.LoginPath = "/Identity/Account/Login"; options.AccessDeniedPath = "/Identity/Account/AccessDenied"; options.SlidingExpiration = true; }); } // JWT 전달자 인증 구성 public static void ConfigureAuthentication(this IServiceCollection services, IConfiguration configuration) { services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Setting.Jwt.SecretKey)), ValidateIssuer = true, ValidateAudience = true, ValidIssuer = Setting.Jwt.Issuer, ValidAudience = Setting.Jwt.Audience, ValidateLifetime = true, ClockSkew = TimeSpan.Zero }; options.Events = new JwtBearerEvents { OnMessageReceived = context => { if (context.Request.Cookies.ContainsKey("accessToken")) { context.Token = context.Request.Cookies["accessToken"]; } return Task.CompletedTask; } }; }); } } }