Swagger Authentication against Azure AD B2C
By Ankit Sharma and Isha Gupta.
If you've been trying to get Swagger to authenticate against Azure AD B2C but realized that it doesn't work the way it does with traditional AD, you have landed at the right page. Azure AD B2C is different from the traditional AD in a lot of ways, and hence this authentication integration also works quite differently. After beating our head around it for quite some time, we felt it was our responsibility to save our fellows developers from this trauma.
In order to integrate Swagger UI with Azure AD B2C authentication, we need to create 2 applications.
- Web App Application: The first application represents the Web API app.
- Swagger UI Application: The second application represents the Swagger UI which enables it to authenticate to the Web API.
We need to follow the following steps:
-
- Create the first AD application as mentioned above – Web Application.
Go to your azure portal, select your Azure AD B2C Account and click to create a new application of type "Web App".
Provide details to create this application. The name of the application could be any unique identifier amongst all applications in your AD B2C and AppID URI can also be any unique identifier.
Note: The replyUrl mentioned here is not used for any redirection, so it doesn't need to be the actual Web API url. Any valid URL would work here.
Once you click on Create, you will be able to see your application along with its application ID on the Applications page.
Click on the application to view the application details. Since this application won't be directly used for authentication, we don't need to create any keys.
In the published scope, we'd be able to see a default scope added.
We need to add another scope here which will enable the Swagger application to authenticate against the Web App.
- Create the first AD application as mentioned above – Web Application.
Scope | read_write |
Description | Read Write Access To WebAPI |
Note: The Scope Name mentioned here is the actual text that is shown across the checkbox when we try to authenticate a user from the Swagger UI as shown in the later part of this post. Anything that is intuitive to users can be added here
.
Now we'd create the second application – Swagger UI application.
Using the same process as defined in point 1.a.
The reply URL in this application is extremely important. This should be the URL of the application where we wish to enable Swagger.
https://{your_application_url}/swagger/ui/o2c-html
Alternatively, this can be a static dedicated common URL, which can be used as a kind of application realm.
There is no need of App ID URI here. Also make sure that the implicit flow is set to yes.After the app is created, we need to go to the application details. Here comes the part that enables the authentication mechanism. We need to enable the API access to the Web App we created in the previous step.
Add a new API Access to allow it to access the Web App with both the defined scopes.
Voila, we have created both our applications.
Note: We don't need to create any keys for this application as well. It's because this application doesn't authenticate a request, but enables the user to authenticate himself by presenting a sign in page.
Now we will tweak our web application to enable Azure AD B2C authentication.
We assume that you have already done the initial setup for integrating swagger using Swashbuckle. If not, please follow this link.
Go to Swagger.Config file in your solution and add the following code.
GlobalConfiguration.Configuration .EnableSwagger(c => { c.SingleApiVersion(“v1”, “Demo App”); c.IncludeXmlComments(@“\bin\DemoApp.XML”); c.OAuth2("oauth2") .Description("OAuth2 Implicit Grant") .Flow("implicit) .AuthorizationUrl(@”https://login.microsoftonline.com/testdemodomain/oauth2/v2.0/authorize”) .Scopes( scopes => { scopes.Add(“https://testdemodomain.onmicrosoft.com/demowebapp/read_write”, “Access APIs”); }); c.OperationFilter(); }) .EnableSwaggerUi( c => { c.EnableOAuth2Support(“9099f811-e886-475d-80ca-456ae0af1da8”, null, null, null, null, additionalQueryStringParams: new Dictionary() { { “p”, “MySignInPolicy” }}); });
Let's look at the Oauth2 method here, which is of prime importance in this whole procedure.
c.Oauth2 ("oauth2") B2C only works with OAuth2, so don't try to change this line. .Description("OAuth2 Implicit Grant") Simple text description. .Flow("implicit") Specifying the flow is important here. Remember, we created an implicit flow while creating the Azure AD B2C application for Swagger. .AuthorizationUrl() https://login.microsoftonline.com//oauth2/v2.0/authorize .Scopes( Add the additional scope here that we created for the web App. We cannot stress enough how important it to give the scope correctly.Pay great attention to the format of the scope. The AppID URI of the Azure AD B2C Application where the scope is hosted and the scope value is used to create this URL./ c.OperationFilter Add your operation filter here that you'll create in the next step. c.EnableOAuth2Support( The first parameter is the client ID for your Swagger Azure application.We don't need to provide other values like secret, realm etc. as this application doesn't do authentication but only facilitates it for the user.We need to add the sign in policy that our application is using using the additional query parameters dictionary.{"p", ""} In the newly added Operation filter ( AddAuthorizationAttribute in our case), the Apply method should look like the following:
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { if (operation.security == null) { operation.security = new List<IDictionary<string, IEnumerable>>(); } // Add the appropriate security definition to the operation var scopes = new List() { "https://testdemodomain.onmicrosoft.com/demowebapp/read_write" }; var openAuthRequirements = new Dictionary<string, IEnumerable> { { “oauth2”, scopes } }; operation.security.Add(openAuthRequirements); }
Similarly, we need to add the newly added scope in the Operationfilter as well.
This is how your Web API should look like now.
Comments
- Anonymous
September 07, 2017
Good work - Anonymous
September 11, 2017
Hi ! This was very helpful.