IdentityServer 6:如何在应用内部获取用户访问令牌?
在IdentityServer 6中内部获取用户访问令牌的方案
1. 配置专门的测试客户端
首先在IdentityServer的客户端配置中添加一个用于QA测试的独立客户端,避免将IdentityServer自身作为客户端:
public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { ClientId = "qa-test-client", ClientName = "QA测试专用客户端", AllowedGrantTypes = GrantTypes.Code, RequirePkce = true, // 启用PKCE提升流程安全性 RedirectUris = { "https://your-idsrv-domain/qa/show-token" }, // 回调到内部测试页面 PostLogoutRedirectUris = { "https://your-idsrv-domain/qa/logout" }, AllowedScopes = { "openid", "profile", "api1", "api2" }, // 包含需要测试的API范围 AllowOfflineAccess = false, RequireClientSecret = false, // 内部测试客户端无需密钥 AccessTokenLifetime = 3600 // 设置合适的令牌有效期 } }; }
2. 创建测试页面控制器
新建控制器处理令牌请求和交换逻辑,利用IdentityServer内置服务完成授权码流程:
public class QaController : Controller { private readonly IIdentityServerInteractionService _interaction; private readonly ITokenService _tokenService; public QaController(IIdentityServerInteractionService interaction, ITokenService tokenService) { _interaction = interaction; _tokenService = tokenService; } // 触发授权流程获取授权码 public IActionResult RequestToken() { var redirectUrl = Url.Action(nameof(ShowToken), "Qa"); var props = new AuthenticationProperties { RedirectUri = redirectUrl, Items = { { "client_id", "qa-test-client" }, { "scope", "openid profile api1 api2" } } }; // 生成PKCE验证所需的code_verifier和code_challenge var codeVerifier = CryptoRandom.CreateUniqueId(32); var codeChallenge = codeVerifier.ToCodeChallenge(); // 将code_verifier存入Cookie,后续交换令牌时使用 Response.Cookies.Append("code_verifier", codeVerifier, new CookieOptions { HttpOnly = true, Secure = true, SameSite = SameSiteMode.Strict }); props.Items.Add("code_challenge", codeChallenge); props.Items.Add("code_challenge_method", "S256"); // 触发IdentityServer的授权流程 return Challenge(props, IdentityServerConstants.DefaultCookieAuthenticationScheme); } // 回调页面:交换授权码为访问令牌并展示 public async Task<IActionResult> ShowToken(string code) { if (string.IsNullOrEmpty(code)) { return RedirectToAction(nameof(RequestToken)); } var codeVerifier = Request.Cookies["code_verifier"]; if (string.IsNullOrEmpty(codeVerifier)) { return View("Error", "PKCE验证失败"); } // 构造令牌交换请求 var tokenRequest = new TokenRequest { ClientId = "qa-test-client", GrantType = GrantTypes.Code, Code = code, RedirectUri = Url.Action(nameof(ShowToken), "Qa"), CodeVerifier = codeVerifier }; // 调用内置服务交换令牌 var tokenResponse = await _tokenService.CreateTokenAsync(tokenRequest); if (tokenResponse.IsError) { return View("Error", tokenResponse.ErrorDescription ?? tokenResponse.Error); } // 清理临时Cookie Response.Cookies.Delete("code_verifier"); return View(tokenResponse); } }
3. 创建令牌展示视图
新建Razor视图(ShowToken.cshtml)用于展示令牌信息:
@{ ViewData["Title"] = "QA测试令牌"; } <h1>用户访问令牌信息</h1> <div class="card"> <div class="card-body"> <h5 class="card-title">访问令牌</h5> <pre class="card-text">@Model.AccessToken</pre> </div> </div> <div class="card mt-3"> <div class="card-body"> <h5 class="card-title">令牌类型</h5> <p class="card-text">@Model.TokenType</p> </div> </div> <div class="card mt-3"> <div class="card-body"> <h5 class="card-title">过期时间(秒)</h5> <p class="card-text">@Model.ExpiresIn</p> </div> </div> <div class="card mt-3"> <div class="card-body"> <h5 class="card-title">ID Token(可选)</h5> <pre class="card-text">@Model.IdentityToken</pre> </div> </div> <a asp-action="RequestToken" class="btn btn-primary mt-3">重新获取令牌</a>
4. 关键说明
- 该方案完全遵循OAuth2/OpenID Connect规范,通过独立测试客户端完成令牌获取,避免将IdentityServer自身作为客户端。
- PKCE机制确保了授权流程的安全性,防止授权码被劫持。
- 令牌生成完全由IdentityServer内置逻辑处理,符合你配置的API范围、有效期等规则。
- QA团队只需访问
/qa/requesttoken,登录后即可获取当前用户的访问令牌,用于API测试。
内容的提问来源于stack exchange,提问作者JED
相关产品推荐
相关产品推荐

