azure - 为什么 MSAL loginPopup 响应“应用程序客户端要求资源上不存在的范围”?

标签 azure azure-active-directory single-page-application access-token azure-ad-msal

(继续问题:Why is my SPA, which is calling my WebAPI, using Azure Active Directory, receiving "Authorization has been denied for this request."?)

我的客户端 SPA 正在尝试调用 protected WebAPI(服务)。客户端使用 MSAL(Micosoft 身份验证库)。问题发生在调用 API 之前,即下图中 1 和 2 之间的某个位置。

enter image description here

这是客户端

<!DOCTYPE html>
<html>
<head>
    <title>Quickstart for MSAL JS</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.4/bluebird.min.js"></script>
    <script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.2/js/msal.js"></script>
</head>
<body>
    <div class="container">
        <div>
            <button id="GetTodos" onclick="getTodos()">Get Todos</button>
        </div>
    </div>
    <script>

        var msalConfig = {
            auth: {
                clientId: 'xxxxxxxxxxxxxxxxxxxxxxx2427', 
                authority: "https://login.microsoftonline.com/my.tenant"
            },
            cache: {
                cacheLocation: "sessionStorage",
                storeAuthStateInCookie: true
            }
        };


        var requestObj = {
            // scopes: ["user.read"]
            scopes: ["access_as_user"]
        };

        var myMSALObj = new Msal.UserAgentApplication(msalConfig);

        myMSALObj.handleRedirectCallback(authRedirectCallBack);

        function getTodos() {
            console.log("getTodos ...");

            myMSALObj.loginPopup(requestObj)
                .then(response => {
                    myMSALObj.acquireTokenPopup(requestObj).then(function (tokenResponse) {

                        var xmlHttp = new XMLHttpRequest();
                        xmlHttp.onreadystatechange = function () {
                            if (this.readyState == 4 && this.status == 200) {
                                console.log("success");
                                //this.responseText
                            } else {
                                console.log("failure");
                            }
                        }
                        const apiUrl = "https://localhost:44321/api/todolist";
                        xmlHttp.open("GET", apiUrl, true); // true for asynchronous
                        xmlHttp.setRequestHeader('Authorization', 'Bearer ' + tokenResponse.accessToken);
                        xmlHttp.send();

                    }).catch(function (error) {
                        console.log(error);
                    });
                })
                .catch(err => {
                    // handle error
                    console.log("login popup failed.", err);
                });
        }


        function authRedirectCallBack(error, response) {
            console.log('authRedirectCallBack');
            if (error) {
                console.log(error);
            } else {
                if (response.tokenType === "access_token") {
                    console.log("response.tokenType === access_token");
                } else {
                    console.log("token type is:" + response.tokenType);
                }
            }
        }

    </script>
</body>
</html>

客户端和服务都是在 Azure Active Directory 上注册的应用

enter image description here

客户端具有访问服务的 API 权限。

enter image description here

并且该服务确实公开了范围为 access_as_user 的 API

enter image description here

但是调用

myMSALObj.loginPopup(requestObj)

原因

ServerError: "AADSTS650053: The application 'ClientSPA' asked for scope 'access_as_user' that doesn't exist on the resource '00000003-0000-0000-c000-000000000000'.

当使用 Chrome 时,我收到此消息

enter image description here

进一步调查

我不要求范围“access_as_user”,而是要求“user.read” 这给了我一个访问 token 。但这会导致 WebAPI 响应

Authorization has been denied for this request

当我解码访问 token 时,我看到观众是 https://graph.microsoft.com 。但我期望观众是“https://my.tenant/TodoListService-NativeDotNet” ”。请参见下图(混淆的行确实包含特定于我的用户和我注册的应用程序的信息)

enter image description here

问题

  1. 资源“00000003-0000-0000-c000-000000000000”ID 来自哪里(错误消息中提到)?它不是客户端或服务的应用程序 ID。

  2. 我在 Azure Active Directory 上的配置或客户端中做错了什么?

  3. CORS 会成为问题吗?我已将服务设置为允许 CORS。

最佳答案

范围应包括公开资源的标识符(应用程序 ID URI)。您可以通过转到“公开 API”-> 编辑范围-> 复制顶部的标签来找到完整值...

var requestObj = {
    // scopes: ["https://graph.microsoft.com/user.read"]
    scopes: ["https://ServiceWebAPI/TodoListService-NativeDotNet-access_as_user"]
};

有关各个范围的进一步阅读:https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#requesting-individual-user-consent

关于azure - 为什么 MSAL loginPopup 响应“应用程序客户端要求资源上不存在的范围”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56951054/

相关文章:

vue.js - 路由器链接绑定(bind)到 b 卡图像

powershell - 如何将 msi 从 Visual Studio Online 部署到 azure vm?

Azure 公开 API 与 API 权限

azure - 访问 IIS 托管的 Web 应用程序,该应用程序通过 PowerShell 使用 AzureAD 凭据来使用 API

angularjs - 如何在angular ui-router中将对象发送到操作方法

javascript - 如何使用非 Node.js 后端构建现代前端?

Azure 存储队列 - 是否有用于设置有害消息 TTL 的应用程序范围配置

azure - 标准网站 (Windows Azure) 上的 Crystal Reports

asp.net-mvc - Azure 云服务中的安全异常

azure - 使用 azure 帐户用户名和密码在 azure 中获取访问 token