ASP.NET Core MVC对接非OIDC第三方API OAuth2授权码获取咨询
实现指引与问题排查
1. OidcClient报错的根因
你的推测完全正确,DiscoveryDocument是OpenID Connect的标准特性,OidcClient类仅面向符合OIDC规范的身份提供商设计,你对接的服务不支持OIDC的话,无法使用这个类,这不是你遗漏了配置,是选型不匹配。IdentityModel本身提供了纯OAuth2流程的工具类,不需要依赖OIDC相关能力即可完成授权流程。
2. 授权码流程完整实现(ASP.NET Core MVC)
第一步:构造授权跳转链接,唤起第三方登录窗口
你可以直接拼接第三方授权端点的必填参数,通过重定向或者前端弹窗的方式让用户完成认证:public IActionResult StartOAuth() { // 生成state防CSRF攻击,存入Cookie后续回调校验 var state = Guid.NewGuid().ToString("N"); Response.Cookies.Append("oauth_state", state, new CookieOptions { HttpOnly = true, Secure = true, SameSite = SameSiteMode.Lax, Expires = DateTimeOffset.Now.AddMinutes(10) }); // 拼接授权请求参数 var authQuery = new Dictionary<string, string> { ["client_id"] = "你在第三方平台申请的客户端ID", ["redirect_uri"] = Url.Action("OAuthCallback", "Auth", null, Request.Scheme), // 提前在第三方平台注册的回调地址 ["response_type"] = "code", ["scope"] = "你申请的权限范围", ["state"] = state }; var authUrl = "第三方授权端点完整地址" + QueryString.Create(authQuery); return Redirect(authUrl); }如果需要弹窗效果,前端增加触发逻辑即可:
<button onclick="openAuthWindow()">第三方授权</button> <script> function openAuthWindow() { window.open('/Auth/StartOAuth', 'oauthWin', 'width=600,height=650,top=100,left=200'); } </script>第二步:实现回调接口,捕获授权码并兑换令牌
第三方认证完成后会自动跳转到你配置的redirect_uri,携带授权码code和state参数:public async Task<IActionResult> OAuthCallback(string code, string state) { // 校验state防止CSRF攻击 var storedState = Request.Cookies["oauth_state"]; if (string.IsNullOrEmpty(code) || storedState != state) { return BadRequest("无效的授权请求"); } // 校验完成后删除state Cookie Response.Cookies.Delete("oauth_state"); // 用授权码兑换令牌,直接用IdentityModel的原生工具类 using var httpClient = new HttpClient(); var tokenRes = await httpClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest { Address = "第三方令牌端点完整地址", ClientId = "你在第三方平台申请的客户端ID", ClientSecret = "你在第三方平台申请的客户端密钥", Code = code, RedirectUri = Url.Action("OAuthCallback", "Auth", null, Request.Scheme) }); if (tokenRes.IsError) { return BadRequest($"令牌获取失败:{tokenRes.Error}"); } // 这里已经拿到需要的令牌,可按需存入用户Session、数据库等位置 var accessToken = tokenRes.AccessToken; var refreshToken = tokenRes.RefreshToken; var expiresIn = tokenRes.ExpiresIn; // 授权完成后跳转到业务页面,弹窗场景下可返回关闭窗口+父页面刷新的脚本 return RedirectToAction("Index", "Home"); }第三步:后续API请求携带令牌
调用第三方业务接口时,在请求头中携带获取到的access_token即可,IdentityModel提供了简化的扩展方法:using var apiClient = new HttpClient(); apiClient.SetBearerToken(accessToken); // 自动添加Authorization请求头 var apiRes = await apiClient.GetAsync("第三方业务接口地址");
内容的提问来源于stack exchange,提问作者SiStone
相关产品推荐
相关产品推荐

