I'm looking at implementing a simple authentication mechanism based on the old PAT or API-Key in the header system. Ultimately, I want the user to provide two headers during a request that requires authentication. A Client-Id and their Token. In Postman, it simply would look like this:
and have managed to achieve this, largely by adapting to what I found here
https://stackoverflow.com/a/61365691/4087918
My definitions look like this
c.AddSecurityDefinition("API-Key", new OpenApiSecurityScheme
{
Description = "API Key required to access the api.",
In = ParameterLocation.Header,
Name = "API-Key",
Type = SecuritySchemeType.ApiKey
});
c.AddSecurityDefinition("Client-ID", new OpenApiSecurityScheme
{
Description = "Client ID required to access the api.",
In = ParameterLocation.Header,
Name = "Client-ID",
Type = SecuritySchemeType.ApiKey
});
c.OperationFilter<ApiKeyHeaderFilter>();
and my filter a little like this:
operation.Security.Add(
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Name = "API-Key",
Type = SecuritySchemeType.ApiKey,
In = ParameterLocation.Header,
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "API-Key"
}
},
new string[] { }
}
}
operation.Security.Add(
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Name = "Client-ID",
Type = SecuritySchemeType.ApiKey,
In = ParameterLocation.Header,
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Client-ID"
}
},
new string[] { }
}
}
);
And the result is like so
with the curl request being generated correctly like so
curl -X GET "https://localhost:44394/Configuration/application-key" -H "accept: text/plain" -H "API-Key: token" -H "Client-ID: client-id"
Importantly, I didn't want to have to define the requirement for the Client-ID by decorating each authorised endpoint with a [FromHeader] param or use a SwaggerHeader attribute etc I just want the two headers to be accessible via the Swagger UI so the user could authenticate their requests.
So my question, finally. I have decided that two values are required to authenticate a request but is this the right way to go about it, I mean in terms of convention etc. Or, should I go down a basic auth route, and provide the Client-ID
as username
and API-Key
as password
, or is there an alternative approach I may want to consider?
Side Note: This app is a little too simple to consider the use of JWT and the implementation of an authority service.