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                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Kemenkeu.Authorization.Core" Version="1.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Kemenkeu.Authorization.Core --version 1.1.0                
#r "nuget: Kemenkeu.Authorization.Core, 1.1.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// 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

  1. NuGet Package Add the NuGet package to your project:

    dotnet add package Kemenkeu.Authorization.Core
    
  2. Register Services Register AuthorizationService and caching in Program.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 given ProfilDto based on the user's client_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:

  1. Fetches the client_id from the user's claims.
  2. Retrieves the allowedAttributes from Redis or the IAM API.
  3. 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 or allowedAttributes 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.0 91 12/19/2024
1.0.1 93 12/18/2024