Authentication 使用Azure AD多租户openID身份验证获取访问令牌

Authentication 使用Azure AD多租户openID身份验证获取访问令牌,authentication,azure,azure-active-directory,Authentication,Azure,Azure Active Directory,我按照示例代码创建了一个具有Azure AD多租户OpenID身份验证的MVC web应用程序。我使用以下代码让用户登录 public void SignIn() { if (!Request.IsAuthenticated) { HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnec

我按照示例代码创建了一个具有Azure AD多租户OpenID身份验证的MVC web应用程序。我使用以下代码让用户登录

public void SignIn()
{
    if (!Request.IsAuthenticated)
    {
        HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType);
    }
}
现在我需要发送一个web api调用,它也受我的Azure广告保护。目前,在发送请求之前,我使用ADAL库要求用户再次登录并获得如下访问令牌

AuthenticationContext ac = new AuthenticationContext(authority);
AuthenticationResult ar = ac.AcquireToken(resourceID, clientID, redirectURI, PromptBehavior.Always); 
string accessToken = ar.AccessToken;
但是,由于MVC中使用的身份验证(如果用户来自my AD)与用于保护web api的身份验证相同。我想知道,当用户使用此openID身份验证登录时,是否有办法获取访问令牌,以便我可以跳过使用ADAL的第二次登录

更新: 根据vibronet的回答,我尝试使用以下代码获取令牌:

string authority = "https://login.windows.net/ucdavisprojecthotmail.onmicrosoft.com";

ClientCredential clientcred = new ClientCredential(clientId, appKey);
AuthenticationContext authContext = new AuthenticationContext(authority);
AuthenticationResult result = authContext.AcquireTokenSilent(resourceID, clientcred, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));
这里,这段代码用于MVC web应用程序,clienId和appKey是我要调用的web API的clientID和key。ResourceId是在Azure portal中获得的web API的应用程序ID URI


然而,我得到了这个错误:无法悄悄地获取令牌。调用方法AcquireToken。我遗漏了什么吗?

当然。请注意,这就像您一直在使用的示例,但除了您所询问的访问令牌获取和使用之外。另外请注意,AcquireTokenSilent仅在缓存中有令牌时才能工作-直接使用或刷新。最后:当您请求令牌时,必须同时指定您想要令牌的资源的ID和执行请求的应用程序的clientID。在代码中,您似乎使用了目标应用程序的clientID。请参考我上面链接的示例,它显示了此场景中要使用的确切模式。

在检查了您提供的示例代码后,我知道我需要使用AcquireTokenSilent方法。在本示例中,AuthenticationContext是使用如下所示的缓存构造的:
AuthenticationContext authContext=new AuthenticationContext(string.Format()https://login.microsoftonline.com/{0},tenantID),新的EFADALTokenCache(signedInUserID))。在示例代码中,我似乎需要处理db。让我们假设我根本不需要多租户,我只需要使用我的AD。有没有更简单的方法来构造令牌缓存而不与db交互?您可以使用您喜欢的任何持久层来构建缓存。例如,查看缓存在会话中的保存位置。缓存实际上并不用于处理多租户,只要您想持久化访问令牌,就需要它。我可以在没有此缓存的情况下获取令牌吗?是的,但是您必须在每次请求时都请求它。我尝试使用AcquireTokenSilent,但这不起作用。我已经更新了问题。请看一看。谢谢