Introduction
This repo is used to store the collection of standardized security packages for LCU
LCU.Library.Internal.ApiSecurity
Currently you can add API Key security to you API using this nuget package The following sample code will run the configuration code and add the required services to the applications service collection on startup
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "IntegrationTestApiTwo",
Version = "v1"
});
//Add Security Entry Fields In Swagger
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Id = HeaderKeys.ApiKey, // Must match the "AddSecurityDefinition"
Type = ReferenceType.SecurityScheme
}
},
new List<string>()
}
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Id = HeaderKeys.Client, // Must match the "AddSecurityDefinition"
Type = ReferenceType.SecurityScheme
}
},
new List<string>()
}
});
c.AddSecurityDefinition(HeaderKeys.ApiKey,
new OpenApiSecurityScheme
{
Description = HeaderKeys.ApiKey,
In = ParameterLocation.Header,
Name = HeaderKeys.ApiKey,
Type = SecuritySchemeType.ApiKey,
Scheme = "apikey"
});
c.AddSecurityDefinition(HeaderKeys.Client,
new OpenApiSecurityScheme
{
Description = HeaderKeys.Client,
In = ParameterLocation.Header,
Name = HeaderKeys.Client,
Type = SecuritySchemeType.ApiKey,
Scheme = "apikey"
});
});
builder.Services.AddApiKeySecurity(builder.Configuration);
There are two ways to implement API Key auth in a Web API
- Attribute: A more precise implementation that will only run the authentication against requests that hit endpoints tagged with the 'ApiKey' attribute within your controllers
[ApiKey]
public async Task<IActionResult> Get()
{
return Ok();
}
- Middleware: A blanket authentication solution that will authenticate all incoming requests
app.UseAuthorization();
app.UseMiddleware<ApiKeyMiddleware>();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
Extracting the auth logic from the Attribute & Middleware to a service class was explored and is possible but was rolled back to allow for custom logic updates to each respective authentication strategy
ApiSecurityConfiguration
ApiKeyAuthenticationFailureBehavior [ Default = Error ]
Authentication failure behavior enum
- Error: Log error on failure, return error to requesting client
- Warn: Log warning on failure, process request normally afterwards
ExternalApiKeySet [ Default = Null ]
Collection of authorized client-key combinations to authenticate incoming requests against
InternalApiKeySet [ Default = Null ]
Collection of authorized client-key combinations to be added to outbound requests requiring authentication
Sample Configuration
"ApiSecurityConfiguration": {
"ApiKeyAuthenticationFailureBehavior": "Warn",
"ExternalApiKeySet": {
"TestTenantTwo": "TestKeyTwo"
},
"InternalApiKeySet": {
"TestTenantOne": "TestKeyOne"
}
}
Azure AD Authentication
Open TopDesk ticket in Other Request category. Within ticket, request service account and group creation for each environment such as: Group: temenos_action_handler_qa User: svc_temenosaction_q Also ask that each group be placed into the Groups Organization unit (if this is not requested, the user name and password may inadvertently change).
In appsettings, add the following AzureAd node
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "landmarkcu.onmicrosoft.com",
"TenantId": "acquireFromDevOps",
"CallbackPath": "/signin-oidc",
"ClientId": "acquireFromDevOps",
"ClientSecret": "acquireFromDevOps",
"AzureKeyVaultUrl": "qa-ApiName-kv",
"Role": "Api_Name_QA",
"AuthenticationUrl": "https://login.microsoftonline.com/landmarkcu.onmicrosoft.com/oauth2/v2.0/token",
"Scope": "acquireFromDevOps"
}
In Program class, add configurations and services
using Azure.Identity;
using LCU.Library.Internal.Security.Service;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
var settings = builder.Configuration.GetSection("AzureAd");
var clientSecretCredentials = new ClientSecretCredential(
settings["TenantId"],
settings["ClientId"],
settings["ClientSecret"]);
builder.Configuration.AddAzureKeyVault(
new Uri($"https://{settings["AzureKeyVaultUrl"]}.vault.azure.net/"), clientSecretCredentials);
configuration.Bind<AzureAdJwtRetrievalConfiguration>(services, "AzureAd");
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
services.AddScoped<IAzureAdVerificationService, AzureAdVerificationService>();
Adding Policy Authentication from Azure AD Groups
Here is an example of using the Authentication portion of the library to add Azure AD Group-based authentication to your blazor application, by converting them to policies.
Program.cs
services.AddAzureAdGroupPolicyServices(configuration.GetSection("AzureAd"),
configuration.GetSection("Security"));
appsettings.json
"AzureAd": {
"TenantId": "GET FROM AZURE AD",
"ClientId": "GET FROM AZURE AD",
"ClientSecret": "GET FROM AZURE AD",
"Instance": "https://login.microsoftonline.com/",
"Domain": "landmarkcu.onmicrosoft.com",
"CallbackPath": "/signin-oidc",
"AuthenticationUrl": "https://login.microsoftonline.com/landmarkcu.onmicrosoft.com/oauth2/v2.0/token"
}
"Security": {
"AccessPolicies": {
"Admin": {
"Groups": "IT Development"
}
}
}