I am upgrading my ASP.NET Core 5 Web API security from implicit to authorization code. The authentication is done using Azure A/D and I also need to allow Swagger docs to be used.
I have managed to make it work, but client_secret is useless in my case and I am wondering if I am doing something wrong. My configuration is as follows:
Azure A/D
- Redirect URIs: https://localhost:44444/swagger/oauth2-redirect.html
- API permissions: Microsoft Graph + custom role (
access_as_user
) - Tokens: Access tokens and ID tokens are unchecked
appsettings.json
"AzureAd": {
"Instance": "https://login.microsoftonline.com",
"ClientId": "xxxxxxxx-xxxxxxxxx",
"TenantId": "xxxxxxxx-xxxxxxxxx"
},
Startup.cs
services.AddMicrosoftIdentityWebApiAuthentication(Configuration);
private static void AddSwagger(IServiceCollection services, AzureAdAuthOptions auth)
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Foo API", Version = "v1", });
AddSwaggerDocs_IncludeXmlComments(c);
c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme()
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows()
{
AuthorizationCode = new OpenApiOAuthFlow()
{
AuthorizationUrl = new Uri($"{auth.Instance}/{auth.TenantId}/oauth2/v2.0/authorize"),
TokenUrl = new Uri($"{auth.Instance}/{auth.TenantId}/oauth2/v2.0/token"),
Scopes = { { $"api://{auth.ClientId}/access_as_user", "Access as user" } }
}
}
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "oauth2"
}
},
new string[] { }
}
});
});
}
Swagger
- oauth2 (OAuth2, authorizationCode)
- Application: Foo - Swagger
- Authorization URL: https://login.microsoftonline.com//oauth2/v2.0/authorize
- Token URL: https://login.microsoftonline.com//oauth2/v2.0/token
- client_id: already filled in
- client_secret
Scopes: only one, api://<guid>/access_as_user
If I authorize without the secret, it works correctly. However, if I provide the secret I receive the following error:
Auth ErrorError: Unauthorized, error: invalid_client, description: AADSTS700025: Client is public so neither 'client_assertion' nor 'client_secret' should be presented. Trace ID: dbb64172-2bbb-4392-8fc5-0ee71ab9c301 Correlation ID: 8c7edd8b-b6d0-435b-abeb-158b3278c3fe Timestamp: 2021-05-27 07:21:14Z
I thought the secret is required to make the authentication process more secure, but I do not seem to be able to use it. What am I doing wrong?
Double checked and allowPublicClient
is false. I have switched from SPA to Web client, provided the secret, but I receive the following error:
Auth ErrorError: Bad Request, error: invalid_request, description: AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type. Trace ID: 6e11093f-319b-4d75-92b9-c6a39775a501 Correlation ID: afcd9152-ccd5-4588-ae75-0b829272d66d Timestamp: 2021-05-28 06:10:58Z
So, it seems that I am stuck with the SPA client when using Swagger UI.