配置 Azure AD 应用程序以进行多租户 SSO 登录

问题描述 投票:0回答:1

我和我的同事目前正在开发一个 React 应用程序,该应用程序应该在 Teams 应用程序商店中分发。

我们从 Teams Toolkit 的 VS Code 中提供的 React 模板开始,并设法让 SSO 与 Teams Toolkit 创建的 Azure AD 应用程序注册一起使用。这是我们用来登录用户的代码的简化版本:

import { TeamsUserCredential } from "@microsoft/teamsfx";
import { useNavigate } from "react-router-dom";


interface IProps {
    teamsUserCredential?: TeamsUserCredential
}

const LoginPage = (props: IProps) => {

    const navigate = useNavigate();

    const login = async () => {
        try {
            await props.teamsUserCredential?.login(["User.Read", "User.ReadBasic.All"]);
            navigate("/home");
        }
        catch(e: any) {
            console.log("User did not logged", e);
        }
    }
    
    return (
        <div >
            <p>You need to login</p>
            <button onClick={login}>Login</button>
        </div>
    )
}

export default LoginPage;

Teams Toolkit 创建的 Azure AD 应用程序注册只是单租户,我们无法在其上启用多租户,因此我们决定手动创建一个新的多租户。从那里,我们编辑了应用程序清单,以便它与需要使用的新 Azure AD 应用程序相匹配。

此后,SSO 身份验证不再起作用,每次用户单击该按钮时都会生成以下错误:

Get SSO token failed with error: App resource defined in manifest and iframe origin do not match

我们已经检查了应用程序清单和Azure AD应用程序注册清单,但找不到问题。 我们联系了 Microsoft 以获取有关此问题的帮助,他们告诉我们将此问题发布在 StackOverflow 上,所以我们就到了:)

请注意,我们的应用程序托管在 Azure 存储帐户上,并且我们使用如下 URL 访问它:https://m365tabxxxxxx.z6.web.core.windows.net

这里是应用程序清单和Azure AD应用程序注册清单,也许您可以找到我们错过的错误:

应用清单

{
    "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.12/MicrosoftTeams.schema.json",
    "version": "1.0.15",
    "manifestVersion": "1.12",
    "id": "myappid",
    "packageName": "fr.mycompanyname.myappname",
    "name": {
        "short": "myappname",
        "full": "myappname"
    },
    "developer": {
        "name": "mycompanyname",
        "mpnId": "0000000",
        "websiteUrl": "https://www.mycompanyname.fr/en/",
        "privacyUrl": "https://www.mycompanyname.fr/privacy-policy/",
        "termsOfUseUrl": "https://www.mycompanyname.fr/en/legal-informations/"
    },
    "description": {
        "short": "My app is nice",
        "full": "My app is nice but longer..."
    },
    "icons": {
        "outline": "outline.png",
        "color": "color.png"
    },
    "accentColor": "#FFFFFF",
    "staticTabs": [
        {
            "entityId": "index0",
            "name": "Personal Tab",
            "contentUrl": "https://m365tabxxxxxx.z6.web.core.windows.net/index.html#/tab",
            "websiteUrl": "https://m365tabxxxxxx.z6.web.core.windows.net/index.html#/tab",
            "scopes": [
                "personal"
            ]
        }
    ],
    "validDomains": [
        "myappname.mycompanyname.fr",
        "m365tabxxxxxx.z6.web.core.windows.net"
    ],
    "webApplicationInfo": {
        "id": "myMultiTenantAzureADAppId",
        "resource": "api://myappname.mycompanyname.fr/myMultiTenantAzureADAppId"
    },
    "localizationInfo": {
        "defaultLanguageTag": "en-us",
        "additionalLanguages": [
            {
                "languageTag": "fr",
                "file": "fr.json"
            }
        ]
    },
    "publisherDocsUrl": "https://www.mycompanyname.fr/en/help-page/"
}

Azure AD 应用程序注册清单

