Skip to content

Commit

Permalink
added api key authentication to aspnetcore 2.1 (#3089)
Browse files Browse the repository at this point in the history
updated samples
  • Loading branch information
MBcom authored and wing328 committed Jun 21, 2019
1 parent b6bb13b commit 1540ae7
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("Filters" + File.separator + "GeneratePathParamsValidationFilter.mustache",
packageFolder + File.separator + "Filters", "GeneratePathParamsValidationFilter.cs"));
}

supportingFiles.add(new SupportingFile("Authentication" + File.separator + "ApiAuthentication.mustache",packageFolder + File.separator + "Authentication", "ApiAuthentication.cs"));
}

public void setPackageGuid(String packageGuid) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace {{packageName}}.Authentication
{
public class ApiKeyRequirement : IAuthorizationRequirement
{
public IReadOnlyList<string> ApiKeys { get; set; }

public string PolicyName { get; set; }

public ApiKeyRequirement(IEnumerable<string> apiKeys, string policyName)
{
ApiKeys = apiKeys?.ToList() ?? new List<string>();
PolicyName = policyName;
}
}

public class ApiKeyRequirementHandler : AuthorizationHandler<ApiKeyRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ApiKeyRequirement requirement)
{
SucceedRequirementIfApiKeyPresentAndValid(context, requirement);
return Task.CompletedTask;
}

private void SucceedRequirementIfApiKeyPresentAndValid(AuthorizationHandlerContext context, ApiKeyRequirement requirement)
{
{{#authMethods}}{{#isApiKey}}
{{#-first}}
if (context.Resource is AuthorizationFilterContext authorizationFilterContext)
{
var apiKey = "";
{{/-first}}
{{#isKeyInHeader}}
apiKey = authorizationFilterContext.HttpContext.Request.Headers["{{keyParamName}}"].FirstOrDefault();
{{/isKeyInHeader}}
{{#isKeyInQuery}}
apiKey = authorizationFilterContext.HttpContext.Request.Query["{{keyParamName}}"].FirstOrDefault();
{{/isKeyInQuery}}
{{#isKeyInCookie}}
apiKey = authorizationFilterContext.HttpContext.Request.Cookies["{{keyParamName}}"] ?? null;
{{/isKeyInCookie}}
if (requirement.PolicyName == "{{name}}" && apiKey != null && requirement.ApiKeys.Any(requiredApiKey => apiKey == requiredApiKey))
{
context.Succeed(requirement);
}
{{#-last}}
}
{{/-last}}
{{/isApiKey}}{{/authMethods}}
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ using Newtonsoft.Json.Serialization;{{#useSwashbuckle}}
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using {{packageName}}.Filters;{{/useSwashbuckle}}
using {{packageName}}.Authentication;
using Microsoft.AspNetCore.Authorization;

namespace {{packageName}}
{
Expand Down Expand Up @@ -40,6 +42,22 @@ namespace {{packageName}}
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services)
{
{{#authMethods}}
{{#isApiKey}}
{{#-first}}
services.AddTransient<IAuthorizationHandler, ApiKeyRequirementHandler>();
services.AddAuthorization(authConfig =>
{
{{/-first}}
authConfig.AddPolicy("{{name}}",
policyBuilder => policyBuilder
.AddRequirements(new ApiKeyRequirement(new[] { "my-secret-key" },"{{name}}")));
{{#-last}}
});
{{/-last}}
{{/isApiKey}}
{{/authMethods}}

// Add framework services.
services
.AddMvc()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ namespace {{apiPackage}}
/// <param name="{{paramName}}">{{description}}</param>{{/allParams}}{{#responses}}
/// <response code="{{code}}">{{message}}</response>{{/responses}}
[{{httpMethod}}]
[Route("{{{basePathWithoutHost}}}{{{path}}}")]{{#hasAuthMethods}}{{#authMethods}}{{#isBasicBearer}}
[Route("{{{basePathWithoutHost}}}{{{path}}}")]{{#hasAuthMethods}}{{#authMethods}}{{#isApiKey}}
[Authorize(Policy = "{{name}}")]{{/isApiKey}}{{#isBasicBearer}}
[Authorize{{#hasScopes}}(Roles = "{{#scopes}}{{scope}}{{#hasMore}},{{/hasMore}}{{/scopes}}"){{/hasScopes}}]{{/isBasicBearer}}{{/authMethods}}{{/hasAuthMethods}}
[ValidateModelState]{{#useSwashbuckle}}
[SwaggerOperation("{{operationId}}")]{{#responses}}{{#dataType}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Org.OpenAPITools.Authentication
{
public class ApiKeyRequirement : IAuthorizationRequirement
{
public IReadOnlyList<string> ApiKeys { get; set; }

public string PolicyName { get; set; }

public ApiKeyRequirement(IEnumerable<string> apiKeys, string policyName)
{
ApiKeys = apiKeys?.ToList() ?? new List<string>();
PolicyName = policyName;
}
}

public class ApiKeyRequirementHandler : AuthorizationHandler<ApiKeyRequirement>
{

protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ApiKeyRequirement requirement)
{
SucceedRequirementIfApiKeyPresentAndValid(context, requirement);
return Task.CompletedTask;
}

private void SucceedRequirementIfApiKeyPresentAndValid(AuthorizationHandlerContext context, ApiKeyRequirement requirement)
{

if (context.Resource is AuthorizationFilterContext authorizationFilterContext)
{
var apiKey = "";
apiKey = authorizationFilterContext.HttpContext.Request.Headers["api_key"].FirstOrDefault();
if (requirement.PolicyName == "api_key" && apiKey != null && requirement.ApiKeys.Any(requiredApiKey => apiKey == requiredApiKey))
{
context.Succeed(requirement);
}

}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ public virtual IActionResult FindPetsByTags([FromQuery][Required()]List<string>
/// <response code="404">Pet not found</response>
[HttpGet]
[Route("/v2/pet/{petId}")]
[Authorize(Policy = "api_key")]
[ValidateModelState]
[SwaggerOperation("GetPetById")]
[SwaggerResponse(statusCode: 200, type: typeof(Pet), description: "successful operation")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public virtual IActionResult DeleteOrder([FromRoute][Required]string orderId)
/// <response code="200">successful operation</response>
[HttpGet]
[Route("/v2/store/inventory")]
[Authorize(Policy = "api_key")]
[ValidateModelState]
[SwaggerOperation("GetInventory")]
[SwaggerResponse(statusCode: 200, type: typeof(Dictionary<string, int?>), description: "successful operation")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using Org.OpenAPITools.Filters;
using Org.OpenAPITools.Authentication;
using Microsoft.AspNetCore.Authorization;

namespace Org.OpenAPITools
{
Expand Down Expand Up @@ -49,6 +51,13 @@ public Startup(IConfiguration configuration)
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IAuthorizationHandler, ApiKeyRequirementHandler>();
services.AddAuthorization(authConfig =>
{
authConfig.AddPolicy("api_key",
policyBuilder => policyBuilder
.AddRequirements(new ApiKeyRequirement(new[] { "my-secret-key" },"api_key")));
// Add framework services.
services
.AddMvc()
Expand Down

0 comments on commit 1540ae7

Please sign in to comment.