Kemenkeu.Authorization.Core
1.1.0
dotnet add package Kemenkeu.Authorization.Core --version 1.1.0
NuGet\Install-Package Kemenkeu.Authorization.Core -Version 1.1.0
<PackageReference Include="Kemenkeu.Authorization.Core" Version="1.1.0" />
paket add Kemenkeu.Authorization.Core --version 1.1.0
#r "nuget: Kemenkeu.Authorization.Core, 1.1.0"
// Install Kemenkeu.Authorization.Core as a Cake Addin #addin nuget:?package=Kemenkeu.Authorization.Core&version=1.1.0 // Install Kemenkeu.Authorization.Core as a Cake Tool #tool nuget:?package=Kemenkeu.Authorization.Core&version=1.1.0
Kemenkeu.Authorization.Core
The Kemenkeu.Authorization.Core
library provides an easy-to-use mechanism for filtering API responses based on allowed attributes. It supports dynamic configuration through IAM APIs, Redis caching, and fine-grained control using method-level attributes.
Features
- Filter response properties dynamically based on user-specific allowed attributes.
- Support for nested objects and arrays of objects in response filtering.
- Fetch allowed attributes from an IAM API with support for bearer tokens.
- Redis caching to improve performance.
- Configurable Redis endpoint and IAM API URL via
appsettings.json
. - Simple integration using attributes.
Installation
NuGet Package Add the NuGet package to your project:
dotnet add package Kemenkeu.Authorization.Core
Register Services Register
AuthorizationService
and caching inProgram.cs
:builder.Services.AddKemenkeuAuthorization(builder.Configuration);
Configuration
Add the following section to your appsettings.json
:
{
"AuthService": {
"IamUrl": "https://example.com/api/allowed-attributes",
"RedisEndpoint": "localhost",
"RedisPort": 6379,
"RedisPassword": "your_redis_password"
}
}
Key | Description |
---|---|
IamUrl |
URL of the IAM API to fetch attributes. |
RedisEndpoint |
Redis server address. |
RedisPort |
Redis server port (default: 6379). |
RedisPassword |
Password for Redis (optional for unsecured). |
Usage
1. Apply Attribute to a Method
Use the FilterResponseAttribute
to specify which DTO class needs filtering:
[ApiController]
[Route("api/[controller]/[action]")]
public class SampleController : ControllerBase
{
[HttpGet]
[FilterResponse("ProfilDto")]
public IActionResult GetProfile()
{
var response = new
{
Id = 1,
Name = "John Doe",
Email = "john@example.com",
Address = new { StreetName = "123 Main St", City = "Jakarta" },
Jobs = new[]
{
new { JobTitle = "Developer", CompanyName = "Telkom" }
}
};
return Ok(response);
}
}
2. Dynamic Filtering
- The library will fetch the
allowedAttributes
for the givenProfilDto
based on the user'sclient_id
claim from the token. - If attributes are not found, the full object is returned.
3. Filter Logic
- The properties of the response object are matched against the
allowedAttributes
fetched from the IAM API.
Implementation Details
FilterResponseAttribute
This attribute is applied to controller methods. It:
- Fetches the
client_id
from the user's claims. - Retrieves the
allowedAttributes
from Redis or the IAM API. - Filters the response object's properties to match the
allowedAttributes
.
AuthorizationService
The service handles:
- Fetching allowed attributes from the external API.
- Storing and retrieving allowed attributes from Redis.
public async Task<string> GetAllowedAttributesAsync(string dtoClass, string clientId)
{
var cacheKey = $"iam_attribute:{clientId}:{dtoClass}";
return await _easyCachingProvider.GetOrSetAsync(cacheKey, async () =>
{
var response = await FetchAllowedAttributesFromApi(dtoClass, clientId);
return response?.AllowedAttributes ?? string.Empty;
}, TimeSpan.FromMinutes(120));
}
Redis Integration
The library uses Redis as a caching layer to improve performance. If no cached data is found, it falls back to the IAM API.
IAM API
The IAM API is called using the bearer token extracted from the incoming request's headers. The IAM API must return data in the following format:
{
"statusCode": 200,
"message": "GET Request successful.",
"isError": false,
"data": [
{
"id": "540804d9-2431-4898-91ac-df483a092847",
"dtoClass": "ProfilDto",
"grantAttributes": "Id, Name, Email, Address.City, Jobs.JobTitle"
}
]
}
Example Response Filtering
Given the API response above and the following response object:
{
"Id": 1,
"Name": "John Doe",
"Email": "john.doe@example.com",
"Address": {
"StreetName": "123 Main St",
"City": "Jakarta",
"PostalCode": "12345"
},
"Jobs": [
{
"JobTitle": "Developer",
"CompanyName": "Pusintek",
"StartDate": "01/01/2010",
"EndDate": "01/12/2014"
}
]
}
If the allowedAttributes
for ProfilDto
are "Id, Name, Address.City, Jobs.JobTitle"
, the filtered response will be:
{
"Id": 1,
"Name": "John Doe",
"Address": {
"City": "Jakarta"
},
"Jobs": [
{
"JobTitle": "Developer"
}
]
}
Release Notes
v 1.1.0
New Features:
- Support for Nested Objects and Arrays: The library now supports filtering nested objects and arrays of objects based on allowed attributes.
Developer Notes
Extract client_id
The client_id
is dynamically extracted from the incoming request's claims:
private string GetClientIdFromClaims(HttpContext httpContext)
{
var clientIdClaim = httpContext.User.Claims.FirstOrDefault(c => c.Type == "client_id");
return clientIdClaim?.Value;
}
Error Handling
- If
client_id
orallowedAttributes
is null, the filtering process is bypassed, and the full object is returned.
Contributing
Contributions are welcome! Please submit a pull request or open an issue to suggest improvements.
License
This project is licensed under the MIT License. See the LICENSE
file for details.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. |
.NET Core | netcoreapp3.1 is compatible. |
-
.NETCoreApp 3.1
- EasyCaching.Core (>= 1.9.2)
- EasyCaching.InMemory (>= 1.9.2)
- EasyCaching.Redis (>= 1.9.2)
- EasyCaching.Serialization.MessagePack (>= 1.9.2)
- Microsoft.AspNetCore.Mvc.NewtonsoftJson (>= 3.1.32)
-
net5.0
- EasyCaching.Core (>= 1.9.2)
- EasyCaching.InMemory (>= 1.9.2)
- EasyCaching.Redis (>= 1.9.2)
- EasyCaching.Serialization.MessagePack (>= 1.9.2)
- Microsoft.AspNetCore.Mvc.NewtonsoftJson (>= 5.0.17)
-
net6.0
- EasyCaching.Core (>= 1.9.2)
- EasyCaching.InMemory (>= 1.9.2)
- EasyCaching.Redis (>= 1.9.2)
- EasyCaching.Serialization.MessagePack (>= 1.9.2)
- Microsoft.AspNetCore.Mvc.NewtonsoftJson (>= 6.0.35)
-
net7.0
- EasyCaching.Core (>= 1.9.2)
- EasyCaching.InMemory (>= 1.9.2)
- EasyCaching.Redis (>= 1.9.2)
- EasyCaching.Serialization.MessagePack (>= 1.9.2)
- Microsoft.AspNetCore.Mvc.NewtonsoftJson (>= 7.0.20)
-
net8.0
- EasyCaching.Core (>= 1.9.2)
- EasyCaching.InMemory (>= 1.9.2)
- EasyCaching.Redis (>= 1.9.2)
- EasyCaching.Serialization.MessagePack (>= 1.9.2)
- Microsoft.AspNetCore.Mvc.NewtonsoftJson (>= 8.0.10)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.