Configure Swagger to authenticate against Azure AD
If you are building a Web API secured by Azure AD you will need to authenticate to test the API. Configuring OAuth 2 in Swagger allows you to authenticate using the Swagger UI and test the API with the necessary authentication headers.
The steps to configure this are:
- Create a Web API project
- Register an Azure AD (AAD) app for the Web API
- Update the Web API project to use Azure AD authentication
- Register an AAD app for the Swagger web site
- Grant permissions for the Swagger AAD app to access the Web API AAD app
- Generate a Client Secret for the Swagger AAD app
- Enable OAuth2 implicit flow on the Swagger AAD app
- Add Swagger to the Web API project
The example below is for a .NET Core 2.1 Web API application using Swashbuckle.AspNetCore 3.0.0:
1. Create a Web API project
The first step is to create a new Web API project either using Visual Studio or via the command line:
md AspNetCore.AzureAd.Swagger cd AspNetCore.AzureAd.Swagger dotnet new webapi
If you open and run the project in Visual Studio you should see the values returned from the default controller.
2. Register an Azure AD (AAD) app for the Web API
To authenticate against Azure AD you need to add an Azure AD app registration. This can be done via the Azure portal at http://portal.azure.com.
http://portal.azure.com > Azure Active Directory > App Registrations > New application registration
When the app registration is complete copy the Application ID into notepad as we will need it later
3. Update the Web API project to use Azure AD authentication
Add the following nuget package
Microsoft.AspNetCore.Authentication.AzureAD.UI
In the Startup.cs file replace the ConfigureServices method with the following:
services.AddAuthentication(AzureADDefaults.JwtBearerAuthenticationScheme) .AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
services.AddMvc(config => { var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); config.Filters.Add(new AuthorizeFilter(policy)); }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
This will require all requests to be authenticated.
Also in the Startup.cs file add the following to the Configure method (before the app.UseMvc() line):
app.UseAuthentication();
In appsettings.json add the following (remember to move sensitive information out of here before committing to source control e.g. use manage user secrets):
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "<Domain>", "TenantId": "<Directory ID>", "ClientId": "<Application ID>" }, "Swagger": { "ClientId": "<Swagger:Application ID>", "ClientSecret": "<Swagger:Key Value>" }
Copy in the Application ID from step 2 into the ClientId value and grab the domain and directory from the Azure Portal as shown below:
In the ValuesController.cs file update the Get method to include the user name so we can verify the request has been authenticated:
public ActionResult<IEnumerable<string>> Get() { return new string[] { "value1", User.Identity.Name }; }
Run the application and verify it returns a 401 unauthorised error (as the browser doesn’t provide an authentication token):
4. Register an AAD app for the Swagger web site
We will now add a AAD app for the Swagger web site and grant it permission to make requests into the Web API app.
http://portal.azure.com > Azure Active Directory > App Registrations > New application registration. Enter the base URL for the project you created in step 1 followed by /swagger/oauth2-redirect.html in the Sign-on URL field.
Copy the Application ID into the Swagger:ClientId setting in appsettings.json created in step 3
Settings > Reply URLs > Ensure there is a reply URL of https://localhost:<web api port>/swagger/oauth2-redirect.html
5. Grant permissions for the Swagger AAD app to access the Web API AAD app
Settings > Required Permissions > Add > Select an API > Search for ‘Web API’ and select this from the list
Check ‘Access Web API’, click select, then click done
6. Generate a Client Secret for the Swagger AAD app
Settings > Keys > Add a Key named ‘Key 1’ set to never expire and click Save. Copy the key value into the Swagger:ClientSecret setting in appsettings.config.
7. Enable OAuth2 implicit flow on the Swagger AAD app
Edit the manifest and change oauth2AllowImplicitFlow to true
8. Add Swagger to the Web API project
Add the following nuget package swashbuckle.aspnetcore (this is tested with 3.0.0)
Add the following code to Startup.cs in the ConfigureServices method:
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" }); c.AddSecurityDefinition("oauth2", new OAuth2Scheme { Type = "oauth2", Flow = "implicit", AuthorizationUrl = $"https://login.microsoftonline.com/{Configuration["AzureAD:TenantId"]}/oauth2/authorize", Scopes = new Dictionary<string, string> { { "user_impersonation", "Access API" } } }); c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> { { "oauth2", new[] { "user_impersonation" } } }); });
Add the following code to the Configure method:
app.UseSwagger(); app.UseSwaggerUI(c => { c.OAuthClientId(Configuration["Swagger:ClientId"]); c.OAuthClientSecret(Configuration["Swagger:ClientSecret"]); c.OAuthRealm(Configuration["AzureAD:ClientId"]); c.OAuthAppName("My API V1"); c.OAuthScopeSeparator(" "); c.OAuthAdditionalQueryStringParams(new { resource = Configuration["AzureAD:ClientId"] }); c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); });
Change the start page in Visual Studio to open swagger
Run the project and verify you can authenticate and access the API after clicking the ‘Authorize’ button.
You should now see the Bearer authentication token passed in the authorization header and the identity of the logged in user displayed in the result.
I’ve posted the full code to the following github repo:
https://github.com/aribakker/AspNetCore.AzureAd.Swagger
This article is based on information in the following articles with changes where sections are out of date:
Finally a working instruction. I’m very happy with this. Thanks for writing this down. I came across a lot of out dated info, and Swagger/Swagger-UI also had a nasty bug that prevented this from working.
KUDOS!
Saber Karmous
15 Jan 19 at 9:30 am
Hello, this is a very nice article.
I am trying to make a multi-tenant login but sadly I can’t log in when the user is outside the tenant.
Do you have such experience?
Thanks in advance!
Best regards,
Dafinka
Dafinka Gerdjikova
23 Aug 19 at 2:47 pm