从身份验证上下文接收的令牌不工作



我正在设置一个多租户应用程序,并且在创建GraphServiceClient时遇到问题。

我必须遵循authorizationcoderreceived:

AuthorizationCodeReceived = async context =>
                    {
                        var tenantId =
                            context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                        var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/"+ tenantId);
                        await authenticationContext.AcquireTokenByAuthorizationCodeAsync(
                            context.Code,
                            new Uri("http://localhost:21925"),
                            new ClientCredential(ClientId, ClientSecret),
                            "https://graph.microsoft.com");
                    }

这对于验证用户非常有效。我正在使用fiddler,我看到一个新的承载令牌由login.microsoftonline.com/{tenantid}/oauth2/token

给出。

当创建一个新的图形服务客户端时,我使用以下工厂方法:

public IGraphServiceClient CreateGraphServiceClient()
    {
        var client = new GraphServiceClient(
            new DelegateAuthenticationProvider(
                async requestMessage =>
                {
                    string token;
                    var currentUserId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
                    var currentUserHomeTenantId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
                    var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/" + currentUserHomeTenantId + "/");
                    var clientCredential = new ClientCredential(_configuration.ClientId, _configuration.ClientSecret);
                    try
                    {
                        var authenticationResult = await authenticationContext.AcquireTokenSilentAsync(
                            GraphResourceId,
                            clientCredential,
                            new UserIdentifier(currentUserId, UserIdentifierType.UniqueId));
                        token = authenticationResult.AccessToken;
                    }
                    catch (AdalSilentTokenAcquisitionException e)
                    {
                        var result = await authenticationContext.AcquireTokenAsync(GraphResourceId, clientCredential);
                            token = result.AccessToken;
                    }
                    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
                }));
        return client;
    }

这个方法总是抛出一个adalsilentacquiretokenasync获取一个新的令牌。

使用此令牌,我无法请求图上的"我"。我得到以下异常:message=资源'some guid'不存在,或者它查询的引用属性对象之一不存在。

但是,如果我正在调试,并且在将令牌传递给标头之前更改令牌,在登录后(从login.microsoftonline.com/{tenantid}/oauth2/token收到)之前获得的值,则API调用工作。

有人知道我做错了什么吗?我能让被收购的代币默默地工作吗?

Update:我已经更新了代码示例。我已经删除了自定义缓存,现在一切似乎都工作。

如何根据http会话制作自定义缓存,确保acquiretokensilent工作

令牌缓存不工作预览:

public class WebTokenCache : TokenCache
{
    private readonly HttpContext _httpContext;
    private readonly string _cacheKey;
    public WebTokenCache()
    {
        _httpContext = HttpContext.Current;
        var claimsPrincipal = (ClaimsPrincipal) HttpContext.Current.User;
        _cacheKey = BuildCacheKey(claimsPrincipal);
        AfterAccess = AfterAccessNotification;
        LoadFromCache();
    }
    private string BuildCacheKey(ClaimsPrincipal claimsPrincipal)
    {
        var clientId = claimsPrincipal.FindFirst("aud").Value;
        return $"{claimsPrincipal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value}_TokenCache";
    }
    private void LoadFromCache()
    {
        var token = _httpContext.Cache[_cacheKey];
        if (token == null) return;
        Deserialize((byte[]) token);
    }
    private void AfterAccessNotification(TokenCacheNotificationArgs args)
    {
        if (!HasStateChanged) return;
        if (Count > 0)
        {
            _httpContext.Cache[_cacheKey] = Serialize();
        }
        else
        {
            _httpContext.Cache.Remove(_cacheKey);
        }
        HasStateChanged = false;
    }
}

我正在尝试使用上面的代码,它工作得很好。

请确保GraphResourceIdhttps://graph.microsoft.com(此资源是在您的startUp类中第一次请求的),因为方法AcquireTokenSilentAsync将尝试根据资源从缓存中检索令牌。

相关内容

  • 没有找到相关文章

最新更新