【问题标题】:Is it possible to obtain an Azure AD V1 token using MSAL?是否可以使用 MSAL 获取 Azure AD V1 令牌?
【发布时间】:2019-06-19 11:20:17
【问题描述】:

我目前正在为我的应用设置带有 MSAL 的 ADD。我遇到的问题是 api 设置为接受 Azure AD V1 令牌,但使用我当前的 MSAL 设置,我一直收到 Azure AD V2。

我团队中的其他人正在使用 ADAL,但我们想迁移到 MSAL。我确定我做错了什么,因为似乎很难相信没有向后兼容性。

这是我的 Msal 配置:

import * as Msal from 'msal';

export const applicationConfig = {
    clientID: process.env.REACT_APP_MSAL_CLIENT_ID,
    authority: process.env.REACT_APP_AUTHORITY_TENANT,
    graphScopes: ['user.read'],
    graphEndpoint: process.env.REACT_APP_GRAPH_ENDPOINT,
};

/**
 * will get the call back once the API is complete
 * (either complete or failure), redirects flows.
 * Is called after the authentication request is completed
 * successfully/failure
 *
 * @param {*} errorDesc
 * @param {*} token
 * @param {*} error
 * @param {*} tokenType
 */
const tokenReceivedCallback = async (errorDesc, token, errorMsg) => {
    try {
        if (token) console.log('Success!');
    } catch (error) {
        throw new Error(`${errorMsg}:${errorDesc}`);
    }
};

/**
 * Instantiate UserAgentApplication
 */
const userAgentApplication = new Msal.UserAgentApplication(
    applicationConfig.clientID,
    applicationConfig.authority,
    tokenReceivedCallback,
    {
        cacheLocation: process.env.REACT_APP_CACHE_LOCATION,
        redirectUri: process.env.REACT_APP_REDIRECT_URI,
    },
);

/**
 * Log user in
 * Checks if there is no user and if there is no
 * callback occuring within the window url which throws into
 * infinite loop, then login, and redirect to SSO login
 * @param {*} graphScopes
 */
export const signIn = async graphScopes => {
    console.log(graphScopes);
    /**
     * avoid duplicate code execution on page load in case of iframe and popup window
     */
    if (!userAgentApplication.getUser() && !userAgentApplication.isCallback(window.location.hash)) {
        /**
         * login site, and go directly to SSO
         */
        await userAgentApplication.loginRedirect(graphScopes, process.env.REACT_APP_DOMAIN);
        /**
         * acquireTokenSilent method makes a silent request to ADD to obtain an access token.
         * ADD returns an access token containing the user consented scopes to allow
         * the app to securely call the api
         */
        await userAgentApplication.acquireTokenSilent(graphScopes);
    }
};

/**
 * Logs user out
 */
export const logOut = () => userAgentApplication.logout();

这是我使用 jwt.ms 时得到的:

提前致谢!

【问题讨论】:

  • 这些范围不是 Graph API 而不是你的 API 吗?您在哪里为您的 API 请求令牌?
  • 嗨@juunas 感谢您的快速回复。我不确定我是否遵循您问题的第一部分。我认为范围适用于graphAPI,loginRedirect() 属于MSAL() 对象。我向graph.windows请求我的令牌
  • 您正在为 Graph API 请求访问令牌。那不是您的 API,因此它不尊重您的令牌版本设置。您需要更改范围以匹配您的 API 标识符。
  • github.com/AzureAD/microsoft-authentication-library-for-dotnet/… 向您展示了一些示例。您通常会使用 app id URI + /.default 或某些特定范围。如果您想为客户端和 API 使用相同的应用注册,我不记得是否有所不同。
  • 如果 API 尚不存在,您可以从 Azure 门户创建应用 ID URI

标签: azure authentication azure-active-directory adal msal


【解决方案1】:

是的,可以从 V2 端点请求 V1 访问令牌。颁发给客户端应用程序的访问令牌类型(v1 或 v2)由资源 API 的应用程序注册决定。正如其他人指出的那样,您的示例代码请求 Microsoft Graph 范围,并且 Microsoft Graph 应用程序注册配置为接受 v2 令牌。您可以通过查看应用注册来确定您的 API 配置为接受哪种类型的令牌。在 portal.azure.com 中,打开“App registrations (Preview)”,转到“Manifest”部分,然后查找属性“accessTokenAcceptedVersion”。如果设置为 null 或 1,那么所有请求访问令牌以调用此资源的客户端应用程序都将获得一个 v1 访问令牌(无论它们使用 MSAL 还是 ADAL 来请求访问令牌)。

ADAL 应用调用 v1 资源 API 的常见调用模式是提供资源 URI 作为范围。这告诉端点为资源 API 的应用注册中配置的所有权限颁发访问令牌。 MSAL(使用 v2 端点)允许请求任何范围,无论它是否位于资源的应用注册范围的静态列表中。要获得与 ADAL(使用 v1 端点)相同的行为,请将“.default”附加到资源 URI(例如“https://contoso.onmicrosoft.com/V1TodoListService/.default”)

在 Ignite,我演示了一个仅接受 v1 访问令牌的现有待办事项列表服务,我浏览了我的新 MSAL 客户端应用程序的整个门户配置以请求 v1 访问令牌并调用此服务。在这里观看:https://youtu.be/77A47CfNqIU?t=3120

【讨论】:

  • 出于好奇,您是如何知道将 .default 添加到资源 URI 的?
  • @saeed-akhter 您知道 CRM 的资源(范围)是什么吗?从您所说的情况来看,https://crm-instance.crm4.dynamics.com/.default 应该是这种情况。获取token时没有错误但里面定义了错误的受众,使用token时CRM给出401。来自MSAL的token有aud定义为:00000007-0000-0000-c000-000000000000,来自adal的token有:https://crm-instance.crm4.dynamics.com
  • @CircusRanger 一种可能性 - 您是否请求多个范围,包括 Microsoft Graph 的其他范围之一?可以为多个受众提供一个范围列表,以最大限度地减少最终用户看到的同意屏幕的数量,但随后要为每个受众获取访问令牌,有必要仅使用与相关的范围发出单独的请求以收集访问令牌那个观众。
  • @saeed-akhter 我已经尝试了所有的组合。有和没有 graphApi 资源(范围)。我基本上没有成功获得 DynamicsCRM(仅适用于 CRM)的令牌(通过 MSAL)。相同的应用程序用户、设置等适用于 ADAL。我试图定义的是protectedResourceMap 和consenseScopes 字段。加重因素是 MSAL 获取令牌没有任何错误,但是当我尝试访问 CRM webapi 端点时它不起作用。您是否有任何提示 MsalModule.forRoot 对象在 D365 中应该看起来如何?
  • @CircusRanger,感谢您确认范围不是问题。我目前正在外面度假,但我给办公室里的几个人发了消息,让他们看看。您可以在 GitHub 上上传任何重现该问题的示例代码吗?这可能有助于他们加快调查。
猜你喜欢
  • 2021-03-19
  • 1970-01-01
  • 2020-03-10
  • 2021-12-28
  • 2022-01-02
  • 2020-10-17
  • 2022-08-03
  • 2020-10-16
  • 2021-01-03
相关资源
最近更新 更多