Reputation: 5720
I have an ASP.Net 5 Web API which is secured using The Microsoft.identity.Web package, so it is backed by Azure Active Directory. The authentication in the API itself is working fine and without any problems.
I'm struggling when I want to get the authorization to work inside Swagger UI. I'm using the Authorization code flow and everything seems fine at first (I get to the Microsoft login screen, can enter my credentials and receive an authorization code).
However after Swagger UI got the authorization code, it calls the token endpoint at https://login.microsoftonline.com/organizations/oauth2/v2.0/token. The response from that call is 99% percent fine, except that it is missing the Allow-Origin-Header so the response is blocked by the browser itself and cannot reach the Swagger UI JavaScript which would then set the token it received from that response.
What am I missing here to get that header in the response?
This is the code in my 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" }
}
});
});
This is the request which is sent from Swagger UI to 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
This is the response
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"}
Upvotes: 3
Views: 3042
Reputation: 5720
The problem was that I was using the AuthorizationCode
-Flow which is only suitable for backend applications, because the client secret needs to be transmitted there.
The correct way was to use the Implicit
-Flow while keeping everything else the same. That flow is intended for JS applications where it is impossible to securely send a client secret without the user being able to see it.
Upvotes: 0