ASP.NET(非.NET Core)如何通过代码或CLI从ADFS获取JWT令牌
非交互模式从ADFS获取JWT令牌解决方案
前置配置确认
首先需要ADFS管理员完成以下配置,否则无法正常获取令牌:
- 在ADFS中注册服务器应用作为调用端,记录分配的客户端ID
- 若使用客户端凭证流(最适合API服务间调用测试场景):为该客户端分配API的访问权限,生成客户端密钥,同时开启客户端凭证流权限
- 若使用密码授权流(ROPC):为该客户端开启密码授权流权限,准备测试用的域账号凭据
- 你的ASP.NET API需要在ADFS中注册为信赖方信任,记录对应的资源标识符(后续请求的resource参数需和该值完全一致)
Postman请求配置(修复之前的报错问题)
你之前返回的是ADFS通用错误页,没有具体错误信息,大概率是请求参数不全或流权限未开启,按以下配置重新发POST请求到https://<你的ADFS域名>/adfs/oauth2/token:
客户端凭证流参数(优先推荐)
请求头配置:
- Content-Type: application/x-www-form-urlencoded
请求体(x-www-form-urlencoded格式):
grant_type: client_credentials client_id: <注册的客户端ID> client_secret: <生成的客户端密钥> resource: <API的资源标识符>
ROPC流参数(需模拟用户身份时使用)
请求体参数:
grant_type: password client_id: <注册的客户端ID> username: <测试域账号,支持domain\用户名或用户名@域名格式> password: <测试账号密码> resource: <API的资源标识符>
请求成功后返回报文中的access_token字段就是你需要的JWT令牌,可直接放到API请求的Authorization: Bearer <令牌值>头中调用接口。
适配ASP.NET(.NET Framework)的代码实现
如果需要在单元测试或工具代码中自动获取令牌,可参考以下C#代码:
using System; using System.Net.Http; using System.Collections.Generic; using System.Threading.Tasks; using Newtonsoft.Json; public class AdfsTokenHelper { private static readonly HttpClient _httpClient = new HttpClient(); // 替换为你实际的ADFS和应用配置 private const string AdfsTokenUrl = "https://你的ADFS域名/adfs/oauth2/token"; private const string ClientId = "你注册的客户端ID"; private const string ClientSecret = "你生成的客户端密钥"; private const string ApiResourceId = "你的API资源标识符"; public static async Task<string> GetClientCredentialToken() { var requestContent = new FormUrlEncodedContent(new Dictionary<string, string> { {"grant_type", "client_credentials"}, {"client_id", ClientId}, {"client_secret", ClientSecret}, {"resource", ApiResourceId} }); var response = await _httpClient.PostAsync(AdfsTokenUrl, requestContent); // 确保请求成功,失败会抛出异常 response.EnsureSuccessStatusCode(); var responseStr = await response.Content.ReadAsStringAsync(); var tokenResult = JsonConvert.DeserializeObject<TokenResponse>(responseStr); return tokenResult.AccessToken; } } // 令牌返回结果映射类 public class TokenResponse { [JsonProperty("access_token")] public string AccessToken { get; set; } [JsonProperty("expires_in")] public int ExpiresIn { get; set; } [JsonProperty("token_type")] public string TokenType { get; set; } }
注:代码依赖Newtonsoft.Json NuGet包,.NET Framework 4.5及以上版本可直接使用。
报错排查方案
如果依然返回通用错误页,可通过以下方式定位具体问题:
- 登录ADFS服务器,打开事件查看器,路径为应用程序和服务日志>Microsoft>Windows>ADFS>Admin,搜索你报错信息中的Activity ID(本次报错为4acc6a7b-dafe-4a4b-1c00-0080000000dd),对应日志会明确说明错误原因,常见原因包括客户端未开启对应流权限、资源标识符错误、客户端密钥不正确等。
- 确保请求使用HTTPS协议,ADFS默认拒绝HTTP协议的令牌请求。
- 确认ADFS版本为2016及以上,低版本ADFS对OAuth2流支持不完善。
内容的提问来源于stack exchange,提问作者AnthonyDa
相关产品推荐
相关产品推荐

