【问题标题】:Azure ADAL Refresh id_tokenAzure ADAL 刷新 id_token
【发布时间】:2015-02-01 23:35:54
【问题描述】:

我们正在开发一个多租户 Web 应用程序。我们的租户将使用 Windows Azure Active Directory 进行身份验证。我们正在使用 OWIN OpenIdConnect 中间件对用户进行身份验证。我们在认证过程后收到的响应有 id_token 和授权码。

我们还想获取刷新令牌,以便在 id_token 过期后获取新令牌。因此,在 AuthorizationCodeReceived 处理程序中,我们使用 ADAL 库中的 AcquireTokenByAuthorizationCode 方法来获取刷新令牌。响应包含 id_token、access_token 和 refresh_token。

然后我们随后使用 referh_token 来获取新的 id_token,但是响应只包含更新的 access_token 而不是更新的 id_token。是否可以刷新 id_token 或者我们只能刷新 access_token?授权码接收处理程序的代码如下所示。

AuthorizationCodeReceived = (context) =>
{
    string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + "/";
    var code = context.Code;
    string clientSecret = ConfigurationManager.AppSettings["ida:Password"];
    ClientCredential credential = new ClientCredential(clientId, clientSecret);
    string tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
    string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
    MAuthenticationContext authContext = new MAuthenticationContext(string.Format("https://login.windows.net/{0}", tenantID), null);
    AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
                code, new Uri(appBaseUrl), credential, "https://graph.windows.net");

    AuthenticationResult refreshTokenResult = authContext.AcquireTokenByRefreshToken(result.RefreshToken, credential);

    return Task.FromResult(0);
},

【问题讨论】:

    标签: owin azure-active-directory openid-connect adal


    【解决方案1】:

    一般而言,您不能使用 refresh_token 来更新 id_token,因为 id_token 代表用户身份验证,即在没有用户在场的情况下无法刷新的信息。刷新 id_token 的方法在 OpenID Connect (http://openid.net/specs/openid-connect-session-1_0.html) 的会话管理草案中进行了描述,即通过将用户(代理)再次发送到授权端点,并使用身份验证请求,如果您愿意,可能包括“prompt=none”无需用户交互,只需与 OP 确认现有的 SSO 会话。

    Azure AD 支持草案规范中描述的会话管理功能。如果您想将 OP 会话与您的应用程序会话同步,那就是要走的路。 OTOH,您可以选择拥有一个独立于 OP 会话的应用程序会话,使用它自己的会话超时和持续时间,在这种情况下,没有理由刷新 id_token。然后 id_token 仅用于引导应用程序会话,该会话随后独立存在。

    【讨论】:

    • 感谢您的回复。我想刷新 id_token 的原因是我会在 Authorization 标头中使用 id_token 调用服务。由于令牌的生命周期为 3600 秒,因此我需要再次获取 id_token 以用于后续请求。对于 Web 应用程序本身,id_token 充当引导程序。
    • 如果您关心 id_token 的生命周期和登录语义,后端服务本身可以/应该是 OpenID Connect 客户端。如果只是在标准化结构 (JWT) 中传递用户身份,那么后端可以将其视为普通 JWT 并忽略到期,假设调用者以某种方式进行了身份验证。
    【解决方案2】:

    另外:AcquireTokenByRefreshToken 确实是手动回退,以防 ADAL 的自动缓存管理中存在您不想执行的内容。一般来说,每次调用 AcquireToken*(AcquireTokenByRefreshToken 除外)在需要时自动使用刷新令牌,并且缓存中有一个有效令牌。除非您真的处于特殊情况,否则我建议您不要使用 AcquireTokenByRefreshToken

    【讨论】:

    • 我用 AcquireToken 替换了对 AcquireTokenByRefreshToken 的调用,并且我在提琴手中观察到,对 AcquireToken 的后续调用会获得更新的令牌,并且不会从令牌缓存中选择它。 " result = authContext.AcquireToken("graph.windows.net", credential, new UserAssertion(context.JwtSecurityToken.RawData));"
    • Gaurav,在您的代码中,您使用“null”作为缓存初始化 authenticationcontext。这表明您不想使用任何缓存,因此他的刷新令牌丢失了。你有两个选择:一个是使用默认值——不要在那里传递任何东西,Adal 将使用它的 OOB 内存缓存——另一个是传递一个自定义缓存,就像我们在示例中所做的那样,它允许你选择任何持久性你喜欢的存储。我们在 github.com/azureadsamples 下有各种具有自定义缓存类的示例
    • @vibronet 会 AcquireTokenSilent 这样做吗?
    • Acquiretokensilent 使用缓存,是的。
    猜你喜欢
    • 2020-07-08
    • 1970-01-01
    • 2018-11-22
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-13
    • 2018-12-20
    相关资源
    最近更新 更多