{
    "id": "MyAADAppObjectId",
    "acceptMappedClaims": null,
    "accessTokenAcceptedVersion": 2,
    "addIns": [],
    "allowPublicClient": true,
    "appId": "myMultiTenantAzureADAppId",
    "appRoles": [],
    "oauth2AllowUrlPathMatching": false,
    "createdDateTime": "2023-12-12T16:41:59Z",
    "description": null,
    "certification": null,
    "disabledByMicrosoftStatus": null,
    "groupMembershipClaims": null,
    "identifierUris": [
        "api://myappname.mycompanyname.fr/myMultiTenantAzureADAppId"
    ],
    "informationalUrls": {
        "termsOfService": "https://www.mycompanyname.fr/en/legal-informations/",
        "support": null,
        "privacy": "https://www.mycompanyname.fr/privacy-policy/",
        "marketing": null
    },
    "keyCredentials": [],
    "knownClientApplications": [],
    "logoUrl": "https://mylogourl",
    "logoutUrl": null,
    "name": "myappname-multi-tenant",
    "notes": null,
    "oauth2AllowIdTokenImplicitFlow": true,
    "oauth2AllowImplicitFlow": true,
    "oauth2Permissions": [
        {
            "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.",
            "adminConsentDisplayName": "Teams can access app's web APIs",
            "id": "my_access_as_user_id",
            "isEnabled": true,
            "lang": null,
            "origin": "Application",
            "type": "User",
            "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have",
            "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf",
            "value": "access_as_user"
        }
    ],
    "oauth2RequirePostResponse": false,
    "optionalClaims": null,
    "orgRestrictions": [],
    "parentalControlSettings": {
        "countriesBlockedForMinors": [],
        "legalAgeGroupRule": "Allow"
    },
    "passwordCredentials": [
        {
            "customKeyIdentifier": null,
            "endDate": "2025-12-12T10:10:24.569Z",
            "keyId": "myKeyId",
            "startDate": "2023-12-13T10:10:24.569Z",
            "value": null,
            "createdOn": "2023-12-13T10:10:42.6188671Z",
            "hint": "---",
            "displayName": "Password uploaded on Wed Dec 13 2023"
        }
    ],
    "preAuthorizedApplications": [
        {
            "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", /*Microsoft Teams Web Client*/
            "permissionIds": [
                "my_access_as_user_id"
            ]
        },
        {
            "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", /*Microsoft Teams*/
            "permissionIds": [
                "my_access_as_user_id"
            ]
        }
    ],
    "publisherDomain": "mycompanyname.fr",
    "replyUrlsWithType": [
        {
            "url": "https://m365tabxxxxxx.z6.web.core.windows.net",
            "type": "Web"
        },
        {
            "url": "https://m365tabxxxxxx.z6.web.core.windows.net/blank-auth-end.html",
            "type": "Spa"
        },
        {
            "url": "https://m365tabxxxxxx.z6.web.core.windows.net/auth-end.html",
            "type": "Web"
        }
    ],
    "requiredResourceAccess": [
        {
            "resourceAppId": "00000003-0000-0000-c000-000000000000", /*Microsoft Graph*/
            "resourceAccess": [
                {
                    "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", /*User.Read*/
                    "type": "Scope"
                },
                {
                    "id": "b340eb25-3456-403f-be2f-af7a0d370277", /*User.ReadBasic.All*/
                    "type": "Scope"
                }
            ]
        }
    ],
    "samlMetadataUrl": null,
    "signInUrl": "https://www.mycompanyname.fr/en",
    "signInAudience": "AzureADandPersonalMicrosoftAccount",
    "tags": [],
    "tokenEncryptionKeyId": null
}

谢谢

reactjs azure microsoft-graph-api single-sign-on microsoft-teams
1个回答
1
投票

错误消息“获取 SSO 令牌失败,出现错误:清单中定义的应用程序资源与 iframe 源不匹配”表示应用程序清单中定义的应用程序资源与 iframe 源不匹配。

要解决此问题,您需要确保应用清单中定义的应用资源与 iframe 源匹配。

1.检查应用程序清单:打开应用程序清单文件(manifest.json)并验证 webApplicationInfo 部分包含正确的 id 和资源值。 ID 应与 Azure AD 应用程序注册的应用程序(客户端)ID 匹配,并且资源应与 Azure 存储帐户上托管的 React 应用程序的 URL 匹配 (https://m365tabxxxxxx.z6.web.core.windows.net ).

2.验证 Azure AD 应用程序注册:转到 Azure 门户并导航到手动创建的 Azure AD 应用程序注册。确保应用程序(客户端)ID 与应用程序清单中的 id 值匹配。另外,检查重定向 URI 并确保您的 React 应用程序的 URL 被列为有效的重定向 URI。

3.更新应用程序清单:如果您对 Azure AD 应用程序注册进行了任何更改(例如更新重定向 URI),则需要相应地更新应用程序清单。使用正确的 ID 和资源值更新应用程序清单中的 webApplicationInfo 部分。

4.测试应用程序:进行必要的更改后,重建应用程序并将其重新部署到 Teams。再次测试 SSO 身份验证流程并查看问题是否解决。

以下是

webApplicationInfo
部分在应用程序清单中的外观示例:

"webApplicationInfo": {
  "id": "<Azure AD app registration Application (client) ID>",
  "resource": "https://m365tabxxxxxx.z6.web.core.windows.net"
}

另请参阅:在具有 Microsoft Entra ID 的 Teams 中使用 SSO 的选项卡身份验证概述

© www.soinside.com 2019 - 2024. All rights reserved.