让 Microsoft.Identity(以前的 AzureAD)与 Swagger 一起工作

Getting Microsoft.Identity (former AzureAD) to work with Swagger

我有一个 ASP.Net 5 Web API,它使用 Microsoft.identity.Web 包进行保护,因此它由 Azure Active Directory 提供支持。 API 本身的身份验证工作正常,没有任何问题。

当我想获得在 Swagger 内部工作的授权时,我很挣扎 UI。 我正在使用授权代码流程,一开始一切似乎都很好(我进入 Microsoft 登录屏幕,可以输入我的凭据并接收授权代码)。

然而,在 Swagger UI 获得授权码后,它会在 https://login.microsoftonline.com/organizations/oauth2/v2.0/token 调用令牌端点。 该调用的响应是 99% 的正常,除了它缺少 Allow-Origin-Header 因此响应被浏览器本身阻止并且无法到达 Swagger UI JavaScript 然后将设置它从该响应中收到的令牌。

为了在响应中得到 header,我在这里缺少什么?

这是我Startup.cs

中的代码
services.AddSwaggerGen(c =>
{
    c.AddSecurityDefinition("msid", new Microsoft.OpenApi.Models.OpenApiSecurityScheme
    {
        Type = Microsoft.OpenApi.Models.SecuritySchemeType.OAuth2,
        Flows = new Microsoft.OpenApi.Models.OpenApiOAuthFlows
        {
            AuthorizationCode = new Microsoft.OpenApi.Models.OpenApiOAuthFlow
            {
                AuthorizationUrl = new System.Uri("https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize"),
                TokenUrl = new System.Uri("https://login.microsoftonline.com/organizations/oauth2/v2.0/token"),
                Scopes = new Dictionary<string, string>
                {
                    { "api://myClientId/access", "access" }
                }
            }
        }
    });

    c.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement
    {
        {
            new Microsoft.OpenApi.Models.OpenApiSecurityScheme
            {
                Reference = new Microsoft.OpenApi.Models.OpenApiReference {Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme, Id = "msid" }
            },
            new [] { "api://myClientId/access" }
        }
    });
});

这是从 Swagger UI 发送到 https://login.microsoftonline.com/organizations/oauth2/v2.0/token

的请求
POST https://login.microsoftonline.com/organizations/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Connection: keep-alive
Content-Length: 1086
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: "Chromium";v="94", "Microsoft Edge";v="94", ";Not A Brand";v="99"
Accept: application/json, text/plain, */*
Content-Type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4585.0 Safari/537.36 Edg/94.0.972.0
sec-ch-ua-platform: "Windows"
Origin: https://localhost:5003
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://localhost:5003/
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.9,en;q=0.8,en-US;q=0.7

grant_type=authorization_code&code=hereIsMyLongAuthorizationCode&redirect_uri=https%3A%2F%2Flocalhost%3A5003%2Fswagger%2Foauth2-redirect.html

这是回复

HTTP/1.1 200 OK
Cache-Control: no-store, no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
x-ms-request-id: 683dc687-7211-400b-ab02-bccdc6e9ba00
x-ms-ests-server: 2.1.11898.12 - WEULR1 ProdSlices
report-to: {"group":"network-errors","max_age":86400,"endpoints":[{"url":"https://identity.nel.measure.office.net/api/report?catId=GW+estsfd+dub2"}]}
nel: {"report_to":"network-errors","max_age":86400,"success_fraction":0.001,"failure_fraction":1.0}
Set-Cookie: fpc=...; expires=Fri, 03-Sep-2021 13:57:11 GMT; path=/; secure; HttpOnly; SameSite=None
Set-Cookie: x-ms-gateway-slice=estsfd; path=/; secure; samesite=none; httponly
Set-Cookie: stsservicecookie=estsfd; path=/; secure; samesite=none; httponly
Referrer-Policy: strict-origin-when-cross-origin
Date: Wed, 04 Aug 2021 13:57:10 GMT
Content-Length: 1763

{"token_type":"Bearer","scope":"api://myClientId/access","expires_in":3599,"ext_expires_in":3599,"access_token":"theToken"}

问题是我使用的是仅适用于后端应用程序的 AuthorizationCode-Flow,因为客户端密钥需要传输到那里。

正确的方法是使用 Implicit-Flow,同时保持其他一切不变。该流程适用于无法在用户无法看到的情况下安全发送客户端机密的 JS 应用程序。