【问题标题】:Retrieve emails on behalf of user flow from Hotmail using Microsoft Identity Platform and MSAL.NET使用 Microsoft Identity Platform 和 MSAL.NET 从 Hotmail 中代表用户流检索电子邮件
【发布时间】:2020-04-23 20:31:43
【问题描述】:

我想要的只是能够从 Hotmail 中检索电子邮件,我认为这很容易。

我一直在研究如何通过 OAuth 从 Hotmail 中检索电子邮件,现在我走到了死胡同。

这是我的首选架构:

我现在知道的是:

  1. 我需要使用 Microsoft Graph 来检索用户的电子邮件
  2. 我需要在我的 WebApi 项目中使用 OBO(代表)流来获取访问令牌并执行操作

将有2个项目:

1 WebApi 用于处理从 Hotmail、Gmail 等检索到的电子邮件。 1 用于 Web UI 的 WebApp SPA (React.js)

我基本上浏览了所有相关的 Microsoft 文档(例如 Microsoft Identity Platform、MSAL.NET)并找到了这两个我认为与我的项目相关的演示项目:

  1. WebApp calls WebApi to fetch user information. The WebApi calls Microsoft Graph to get emails from Hotmail
  2. SPA (JavaScript) web app to call Microsoft Graph

在 SPA 上,当我运行它的演示项目时(我已经在配置中替换了应用程序 ID),我发现演示项目只在 Edge 中工作(只有登录用户部分工作),它甚至不工作火狐。

我搜索了错误消息,但没有运气。

我已经想不出如何让我的解决方案发挥作用了。


更新 1:

我曾尝试以react + Asp.Net Core project 为例。 我同时运行了 asp.net webapi runnint 和 Reactjs 前端: 但是 reactjs 应用程序总是显示这个:

这是 Reactjs 应用程序地址栏中的 url:

https://login.microsoftonline.com/02xxxxxxx/oauth2/authorize?response_type=id_token&client_id=02xxxx&redirect_uri=https%3A%2F%2Flocalhost%3A3000&state=3b3e49f5-3fff-4249-b3ee-e4f28a87b3dd&client-request-id=2063333f-7dab-4afe-9922-4fe2909ccf37&x-client-SKU=Js&x-client-Ver=1.0.17&nonce=51c7f91f-1c87-4d4b-808b-082433370b39

这里是 My Asp.Net Core WebApi(Papayee) 和 Reactjs 客户端 (PapayeeClient) 的清单

收款人:

{
    "id": "22xxxx",
    "acceptMappedClaims": null,
    "accessTokenAcceptedVersion": 2,
    "addIns": [],
    "allowPublicClient": false,
    "appId": "28xxx12",
    "appRoles": [],
    "oauth2AllowUrlPathMatching": true,
    "createdDateTime": "2020-04-03T03:59:12Z",
    "groupMembershipClaims": null,
    "identifierUris": [
        "https://papayee008.onmicrosoft.com/papayee008"
    ],
    "informationalUrls": {
        "termsOfService": null,
        "support": null,
        "privacy": null,
        "marketing": null
    },
    "keyCredentials": [],
    "knownClientApplications": [],
    "logoUrl": null,
    "logoutUrl": "https://localhost:44321/signout-oidc",
    "name": "Papayee",
    "oauth2AllowIdTokenImplicitFlow": true,
    "oauth2AllowImplicitFlow": true,
    "oauth2Permissions": [
        {
            "adminConsentDescription": "Allow Papayee to access user's emails for filtering billing emails",
            "adminConsentDisplayName": "Papayee User Impersonation",
            "id": "20xxx7a",
            "isEnabled": true,
            "lang": null,
            "origin": "Application",
            "type": "User",
            "userConsentDescription": "Allow Papayee to access user's emails for filtering billing emails",
            "userConsentDisplayName": "Papayee",
            "value": "user_impersonation"
        },
        {
            "adminConsentDescription": "This is used to retrieve your emails and find your bills",
            "adminConsentDisplayName": "Access Papayee as a user",
            "id": "98xxx15a",
            "isEnabled": true,
            "lang": null,
            "origin": "Application",
            "type": "User",
            "userConsentDescription": "This is used to retrieve your emails and find your bills",
            "userConsentDisplayName": "Access Papayee as a user",
            "value": "access_as_user"
        }
    ],
    "oauth2RequirePostResponse": false,
    "optionalClaims": {
        "idToken": [],
        "accessToken": [],
        "saml2Token": []
    },
    "orgRestrictions": [],
    "parentalControlSettings": {
        "countriesBlockedForMinors": [],
        "legalAgeGroupRule": "Allow"
    },
    "passwordCredentials": [
        {
            "customKeyIdentifier": null,
            "endDate": "2021-04-03T06:44:48.449Z",
            "keyId": "c0xxx110",
            "startDate": "2020-04-03T06:45:01.778Z",
            "value": null,
            "createdOn": "2020-04-03T06:45:10.0053885Z",
            "hint": "7uu",
            "displayName": "papayee"
        }
    ],
    "preAuthorizedApplications": [],
    "publisherDomain": "papayee008.onmicrosoft.com",
    "replyUrlsWithType": [
        {
            "url": "https://localhost:3000",
            "type": "Web"
        },
        {
            "url": "https://localhost:44302/",
            "type": "Web"
        },
        {
            "url": "https://localhost:44302/signin-oidc",
            "type": "Web"
        },
        {
            "url": "https://localhost:44351",
            "type": "Web"
        },
        {
            "url": "http://localhost:5000/",
            "type": "Web"
        },
        {
            "url": "https://localhost:5001/",
            "type": "Web"
        },
        {
            "url": "https://localhost:8666",
            "type": "Web"
        },
        {
            "url": "https://localhost:44394/",
            "type": "InstalledClient"
        },
        {
            "url": "https://login.microsoftonline.com/common/oauth2/nativeclient",
            "type": "InstalledClient"
        },
        {
            "url": "https://localhost",
            "type": "Web"
        },
        {
            "url": "https://localhost:44394/signin-oidc",
            "type": "Web"
        },
        {
            "url": "https://localhost:44394",
            "type": "Web"
        }
    ],
    "requiredResourceAccess": [
        {
            "resourceAppId": "28xxxx12",
            "resourceAccess": [
                {
                    "id": "98xxxx5a",
                    "type": "Scope"
                },
                {
                    "id": "20xxxx7a",
                    "type": "Scope"
                }
            ]
        },
        {
            "resourceAppId": "0fxxxxa0",
            "resourceAccess": [
                {
                    "id": "1fxxx6a",
                    "type": "Scope"
                }
            ]
        },
        {
            "resourceAppId": "00xxx00",
            "resourceAccess": [
                {
                    "id": "18xxx10",
                    "type": "Scope"
                },
                {
                    "id": "3bxxxd5",
                    "type": "Scope"
                }
            ]
        },
        {
            "resourceAppId": "00xxx00",
            "resourceAccess": [
                {
                    "id": "64xxxd0",
                    "type": "Scope"
                },
                {
                    "id": "74xxx82",
                    "type": "Scope"
                },
                {
                    "id": "37xxx6e",
                    "type": "Scope"
                },
                {
                    "id": "14xxxc1",
                    "type": "Scope"
                },
                {
                    "id": "5cxxx65",
                    "type": "Scope"
                },
                {
                    "id": "57xxxca",
                    "type": "Scope"
                },
                {
                    "id": "02xxx73",
                    "type": "Scope"
                },
                {
                    "id": "e1xxxx3d",
                    "type": "Scope"
                },
                {
                    "id": "b4xxx4c",
                    "type": "Scope"
                }
            ]
        }
    ],
    "samlMetadataUrl": null,
    "signInUrl": null,
    "signInAudience": "AzureADandPersonalMicrosoftAccount",
    "tags": [],
    "tokenEncryptionKeyId": null
}

这是 PapayeeClient 的清单

{
    "id": "59xxxxe9",
    "acceptMappedClaims": null,
    "accessTokenAcceptedVersion": 2,
    "addIns": [],
    "allowPublicClient": null,
    "appId": "02xxx60",
    "appRoles": [],
    "oauth2AllowUrlPathMatching": false,
    "createdDateTime": "2020-04-13T22:34:14Z",
    "groupMembershipClaims": null,
    "identifierUris": [],
    "informationalUrls": {
        "termsOfService": null,
        "support": null,
        "privacy": null,
        "marketing": null
    },
    "keyCredentials": [],
    "knownClientApplications": [],
    "logoUrl": null,
    "logoutUrl": null,
    "name": "PapayeeClient",
    "oauth2AllowIdTokenImplicitFlow": true,
    "oauth2AllowImplicitFlow": true,
    "oauth2Permissions": [],
    "oauth2RequirePostResponse": false,
    "optionalClaims": null,
    "orgRestrictions": [],
    "parentalControlSettings": {
        "countriesBlockedForMinors": [],
        "legalAgeGroupRule": "Allow"
    },
    "passwordCredentials": [],
    "preAuthorizedApplications": [],
    "publisherDomain": "papayee008.onmicrosoft.com",
    "replyUrlsWithType": [
        {
            "url": "https://localhost:3000/",
            "type": "Web"
        },
        {
            "url": "https://localhost:8080/",
            "type": "Web"
        }
    ],
    "requiredResourceAccess": [
        {
            "resourceAppId": "28xxx12",
            "resourceAccess": [
                {
                    "id": "98xxx5a",
                    "type": "Scope"
                },
                {
                    "id": "20xxx7a",
                    "type": "Scope"
                }
            ]
        },
        {
            "resourceAppId": "00xxx00",
            "resourceAccess": [
                {
                    "id": "64xxxd0",
                    "type": "Scope"
                },
                {
                    "id": "74xxx82",
                    "type": "Scope"
                },
                {
                    "id": "37xxxx6e",
                    "type": "Scope"
                },
                {
                    "id": "14xxxc1",
                    "type": "Scope"
                },
                {
                    "id": "57xxxxca",
                    "type": "Scope"
                },
                {
                    "id": "02xxx73",
                    "type": "Scope"
                },
                {
                    "id": "e1xxxxx3d",
                    "type": "Scope"
                }
            ]
        }
    ],
    "samlMetadataUrl": null,
    "signInUrl": null,
    "signInAudience": "AzureADandPersonalMicrosoftAccount",
    "tags": [],
    "tokenEncryptionKeyId": null
}

【问题讨论】:

    标签: oauth-2.0 azure-active-directory azure-ad-graph-api msal msal.js


    【解决方案1】:

    你的架构是完全正确的。你的场景是客户端调用你的webapi服务器->webapi服务器调用Microsoft Graph API

    以下是对您的项目有帮助的示例:

    A memo on how to implement Azure AD authentication using React and .NET Core

    Call a downstream web API (Microsoft Graph) from a web API secured with the Microsoft identity platform (Azure Active Directory) using the On-Behalf-Of flow

    【讨论】:

    • 嗨@TonyJu 非常感谢您的帮助。我已经尝试了您提供的第一个示例,当我运行 React 前端时,它总是返回“未通过身份验证”。我将更新我的问题以包括我尝试过的内容和 reactjs webapp
    • @Franva,我正在研究类似的架构,SPA --> Web API --> Graph API。启用 CORS 策略后,我就能够通过身份验证。我的 SPA 和 Web Api 项目使用不同的端口,导致 Web Api 项目中的 Authorization 标头为空。启用 Cors 后,授权标头被填充,我就可以调用 Web API。目前,仍在为 Web API 部分的用户同意而苦苦挣扎。但是,这是一个不同的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 2016-04-19
    • 1970-01-01
    • 2011-08-20
    • 2015-07-20
    • 2020-12-11
    • 1970-01-01
    相关资源
    最近更新 更多