I created an asp.net webapi application which is using Individual Account Security so that the Bearer token is enabled by default. It's working fine so that I am able to test them in Postman without problem.
Here comes the question when I'm trying to integrate the Swagger UI by Swashbuckle. I installed the Swashbuckle by:
Install-Package Swashbuckle
Then change the SwaggerConfig.cs:
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.ApiKey("Token")
.Description("Filling bearer token here")
.Name("Authorization")
.In("header");
}
.EnableSwaggerUi(c =>
{
c.EnableApiKeySupport("Authorization", "header");
};
Start my application and fill in the Bearer token:
But it doesn't work when I run the api request which need authorization. Here is the screenshot:
The bearer token is added to Authorization in header. But I still got error 401. I'm wondering if it's because the token is encoded (the SPACE is replaced by %20)? Any idea? Thanks.
By the way, I'm wondering how to add the /token in my Swagger document too so that I can get the token in Swagger UI.
Update
The issue detailed below is now resolved in Swashbuckle v5.5.0.
Issue
Just ran into the exact same issue. I think the root cause is this line in Swashbuckle's source code:
var key = encodeURIComponent($('#input_apiKey')[0].value);
This is where the value from the HTML input field goes through URL encoding turning the space into %20
. I'm planning to open an issue in the Swashbuckle repo on GitHub.
Workaround
Until that issue is resolved, here is a workaround based on replacing the above line using a Javascript file injected into the Swagger UI:
In the project where you have Swashbuckle installed, create a new folder and call it "Swagger".
In the new folder create a new Javascript file called "SwaggerUiCustomization.js" and put this script in it:
(function () {
function addApiKeyAuthorization() {
var key = $('#input_apiKey')[0].value;
if (key && key.trim() != "") {
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization(swashbuckleConfig.apiKeyName, key, swashbuckleConfig.apiKeyIn);
window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
log("added key " + key);
}
}
$('#input_apiKey').change(addApiKeyAuthorization);
})();
In the Solution Explorer, choose the file and hit Alt+Enter to edit its Properties. In the Properties window change the file's Build Action to Embedded Resource.
In your SwaggerConfig.cs file add the following line inside the EnableSwaggerUi()
code block:
c.InjectJavaScript(thisAssembly,
"<Project_Default_Namespace>.Swagger.SwaggerUiCustomization.js");
Be sure, of course, to replace <Project_Default_Namespace>
with your project's default namespace.
Run your project and enter "Bearer " into the text box. When you invoke a controller action, you should get this exact same value - with a whitespace instead of %20%
- on the server side.
Note: this example uses Json Web Tokens.
Your code can be set up so "Bearer" isn't required in the authorization string.
Code in WebApi project to retrieve token (see token = ... in the code segment below):
private static bool TryRetrieveToken(HttpRequestMessage request, out string token)
{
token = null;
IEnumerable<string> authzHeaders;
if (!request.Headers.TryGetValues("Authorization", out authzHeaders) || authzHeaders.Count() > 1)
{
return false;
}
var bearerToken = authzHeaders.ElementAt(0);
token = bearerToken.StartsWith("Bearer ") ? bearerToken.Substring(7) : bearerToken;
return true;
}
Swagger ApiKey:
c.ApiKey("Authorization")
.Description("Filling bearer token here")
.Name("Bearer")
.In("header");
Swagger Enable ApiKey Support:
c.EnableApiKeySupport("Authorization", "header");
Pasting token into Api_Key form element in Swagger UI:
How it looks in the request header in Swagger: