Skip to content

Instantly share code, notes, and snippets.

@justinyoo
Last active February 9, 2024 16:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justinyoo/7a9dab5304ef36c8747a3c0cf8430b71 to your computer and use it in GitHub Desktop.
Save justinyoo/7a9dab5304ef36c8747a3c0cf8430b71 to your computer and use it in GitHub Desktop.
Securing Azure Functions Endpoints via OpenAPI Auth
public static class ApiKeyInQueryAuthFlowHttpTrigger
{
[FunctionName(nameof(ApiKeyInQueryAuthFlowHttpTrigger))]
[OpenApiOperation(operationId: "apikey.query", tags: new[] { "apikey" }, Summary = "API Key authentication code flow via querystring", Description = "This shows the API Key authentication code flow via querystring", Visibility = OpenApiVisibilityType.Important)]
[OpenApiSecurity("apikeyquery_auth",
SecuritySchemeType.ApiKey,
In = OpenApiSecurityLocationType.Query,
Name = "code")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Dictionary<string, string>), Summary = "successful operation", Description = "successful operation")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var queries = req.Query.ToDictionary(q => q.Key, q => (string) q.Value);
var result = new OkObjectResult(queries);
return await Task.FromResult(result).ConfigureAwait(false);
}
}
public static class ApiKeyInHeaderAuthFlowHttpTrigger
{
[FunctionName(nameof(ApiKeyInHeaderAuthFlowHttpTrigger))]
[OpenApiOperation(operationId: "apikey.header", tags: new[] { "apikey" }, Summary = "API Key authentication code flow via header", Description = "This shows the API Key authentication code flow via header", Visibility = OpenApiVisibilityType.Important)]
[OpenApiSecurity("apikeyheader_auth",
SecuritySchemeType.ApiKey,
In = OpenApiSecurityLocationType.Header,
Name = "x-functions-key")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Dictionary<string, string>), Summary = "successful operation", Description = "successful operation")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var headers = req.Headers.ToDictionary(q => q.Key, q => (string) q.Value);
var result = new OkObjectResult(headers);
return await Task.FromResult(result).ConfigureAwait(false);
}
}
public static class HttpBasicAuthFlowHttpTrigger
{
[FunctionName(nameof(HttpBasicAuthFlowHttpTrigger))]
[OpenApiOperation(operationId: "http.basic", tags: new[] { "http" }, Summary = "Basic authentication token flow via header", Description = "This shows the basic authentication token flow via header", Visibility = OpenApiVisibilityType.Important)]
[OpenApiSecurity("basic_auth",
SecuritySchemeType.Http,
Scheme = OpenApiSecuritySchemeType.Basic)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Dictionary<string, string>), Summary = "successful operation", Description = "successful operation")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var headers = req.Headers.ToDictionary(q => q.Key, q => (string) q.Value);
var result = new OkObjectResult(headers);
return await Task.FromResult(result).ConfigureAwait(false);
}
}
public static class HttpBearerAuthFlowHttpTrigger
{
[FunctionName(nameof(HttpBearerAuthFlowHttpTrigger))]
[OpenApiOperation(operationId: "http.bearer", tags: new[] { "http" }, Summary = "Bearer authentication token flow via header", Description = "This shows the bearer authentication token flow via header", Visibility = OpenApiVisibilityType.Important)]
[OpenApiSecurity("bearer_auth",
SecuritySchemeType.Http,
Scheme = OpenApiSecuritySchemeType.Bearer,
BearerFormat = "JWT")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(Dictionary<string, string>), Summary = "successful operation", Description = "successful operation")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var headers = req.Headers.ToDictionary(q => q.Key, q => (string) q.Value);
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(headers["Authorization"].Split(' ').Last());
var claims = token.Claims.Select(p => p.ToString());
var content = new { headers = headers, claims = claims };
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
}
public static class OAuthImplicitAuthFlowHttpTrigger
{
[FunctionName(nameof(OAuthImplicitAuthFlowHttpTrigger))]
[OpenApiOperation(operationId: "oauth.flows.implicit", tags: new[] { "oauth" }, Summary = "OAuth implicit flows", Description = "This shows the OAuth implicit flows", Visibility = OpenApiVisibilityType.Important)]
[OpenApiSecurity("implicit_auth",
SecuritySchemeType.OAuth2,
Flows = typeof(ImplicitAuthFlow))]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(IEnumerable<string>), Summary = "successful operation", Description = "successful operation")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var headers = req.Headers.ToDictionary(p => p.Key, p => (string) p.Value);
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(headers["Authorization"].Split(' ').Last());
var claims = token.Claims.Select(p => p.ToString());
var result = new OkObjectResult(claims);
return await Task.FromResult(result).ConfigureAwait(false);
}
}
public class ImplicitAuthFlow : OpenApiOAuthSecurityFlows
{
private const string AuthorisationUrl =
"https://login.microsoftonline.com/{0}/oauth2/v2.0/authorize";
private const string RefreshUrl =
"https://login.microsoftonline.com/{0}/oauth2/v2.0/token";
public ImplicitAuthFlow()
{
var tenantId = Environment.GetEnvironmentVariable("OpenApi__Auth__TenantId");
this.Implicit = new OpenApiOAuthFlow()
{
AuthorizationUrl = new Uri(string.Format(AuthorisationUrl, tenantId)),
RefreshUrl = new Uri(string.Format(RefreshUrl, tenantId)),
Scopes = { { "https://graph.microsoft.com/.default", "Default scope defined in the app" } }
};
}
}
public static class OpenIDConnectAuthFlowHttpTrigger
{
[FunctionName(nameof(OpenIDConnectAuthFlowHttpTrigger))]
[OpenApiOperation(operationId: "openidconnect", tags: new[] { "oidc" }, Summary = "OpenID Connect auth flows", Description = "This shows the OpenID Connect auth flows", Visibility = OpenApiVisibilityType.Important)]
[OpenApiSecurity("oidc_auth",
SecuritySchemeType.OpenIdConnect,
OpenIdConnectUrl = "https://login.microsoftonline.com/{tenant_id}/v2.0/.well-known/openid-configuration",
OpenIdConnectScopes = "openid,profile")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(IEnumerable<string>), Summary = "successful operation", Description = "successful operation")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var headers = req.Headers.ToDictionary(p => p.Key, p => (string) p.Value);
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(headers["Authorization"].Split(' ').Last());
var claims = token.Claims.Select(p => p.ToString());
var content = new { headers = headers, claims = claims };
var result = new OkObjectResult(content);
return await Task.FromResult(result).ConfigureAwait(false);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment