Files
2026-03-24 09:49:29 -05:00

210 lines
6.3 KiB
Markdown

# 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
```C#
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
```C#
[ApiKey]
public async Task<IActionResult> Get()
{
return Ok();
}
```
- Middleware: A blanket authentication solution that will authenticate
all incoming requests
```C#
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
```C#
"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
```C#
"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
```C#
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
```C#
services.AddAzureAdGroupPolicyServices(configuration.GetSection("AzureAd"),
configuration.GetSection("Security"));
```
appsettings.json
```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"
}
```
```json
"Security": {
"AccessPolicies": {
"Admin": {
"Groups": "IT Development"
}
}
}
```