| name | rpt-permissions |
| description | Configure RPT token exchange and permission-based authorization for affolterNET.Web.Bff. Use when setting up Keycloak permissions, resource policies, or fine-grained access control. |
RPT Permissions
Configure Keycloak RPT-based permission authorization.
For complete reference, see Library Guide.
Overview
RPT (Requesting Party Token) enables fine-grained permissions:
- User authenticates and gets access token
- BFF exchanges access token for RPT
- RPT contains granted permissions
- Controllers authorize based on permissions
Quick Start
Enable Authorization Mode
var options = builder.Services.AddBffServices(isDev, config, opts => {
opts.ConfigureBff = bff => {
bff.AuthMode = AuthenticationMode.Authorize;
};
});
Use Permission Policies
[Authorize(Policy = "admin-resource")]
[HttpGet("admin")]
public IActionResult AdminOnly() => Ok();
// Multiple permissions (any match)
[Authorize(Policy = "admin-resource,manager-resource")]
[HttpGet("management")]
public IActionResult Management() => Ok();
Keycloak Configuration
Resource Setup
- Enable "Authorization" on your client
- Create Resources (e.g., "admin-resource", "user-resource")
- Create Scopes (e.g., "view", "manage", "create")
- Create Policies (role-based, user-based, etc.)
- Create Permissions linking policies to resources/scopes
Permission Structure
{
"permissions": [
{
"rsname": "admin-resource",
"scopes": ["view", "manage"]
},
{
"rsname": "user-resource",
"scopes": ["read", "create"]
}
]
}
Permission Checking in Code
Using RequirePermission Attribute (Recommended)
// Single permission
[RequirePermission("admin-resource:view")]
public IActionResult AdminView() { ... }
// Multiple permissions (any match)
[RequirePermission("admin-resource:manage", "user-resource:delete")]
public IActionResult AdminManage() { ... }
Using Authorize Policy (Alternative)
// Single permission
[Authorize(Policy = "admin-resource:view")]
public IActionResult AdminView() { ... }
// Multiple permissions (comma-separated)
[Authorize(Policy = "admin-resource:manage,user-resource:delete")]
public IActionResult AdminManage() { ... }
Note: RequirePermission is a convenience wrapper that sets the Policy internally.
Programmatic Check
public class MyController : ControllerBase
{
public IActionResult ConditionalAction()
{
var permissions = User.FindAll("permission")
.Select(c => c.Value);
if (permissions.Contains("admin-resource:manage"))
{
// Admin-specific logic
}
return Ok();
}
}
SPA Permission Checking
// Auth store
const useAuthStore = defineStore('auth', {
state: () => ({
permissions: [] as { resource: string; action: string }[]
}),
actions: {
hasPermission(resource: string, action: string): boolean {
return this.permissions.some(
p => p.resource === resource && p.action === action
);
}
}
});
// Component usage
<template>
<button v-if="authStore.hasPermission('admin-resource', 'manage')">
Admin Action
</button>
</template>
Permission Claims Format
When the RPT middleware processes permissions, it adds claims to the user identity:
| Property | Value |
|---|---|
| Claim Type | "permission" |
| Claim Value | "{resource}:{scope}" |
Examples: "admin-resource:view", "user-resource:create"
Caching
RPT tokens are cached per user to avoid repeated Keycloak calls:
{
"affolterNET": {
"Web": {
"PermissionCache": {
"ExpirationMinutes": 5
}
}
}
}
Troubleshooting
Permissions not recognized
- Verify
AuthModeisAuthorize - Check Keycloak client has Authorization enabled
- Ensure resources/permissions are configured
- Review RPT token contents in jwt.io
Permission denied unexpectedly
- Check policy evaluation in Keycloak
- Verify user has required role for policy
- Review permission-to-policy mappings
RPT exchange fails
- Verify client credentials are correct
- Check Keycloak authorization services are enabled
- Review Keycloak logs for errors