【问题标题】:Refresh token implementation using Msal使用 Msal 刷新令牌实现
【发布时间】:2021-02-01 09:08:13
【问题描述】:

我正在尝试将现有的获取令牌实现从 ADAL 迁移到 MSAL。 我能够获得访问令牌,并且 grant_type=auth_code 流程运行良好。

但是当我尝试实现范围为 offline_access 的 grant_type=refresh_token 时,问题就出现了,即使我在调试代码时能够看到 refresh_token,但由于 MSAL 没有向客户端公开 refresh_token,所以我没有得到它我的部分回复。

根据 MSAL 文档,它说我们应该在令牌过期后使用 acquireTokenSilently 来获取令牌。

在这个链接ADAL to MSAL Migration它说

MSAL for Java 有一个 API,允许您将使用 ADAL4j 获取的刷新令牌迁移到 ClientApplication:acquireToken(RefreshTokenParameters)。使用此方法,您可以提供以前使用的刷新令牌以及所需的任何范围(资源)。刷新令牌将交换为新令牌并缓存以供您的应用程序使用。

所以我对上述行感到困惑,因为 MSAL 不会公开 refresh_token 我们如何创建 RefreshTokenParameter。

还有一个用例,我确实需要将 refresh_token 发送回客户端。

谁能帮助我提供进一步的指导。

【问题讨论】:

    标签: java adal msal refresh-token


    【解决方案1】:

    RefreshTokenParameter 是根据从 ADAL 而不是 MSAL 接收到的刷新令牌创建的,文档很清楚。

    MSAL for Java 有一个 API,允许您将 使用 ADAL4j 获取的刷新令牌迁移到 ClientApplication:acquireToken(RefreshTokenParameters)。

    然后在使用迁移码here之后,你会得到新的访问令牌和ID令牌,新的刷新令牌会被存储在缓存中,不会暴露。所以在你的情况下,如果你想直接获取刷新令牌,你仍然需要使用 ADAL。

    不知道为什么需要这个,因为刷新令牌的作用是获取新的访问令牌/ID令牌,要实现这一点,您可以轻松利用MSAL中的acquireTokenSilently

    【讨论】:

    • 感谢您对 RefreshTokenParameter 的快速响应和清晰。那么这是否意味着不再需要用于 grant_type=refresh 令牌的 oauth2 流程,其中 refresh_token 是强制性的?
    • @Yasmeen 是的,首先你要知道refresh token的作用,它只是用来获取新的access/id token,现在有了新的方式,为什么我们还需要使用老办法,对吧? RefreshTokenParameter 仅用于迁移。
    • 是的,我现在明白了,谢谢。最初查看下面的链接有点令人困惑,因为 MSAL 不再支持刷新令牌授予类型。 docs.microsoft.com/en-us/azure/active-directory/develop/…
    【解决方案2】:

    在包 MSAL 中,它提供了功能令牌缓存。它在获取令牌后缓存它。然后我们可以尝试使用acquireTokenSilently方法从缓存中静默刷新令牌。

    例如

    PublicClientApplication pca = PublicClientApplication.builder(CLIENT_ID)
                    .authority(AUTHORITY)
                    .build();
            Consumer<DeviceCode> deviceCodeConsumer = (DeviceCode deviceCode) ->
                    System.out.println(deviceCode.message());
            // get token for graph
            DeviceCodeFlowParameters parameters =
                    DeviceCodeFlowParameters
                            .builder(Collections.singleton("User.Read"), deviceCodeConsumer) 
                            .build();
            IAuthenticationResult result = pca.acquireToken(parameters).join();
    
    
            DecodedJWT jwt = JWT.decode(result.accessToken());
            System.out.println(jwt.getAudience().get(0));
    
            // refresh token
            Set<IAccount> accountsInCache = pca.getAccounts().join();
    
            IAccount account = accountsInCache.iterator().next();
            // get token for my own api
            SilentParameters silentParameters =
                    SilentParameters
                            .builder(Collections.singleton("api://872ebcec-c24a-4399-835a-201cdaf7d68b/access_as_user"), account)
                            .build();
            result = pca.acquireTokenSilently(silentParameters).join();
            jwt = JWT.decode(result.accessToken());
            System.out.println(jwt.getAudience().get(0));
    

    更多详情请参考

    https://docs.microsoft.com/en-us/azure/active-directory/develop/migrate-adal-msal-java#core-classes

    https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-acquire-cache-tokens#acquiring-tokens-silently-from-the-cache

    https://github.com/Azure-Samples/ms-identity-java-devicecodeflow

    【讨论】:

    • 感谢示例和参考链接。我已经尝试过静默令牌方法并且能够获得新的访问令牌,我的问题在于授权类型=刷新令牌流,因为根据 oauth2,我们假设将刷新令牌作为请求的一部分发送。但我认为这对于 Msal 实施是不可能的。
    猜你喜欢
    • 1970-01-01
    • 2021-05-10
    • 2020-02-02
    • 2020-01-17
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    相关资源
    最近更新 更多