如何在ASP.NET Core MVC中实现多项目集中式授权(无需第三方)
ASP.NET Core MVC 集中式认证授权实现方案(无第三方依赖)
方案概述
通过搭建一个基于ASP.NET Core Identity的集中式身份认证服务,让所有业务MVC项目统一对接该服务完成认证授权。以下是最简可运行的实现步骤:
一、集中式身份认证项目配置
1. 修正并完善Program.cs
移除重复的AddAuthorization调用,添加Identity服务和共享Cookie配置:
var builder = WebApplication.CreateBuilder(args); // 添加MVC控制器与视图支持 builder.Services.AddControllersWithViews(); // 配置Identity与数据库存储 builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false) .AddEntityFrameworkStores<ApplicationDbContext>(); // 配置跨项目共享的认证Cookie builder.Services.ConfigureApplicationCookie(options => { options.Cookie.Name = ".SharedAuthCookie"; options.Cookie.Domain = "localhost"; // 本地测试用,生产替换为实际主域名 options.LoginPath = "/Account/Login"; options.LogoutPath = "/Account/Logout"; }); // 仅需添加一次授权服务 builder.Services.AddAuthorization(); var app = builder.Build(); // 中间件顺序必须严格遵循:认证在前,授权在后 app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.MapRazorPages(); // Identity依赖Razor Pages处理默认UI app.Run();
2. 完善AccountController核心逻辑
补充登录、登出的实现代码:
public class AccountController : Controller { private readonly UserManager<IdentityUser> _userManager; private readonly SignInManager<IdentityUser> _signInManager; public AccountController(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager) { _userManager = userManager; _signInManager = signInManager; } [HttpGet] public IActionResult Login(string? returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; return View(); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Login(LoginViewModel model, string? returnUrl = null) { returnUrl ??= Url.Content("~/"); if (ModelState.IsValid) { var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); if (result.Succeeded) return LocalRedirect(returnUrl); ModelState.AddModelError(string.Empty, "登录失败,请检查账号密码"); } return View(model); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Logout(string? returnUrl = null) { await _signInManager.SignOutAsync(); return LocalRedirect(returnUrl ?? Url.Content("~/")); } } // 登录视图模型 public class LoginViewModel { [Required] [EmailAddress] public string Email { get; set; } = string.Empty; [Required] [DataType(DataType.Password)] public string Password { get; set; } = string.Empty; [Display(Name = "记住我")] public bool RememberMe { get; set; } }
二、业务MVC项目配置
1. 修正Program.cs配置
配置对接集中式身份服务的认证逻辑,移除重复的AddAuthorization:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); // 配置认证服务,使用与身份项目一致的共享Cookie builder.Services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; }) .AddCookie(options => { options.Cookie.Name = ".SharedAuthCookie"; options.Cookie.Domain = "localhost"; // 跳转至集中式身份服务的登录/登出页面 options.LoginPath = "https://localhost:5001/Account/Login"; options.LogoutPath = "https://localhost:5001/Account/Logout"; }); // 可选:使用OpenID Connect协议对接(更规范的SSO方案) // .AddOpenIdConnect(options => // { // options.Authority = "https://localhost:5001"; // options.ClientId = "mvc-business-client"; // options.ClientSecret = "your-client-secret"; // options.ResponseType = "code"; // options.SaveTokens = true; // options.Scope.Add("openid"); // options.Scope.Add("profile"); // }); builder.Services.AddAuthorization(); var app = builder.Build(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
2. 受保护的业务控制器(保持原代码)
public class HomeController : Controller { [Authorize] public IActionResult Index() { return View(); } }
核心注意事项
- 数据保护共享:跨项目共享Cookie时,需确保所有项目使用相同的数据保护密钥,可通过配置文件存储密钥或使用Redis等分布式存储共享。
- 域名要求:生产环境中,所有项目需部署在同一主域名下(如
*.yourdomain.com),确保Cookie可跨子域传递。 - 方案选择:直接Cookie共享适合小型场景,OpenID Connect协议更安全,支持标准单点登录(SSO),推荐生产环境使用。
内容的提问来源于stack exchange,提问作者Kong Jungle
相关产品推荐
相关产品推荐

