ASP.NET Core 3.1下Identity Server 4集成Orcid联合登录方案咨询
在Identity Server 4(ASP.NET Core 3.1)中集成Orcid联合登录方案
核心逻辑
Identity Server 4原生支持多外部认证提供商集成,只需添加对应认证中间件、扩展登录页选项,并复用现有第三方令牌存储与客户端重定向逻辑,即可在保留原有NetForum流程的基础上新增Orcid/Google登录能力。
具体步骤
1. 安装依赖包
针对Orcid(基于OAuth2协议),安装ASP.NET Core OAuth认证中间件:
Install-Package Microsoft.AspNetCore.Authentication.OAuth
若集成Google,直接安装官方认证包:
Install-Package Microsoft.AspNetCore.Authentication.Google
2. 配置Orcid认证中间件
在Startup.cs的ConfigureServices方法中,在AddIdentityServer()之后添加Orcid认证配置:
services.AddAuthentication() // 保留已有的NetForum认证配置 .AddOAuth("NetForum", options => { /* 现有配置逻辑 */ }) // 新增Orcid认证配置 .AddOAuth("Orcid", options => { // 从配置文件读取Orcid开发者凭证(建议存放在appsettings.json) options.ClientId = Configuration["Orcid:ClientId"]; options.ClientSecret = Configuration["Orcid:ClientSecret"]; // Orcid OAuth2端点(区分沙箱/生产环境) options.AuthorizationEndpoint = "https://orcid.org/oauth/authorize"; options.TokenEndpoint = "https://orcid.org/oauth/token"; options.UserInformationEndpoint = "https://pub.orcid.org/v3.0/{orcid}"; // 回调地址,需提前在Orcid开发者平台注册 options.CallbackPath = "/signin-orcid"; // 请求的权限范围,根据业务需求调整 options.Scope.Add("/authenticate"); options.Scope.Add("/read-limited"); // 将Orcid返回的用户信息映射到Identity标准Claims options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "orcid"); options.ClaimActions.MapJsonKey(ClaimTypes.Name, "name"); options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email"); // 自定义用户信息解析逻辑(适配Orcid特殊的返回结构) options.Events = new OAuthEvents { OnCreatingTicket = async context => { // 调用Orcid用户信息接口获取完整数据 var request = new HttpRequestMessage( HttpMethod.Get, context.Options.UserInformationEndpoint.Replace("{orcid}", context.User.GetString("orcid")) ); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted); response.EnsureSuccessStatusCode(); var user = JsonDocument.Parse(await response.Content.ReadAsStringAsync()).RootElement; // 补充更多业务所需Claims(如机构信息等) context.RunClaimActions(user); } }; });
3. 扩展登录页,添加Orcid登录选项
在登录视图(如Login.cshtml)中,新增Orcid登录按钮,与现有NetForum按钮并列:
<div class="external-login-group"> <a asp-action="ExternalLogin" asp-route-provider="NetForum" class="btn btn-primary">通过NetForum登录</a> <a asp-action="ExternalLogin" asp-route-provider="Orcid" class="btn btn-secondary">通过Orcid登录</a> <!-- 如需Google登录,添加对应按钮 --> <a asp-action="ExternalLogin" asp-route-provider="Google" class="btn btn-danger">通过Google登录</a> </div>
4. 复用外部登录回调逻辑
在AccountController的ExternalLoginCallback方法中,统一处理所有外部提供商的回调,无需修改原有核心流程:
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null) { // 处理外部登录错误 if (remoteError != null) { ModelState.AddModelError(string.Empty, $"外部登录错误: {remoteError}"); return View("Login"); } // 获取外部认证结果 var info = await _signInManager.GetExternalLoginInfoAsync(); if (info == null) { return RedirectToAction("Login"); } // 获取外部提供商标识与用户ID var provider = info.LoginProvider; var externalUserId = info.Principal.FindFirstValue(ClaimTypes.NameIdentifier); // 复用原有令牌存储逻辑:保存外部提供商的AccessToken(和NetForum流程一致) await _persistedGrantService.CreateAsync(new PersistedGrant { Key = Guid.NewGuid().ToString(), Type = "external_access_token", SubjectId = externalUserId, ClientId = GetClientIdFromReturnUrl(returnUrl), // 从returnUrl解析客户端ID CreationTime = DateTime.UtcNow, Expiration = DateTime.UtcNow.AddHours(1), Data = info.AuthenticationTokens.First(t => t.Name == "access_token").Value }); // 构建Identity Server所需的身份凭证 var claims = new List<Claim> { new Claim(JwtClaimTypes.Subject, externalUserId), new Claim(JwtClaimTypes.Name, info.Principal.FindFirstValue(ClaimTypes.Name)), // 根据业务需求添加更多Claims }; var identity = new ClaimsIdentity(claims, provider); var principal = new ClaimsPrincipal(identity); // 完成登录,触发Identity Server的SSO流程,最终重定向到客户端回调地址 await HttpContext.SignInAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme, principal); return RedirectToAction("Redirect", "Account", new { returnUrl }); }
5. 关键注意事项
- Orcid开发者注册:需在Orcid开发者平台创建应用,获取ClientId和ClientSecret,并配置回调地址(如
https://your-sso-domain/signin-orcid) - 环境区分:沙箱环境的Orcid端点为
https://sandbox.orcid.org/oauth/authorize和https://sandbox.orcid.org/oauth/token,生产环境使用正式端点 - Claims映射:根据Orcid返回的用户信息结构,调整ClaimActions的映射规则,确保Identity Server能获取到必要的用户标识(如sub)
- 令牌存储:复用原有NetForum的令牌存储机制,确保后续可获取Orcid的AccessToken用于调用Orcid API
内容的提问来源于stack exchange,提问作者Mayuri Barve
相关产品推荐
相关产品推荐

