我和我的同事目前正在开发一款Reaction应用程序,该应用程序应该会在Teams应用程序store 上分发.

我们从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;

团队工具包创建的Azure AD App注册仅为单租户,我们无法在其上启用多租户,因此我们决定手动创建一个新的多租户.从那里,我们编辑了应用程序 list ,使其与它需要使用的新Azure AD应用程序相匹配.

此后,SSO身份验证不再起作用,用户每次单击按钮时都会生成以下错误:Get SSO token failed with error: App resource defined in manifest and iframe origin do not match

我们已判断应用程序 list 和Azure AD应用程序注册 list ,但找不到该问题. 我们联系了微软以获得有关此问题的帮助,他们让我们在StackOverflow上发布此信息,因此我们在此:)

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

以下是应用程序 list 和Azure AD应用程序注册 list ,或许你可以找到我们遗漏的错误:

应用程序 list

{
    "$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应用注册 list

{
    "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
}

谢谢

推荐答案

我和他一起工作,我们设法解决了这个问题.

在我们用来托管应用程序的Azure存储帐户上,我们添加了CDN并为其配置了新的自定义域名(例如:myappname.mydomain.fr)

在Azure AD应用程序注册上:

  1. authentication选项卡中,我们更改了重定向URI以匹配自定义域
  2. expose an API选项卡中,我们更新了应用程序ID URI,将部件myappname.mycompanyname.fr替换为自定义域.因此,我们的新ID URI将为api://myappname.mydomain.fr/myMultiTenantAzureADAppId

在应用程序 list 上:

  1. 我们将每一次迭代m365tabxxxxxx.z6.web.core.windows.net替换为 我们的新自定义域
  2. 我们更改webApplicationInfo: ressource部分以匹配新的ID URI.

Reactjs相关问答推荐

MUImaterial -ui-如何将文本字段和 Select 分组?

过滤对象数组并通过迭代对象数组将属性放入新数组

react 表复选框不对任何操作做出react

NextJS(AppRouter)、Apollo(客户端),在根布局中使用ApolloProvider时出错

Next.js-图像组件加载问题

Formik验证不适用于物料UI自动完成

如何在与AntD的react 中限制文件上传和显示消息?

在url中使用MongoDB对象ID被认为是不好的做法?

如何在REACTIVE js中动态添加或删除输入字段?

定位数组中的一项(React、useState)

警告:遇到两个子元素拥有同一把 keys .键应该是唯一的,以便组件在更新时保持其身份

Mui 在 TextField 标签上添加工具提示显示两个工具提示框

useRef.current.value 为空值

如何实现 redux 工具包来注册用户?

使用 React.UseEffect 从 api 获取但我的清理返回不起作用

Cypress ,重试不再附加到 DOM 的元素

导航到屏幕时,react 本机上下文状态变为未定义

从 API 中提取映射数组后出现重复元素

单击三个按钮之一后如何显示特定按钮的内容?单击其中一个按钮后应隐藏所有按钮

Material UI 安装和 React v. 18.2 出现问题