| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- using SharedKernel;
- using Infrastructure.Persistence;
- using Infrastructure.Persistence.Identity;
- using Infrastructure.Extensions;
- using Microsoft.AspNetCore.Authentication.Cookies;
- using Microsoft.AspNetCore.HttpOverrides;
- using Microsoft.AspNetCore.Identity;
- using Microsoft.Extensions.Caching.Distributed;
- using System.Net;
- using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork;
- namespace Admin.Extensions
- {
- public static class ServiceCollectionExtensions
- {
- public static void AddAdminForwardedHeaders(this IServiceCollection services, AppSettings settings)
- {
- services.Configure<ForwardedHeadersOptions>(options =>
- {
- options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
- options.ForwardLimit = settings.ForwardedHeaders.ForwardLimit <= 0 ? 1 : settings.ForwardedHeaders.ForwardLimit;
- // 설정에서 KnownProxies / KnownNetworks 읽기
- var knownProxies = settings.ForwardedHeaders.KnownProxies;
- if (knownProxies != null)
- {
- foreach (var proxy in knownProxies)
- {
- if (IPAddress.TryParse(proxy, out var ip))
- {
- options.KnownProxies.Add(ip);
- }
- }
- }
- var knownNetworks = settings.ForwardedHeaders.KnownNetworks;
- if (knownNetworks != null)
- {
- foreach (var net in knownNetworks)
- {
- var parts = net.Split('/');
- if (parts.Length == 2 && IPAddress.TryParse(parts[0], out var networkIp) && int.TryParse(parts[1], out var prefix))
- {
- options.KnownNetworks.Add(new IPNetwork(networkIp, prefix));
- }
- }
- }
- });
- }
- // 관리자단 비밀번호 정책 구성
- public static void AddAdminIdentity(this IServiceCollection services, AppSettings settings)
- {
- services.AddIdentity<ApplicationUser, IdentityRole>(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 = true;
- })
- .AddDefaultUI() // 기본 UI 사용
- .AddDefaultTokenProviders() // 기본 토큰 제공자 사용
- .AddEntityFrameworkStores<IdentityDbContext>(); // 사용자 계정 저장소
- // Identity Cookie Session Store 설정
- services.AddSingleton<ITicketStore>(sp =>
- new DistributedCacheTicketStore(
- sp.GetRequiredService<IDistributedCache>(),
- keyPrefix: settings.Redis.AuthTicketPrefix
- )
- );
- services.AddOptions<CookieAuthenticationOptions>(IdentityConstants.ApplicationScheme).Configure<ITicketStore>((options, ticketStore) =>
- {
- options.SessionStore = ticketStore;
- });
- services.ConfigureApplicationCookie(options =>
- {
- // Cookie settings
- options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
- options.LoginPath = "/Identity/Account/Login";
- options.AccessDeniedPath = "/Identity/Account/AccessDenied";
- options.SlidingExpiration = true;
- options.Events.OnRedirectToLogin = context =>
- {
- if (context.Request.Path.StartsWithSegments("/Api"))
- {
- context.Response.StatusCode = StatusCodes.Status401Unauthorized;
- return Task.CompletedTask;
- }
- context.Response.Redirect(context.RedirectUri); // 기존 쿠키 인증 흐름 유지
- return Task.CompletedTask;
- };
- options.Events.OnRedirectToAccessDenied = context =>
- {
- if (context.Request.Path.StartsWithSegments("/Api"))
- {
- context.Response.StatusCode = StatusCodes.Status403Forbidden;
- return Task.CompletedTask;
- }
- context.Response.Redirect(context.RedirectUri);
- return Task.CompletedTask;
- };
- });
- }
- }
- }
|