MS Entra ID获取Bearer Token后无法找到Refresh Token的技术咨询
问题场景
在Windows .NET 4.8桌面应用中,使用MS Entra ID身份框架(MSAL)获取Bearer Token,用于访问SharePoint、Graph Explorer等微软服务。当前代码能成功获取AccessToken,但发现AccessToken的JWT Payload中没有Refresh Token相关声明,且不清楚如何获取Refresh Token以调用AcquireTokenByRefreshToken方法。
当前获取令牌的代码:
AuthenticationResult Token = null; this.ClientApp = (PublicClientApplication)PublicClientApplicationBuilder.Create(this.AzureAppId) .WithDefaultRedirectUri() .WithAuthority(AzureCloudInstance.AzurePublic, this.AzureTenant) .Build(); Token = await ClientApp.AcquireTokenInteractive(scopes) .WithPrompt(Prompt.SelectAccount) .WithParentActivityOrWindow(GetActiveWindow()) .WithUseEmbeddedWebView(true) .WithLoginHint(this.UserPrincipal) .ExecuteAsync(); var accessToken = new JwtSecurityToken(Token.AccessToken);
示例AccessToken的Payload:
{ "aud": "https://smith.sharepoint.com", "iss": "https://sts.windows.net/241c2f02-4073-4f03-a65c-7fs98df79s/", "iat": 1708340625, "nbf": 1708340625, "exp": 1708344648, "acr": "1", "aio": "ATQAy/8WAAAAwKrJ5m4ksdTPPDCj6yEjabUUML2CPVr5+BpgPI4PiRQ0yhwHtn9V92z6TCYz89EI", "amr": [ "pwd", "rsa" ], "app_displayname": "Model Gen for Visio (MG4V)", "appid": "6d0d7d48-22aa-4ca2-9aba-7fs98df79s", "appidacr": "0", "deviceid": "b9b110cf-6c2a-4ee2-9f57-7fs98df79s", "family_name": "Smith", "given_name": "John", "idtyp": "user", "ipaddr": "114.76.XXX.XXX", "name": "John Smith", "oid": "3403db6b-c7fa-458f-8e94-7fs98df79s", "puid": "10032001608CEB31", "rh": "0.AUEAAi8cJHNAA0-mXNVTRH7UmwMAAAAAAPEPzgAAAAAAAABBALw.", "scp": "AllSites.Write Application.Read.All EnterpriseResource.Write Mail.Read MyFiles.Write Project.Write User.Read User.Read.All User.ReadBasic.All", "sid": "62f6ac6f-1c60-4256-a90a-7fs98df79s", "signin_state": [ "kmsi" ], "sub": "YzsnKftWdjLMsHbGO0F-l9mr-7fs98df79s", "tid": "241c2f02-4073-4f03-a65c-7fs98df79s", "unique_name": "john.smith@acme.com.au", "upn": "john.smith@acme.com.au", "uti": "NLRbXlWCrk-oBbwRLDIGAA", "ver": "1.0", "wids": [ "ac16e43d-7b2d-40e0-ac05-7fs98df79s" ] }
关键说明与解决方案
1. Refresh Token的位置:不在AccessToken Payload中
Refresh Token是与AccessToken独立返回的凭据,不会包含在AccessToken的JWT Payload里。你可以直接从AuthenticationResult对象的RefreshToken属性获取:
// 从AuthenticationResult中获取Refresh Token var refreshToken = Token.RefreshToken;
2. 确保应用配置与请求参数正确
公共客户端应用(桌面/移动类)默认支持获取Refresh Token,但需确认以下两点:
- 在Entra ID中,你的应用已配置为公共客户端类型(移动和桌面应用),而非机密客户端(Web应用/API)。
- 调用
AcquireTokenInteractive时,使用的权限范围为委派权限(delegated permissions),这是公共客户端获取用户令牌的必要条件。
3. 令牌刷新的推荐方式:优先使用AcquireTokenSilent
MSAL框架推荐使用AcquireTokenSilent自动管理令牌刷新,而非手动调用AcquireTokenByRefreshToken。AcquireTokenSilent会优先从令牌缓存中获取有效AccessToken,若缓存失效,会自动使用Refresh Token获取新令牌,无需手动处理Refresh Token:
try { // 尝试从缓存获取或自动刷新令牌 var silentResult = await ClientApp.AcquireTokenSilent(scopes, Token.Account) .ExecuteAsync(); var newAccessToken = silentResult.AccessToken; } catch (MsalUiRequiredException) { // 缓存无有效令牌且无法自动刷新时,需重新发起交互式登录 var newInteractiveResult = await ClientApp.AcquireTokenInteractive(scopes) .WithPrompt(Prompt.SelectAccount) .WithParentActivityOrWindow(GetActiveWindow()) .ExecuteAsync(); }
4. 手动使用Refresh Token的方式(不推荐)
如果必须使用AcquireTokenByRefreshToken,直接传入之前获取的Refresh Token即可:
var refreshResult = await ClientApp.AcquireTokenByRefreshToken(scopes, refreshToken) .ExecuteAsync(); var refreshedAccessToken = refreshResult.AccessToken;
内容的提问来源于stack exchange,提问作者Andrew Tyson
相关产品推荐
相关产品推荐

