2

我想使用应用程序 ID 和机密对 AAD 用户进行身份验证,以通过 MSAL 访问 powerBi 资源。所以我想获取访问令牌并将其缓存在 SQL Db 中。

浏览了文档,但它解释了使用 MSAL 登录的场景。还通过了教程 ,我能够进行必要的实现来获取令牌。

在这种情况下,如何获取访问令牌并将其缓存?

4

3 回答 3

1

我不确定是否理解,希望这几行代码对您有所帮助。

首先,自定义令牌缓存序列化:

public class ClientApplicationBuilder
{
    public static IConfidentialClientApplication Build()
    {
        IConfidentialClientApplication clientApplication =
            ConfidentialClientApplicationBuilder
                .Create(ClientId)
                .WithRedirectUri(RedirectUri)
                .WithClientSecret(ClientSecret)
                .Build();

        clientApplication.UserTokenCache.SetBeforeAccessAsync(BeforeAccessNotification);
        clientApplication.UserTokenCache.SetAfterAccessAsync(AfterAccessNotification);

        return clientApplication;
    }

    private static async Task<byte[]> GetMsalV3StateAsync()
    {
        //TODO: Implement code to retrieve MsalV3 state from DB
    }

    private static async Task StoreMsalV3StateAsync(byte[] msalV3State)
    {
        //TODO: Implement code to persist MsalV3 state to DB
    }

    private static async Task BeforeAccessNotification(TokenCacheNotificationArgs args)
    {
        byte[] msalV3State = await GetMsalV3StateAsync();
        args.TokenCache.DeserializeMsalV3(msalV3State);
    }

    private static async Task AfterAccessNotification(TokenCacheNotificationArgs args)
    {
        if (args.HasStateChanged)
        {
            byte[] msalV3State = args.TokenCache.SerializeMsalV3();
            await StoreMsalV3StateAsync(msalV3State);
        }
    }
}

这是获取令牌的示例(通过授权码):

public class MsAccountController
    : Controller
{
    private readonly IConfidentialClientApplication _clientApplication;

    public MsAccountController()
    {
        _clientApplication = ClientApplicationBuilder.Build();
    }

    [HttpGet]
    public async Task<IActionResult> Index()
    {
        Uri authorizationRequestUrl = await _clientApplication.GetAuthorizationRequestUrl(ClientApplicationHelper.Scopes).ExecuteAsync();
        string authorizationRequestUrlStr = authorizationRequestUrl.ToString();
        return Redirect(authorizationRequestUrlStr);
    }

    [HttpGet]
    public async Task<IActionResult> OAuth2Callback(string code, string state)
    {
        AuthenticationResult authenticationResult = await _clientApplication.AcquireTokenByAuthorizationCode(scopes, code).ExecuteAsync();
        return Ok(authenticationResult);
    }
}

最后,静默获取令牌并为您的 API 客户端使用身份验证结果:

public class TaskController
    : Controller
{
    private readonly IConfidentialClientApplication _clientApplication;

    public TaskController()
    {
        _clientApplication = ClientApplicationBuilder.Build();
    }

    [HttpGet]
    public async Task<IActionResult> Index()
    {
        IEnumerable<IAccount> accounts = await _clientApplication.GetAccountsAsync();
        AuthenticationResult result = await _clientApplication.AcquireTokenSilent(ClientApplicationHelper.Scopes, accounts.FirstOrDefault()).ExecuteAsync();

        //TODO: Create your API client using authentication result
    }
}

问候

于 2020-02-04T23:11:27.693 回答
1

如其他答案所示,缓存令牌在您有用户登录的情况下很有用,因为一旦访问令牌过期(通常在 1 小时后),您就不想继续提示用户重新进行身份验证。因此,在这些情况下,Azure AD 会发出一个刷新令牌以及一个用于在访问令牌过期后获取访问令牌的访问令牌。需要缓存来缓存这些刷新令牌,因为它们的有效期为 90 天。

当应用程序以自己的身份签名(而不是用户登录)时,将使用客户端凭据流,它只需要应用程序 ID (clientId) 和凭据(秘密/证书)来颁发访问令牌。MSAL 库将自动检测访问令牌何时过期,并将使用 clientId/credential 组合自动获取新的访问令牌。所以缓存不是必需的。

您应该查看的示例是这个

于 2019-09-12T01:03:52.153 回答
0

您可以缓存访问令牌(实际上,库已经这样做了),但它仅在 1 小时内有效。所以把它保存在数据库中是没有意义的,因为它会很快过期。

您应该缓存获取令牌所需的凭据(用户名和密码、应用 ID 和密钥或证书),并在需要时获取令牌。

于 2019-09-11T19:04:00.657 回答