How to use Swagger in ASP.Net WebAPI 2.0 with token based authentication
Solution 1
I found the solution myself. I would like to share it in case anybody is facing the same problem. The solution is of 2 steps, first one is to request a token and the next step, is to add the token into the header request.
So the first step:
Customize the frontend to enable post request for requesting a token:
Add a AuthTokenOperation
class to enable which inherits the IDcoumentFilter
interface and implements the Apply method:
public class AuthTokenOperation : IDocumentFilter
{
/// <summary>
/// Apply custom operation.
/// </summary>
/// <param name="swaggerDoc">The swagger document.</param>
/// <param name="schemaRegistry">The schema registry.</param>
/// <param name="apiExplorer">The api explorer.</param>
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
{
swaggerDoc.paths.Add("/token", new PathItem
{
post = new Operation
{
tags = new List<string> { "Auth"},
consumes = new List<string>
{
"application/x-www-form-urlencoded"
},
parameters = new List<Parameter>
{
new Parameter
{
type = "string",
name = "grant_type",
required = true,
@in = "formData"
},
new Parameter
{
type = "string",
name = "username",
required = false,
@in = "formData"
},
new Parameter
{
type = "string",
name = "password",
required = false,
@in = "formData"
},
}
}
});
}
}
And in the SwaggerConfig class in the register method, add this action
c.DocumentFilter<AuthTokenOperation>();
to the extension method:
GlobalConfiguration.Configuration.EnableSwagger
To add the authorization token in the request header:
Add this operation class:
/// <summary>
/// The class to add the authorization header.
/// </summary>
public class AddAuthorizationHeaderParameterOperationFilter : IOperationFilter
{
/// <summary>
/// Applies the operation filter.
/// </summary>
/// <param name="operation"></param>
/// <param name="schemaRegistry"></param>
/// <param name="apiDescription"></param>
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
if (operation.parameters != null)
{
operation.parameters.Add(new Parameter
{
name = "Authorization",
@in = "header",
description = "access token",
required = false,
type = "string"
});
}
}
}
And in the SwaggerConfig class in the register method, add this action
c.OperationFilter<AddAuthorizationHeaderParameterOperationFilter>();
to the extension method:
GlobalConfiguration.Configuration.EnableSwagger
Of course in the Authoization field, you need to add: Bearer token_string
Solution 2
I just want to add something to the accepted answer that when autorest is used for client generation, the accepted answer is not complete for it misses the some properties.
[Fatal]OperationId is required for all operations. Please add it for 'post' operation of '/authenticate' path. Exception: There was an error during code generation when trying to add a client for the REST API Generating client code and adding to project failed Adding REST API client for failed
post = new Operation
{
operationId = "Auth_AccessToken",
tags = new List<string> { "Auth" },
produces = new List<string>
{
"application/json",
"text/json",
"application/xml",
"text/xml"
},
consumes = new List<string>
{
"application/x-www-form-urlencoded"
},
parameters = new List<Parameter>
{
new Parameter
{
type = "string",
name = "grant_type",
required = true,
@in = "formData"
},
new Parameter
{
type = "string",
name = "username",
required = true,
@in = "formData"
},
new Parameter
{
type = "string",
name = "password",
required = true,
@in = "formData"
},
new Parameter
{
type = "string",
name = "client_id",
required = true,
@in = "formData"
},
new Parameter
{
type = "string",
name = "client_secret",
required = true,
@in = "formData"
}
},
responses = new Dictionary<string, Response>
{
{"200", new Response{ description = "OK", schema = new Schema{ type = "object"} } }
}
}
you need to add the operationId and responses for autorest to work properly.
Related videos on Youtube
alaa_sayegh
My name is Alaa, staying in Germany. I'm a senior software developer as working as freelancer. I'm very attracted to new technologies and writing code is my passion.
Updated on August 17, 2021Comments
-
alaa_sayegh over 2 years
I have a ASP.Net WebApi with token based authentication and I want to use swagger to create documentation for this RestApi.
The Api has for now only 2 methods, one for requesting a token i.e.
http://localhost:4040/token
and the other one is for creating a notification. The returned bearer token is sent like follows:using (var client = new HttpClient()) { // setup client client.BaseAddress = new Uri("http://localhost:4040"); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var serializedNotification = new JavaScriptSerializer().Serialize(notification); var stringContent = new StringContent(serializedNotification, Encoding.UTF8, "application/json"); var response = await client.PostAsync("api/Notification", stringContent); response.EnsureSuccessStatusCode(); // return URI of the created resource. return response.Headers.Location; }
With swagger I can see the post Notification method, however I can't do a request because I don't have a token and I don't know how to do it in swagger.
-
Imbajoe over 4 yearsI used this method, and all the information shows up in swagger. However, when I try to get an auth token, I get an "error": "unsupported_grant_type" response back. Any idea what I might have done wrong? I'm using 'password' as the grant_type
-
Jeff Hartman about 4 yearsI had the same problem with "unsupported_grant_type". The issue with mine was the @in string is case sensitive, and I had it all lowercase. Changing it to formData like the example fixed my issue.
-
Sam White over 3 yearsThis method (attributed to this answer) has been presented in full detail by Tim Corey in one of his YouTube video tutorials. Link: youtube.com/watch?v=zQRgB6nasUc
-
Hamza Khanzada about 2 yearsReminding once again: Make sure you add
Bearer <token>
in the Authorization textbox when accessing a protected resource