ASP.Net Core Identity与OpenIdConnect OAuth2并行使用可行性咨询
解决方案:并行使用ASP.NET Core Identity与OpenIdConnect
完全可以同时用ASP.NET Core Identity管理站点本地用户、OpenIdConnect对接远程OAuth2授权,核心是解决认证Cookie冲突和用户身份关联的问题,以下是具体实现步骤:
1. 配置独立的认证Cookie
给Identity和OIDC分别指定不同的Cookie名称,避免互相覆盖导致本地用户身份丢失:
// 配置Identity专属Cookie builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>() .AddSignInManager(); // 配置OIDC独立Cookie builder.Services.AddAuthentication() .AddOpenIdConnect("RemoteOIDC", options => { options.ClientId = "你的客户端ID"; options.ClientSecret = "你的客户端密钥"; options.Authority = "https://远程授权服务器地址"; options.CallbackPath = "/signin-oidc"; // 指定OIDC专属Cookie名称,与Identity的默认Cookie区分开 options.Cookie.Name = ".AspNetCore.RemoteOIDC"; // 其他OIDC配置... });
2. 调整中间件执行顺序
必须先启动Identity相关的认证逻辑,再加载OIDC中间件,确保本地用户身份优先被识别:
var app = builder.Build(); // 先启用认证、授权中间件 app.UseAuthentication(); app.UseAuthorization(); // 再配置其他中间件(比如MVC路由等) app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.MapRazorPages(); app.Run();
3. 关联远程用户与本地Identity用户(关键)
登录远程OIDC后,需要将远程用户信息与本地Identity用户绑定,避免本地用户身份丢失。可以在OIDC的OnTokenValidated事件中完成关联逻辑:
options.Events = new OpenIdConnectEvents { OnTokenValidated = async context => { var signInManager = context.HttpContext.RequestServices.GetRequiredService<SignInManager<IdentityUser>>(); var userManager = context.HttpContext.RequestServices.GetRequiredService<UserManager<IdentityUser>>(); // 从远程Claims中提取用户唯一标识(比如邮箱) var userEmail = context.Principal.FindFirstValue(ClaimTypes.Email); if (!string.IsNullOrEmpty(userEmail)) { // 查找本地Identity用户 var localUser = await userManager.FindByEmailAsync(userEmail); if (localUser != null) { // 重新登录本地用户,保留远程授权的Token信息 await signInManager.SignInAsync(localUser, isPersistent: false); // 可选:将远程AccessToken存入本地用户的Claims,方便后续调用远程API var remoteToken = context.TokenEndpointResponse.AccessToken; if (!string.IsNullOrEmpty(remoteToken)) { var claimsIdentity = context.Principal.Identity as ClaimsIdentity; claimsIdentity.AddClaim(new Claim("RemoteAccessToken", remoteToken)); } } } await Task.CompletedTask; } };
4. 区分不同场景的授权验证
- 针对需要本地角色权限的页面/接口,直接使用Identity的授权特性:
[Authorize(Roles = "Admin")] public IActionResult AdminDashboard() { return View(); } - 针对需要远程授权的场景,指定OIDC的认证Scheme:
[Authorize(AuthenticationSchemes = "RemoteOIDC")] public async Task<IActionResult> RemoteApiCall() { // 获取远程AccessToken调用API var token = User.FindFirstValue("RemoteAccessToken"); // 后续逻辑... return View(); }
注意事项
- 确保两个Cookie的名称完全不同,避免互相覆盖身份信息;
- 远程用户与本地用户的关联逻辑可以根据业务调整,比如支持手动绑定账号,而非仅通过邮箱匹配;
- 如果需要同时验证本地角色和远程授权,可以自定义授权策略,同时检查两个认证Scheme的身份有效性。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

