Token导航 LogoToken导航TokenDH.com
待分类只读github未标认证来源可访问许可证需确认审计通过

permission-authorization权限授权

Agent Skill

用于辅助安全审计、权限检查、凭据风险、认证流程和常见漏洞排查。它适合让 Agent 梳理敏感配置、检查依赖风险、分析鉴权逻辑或生成安全复核清单。使用时不能把工具输出直接当最终结论,涉及密钥、令牌、用户数据或生产系统时,应先确认最小权限、脱敏方式和操作边界。

总安装

238

周安装

10

GitHub Stars

50

下载量

83
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:permission-authorization(权限授权)
来源仓库:https://github.com/ronnythedev/dotnet-clean-architecture-skills
仓库路径:skills/permission-authorization
安装命令:
npx skills add https://github.com/ronnythedev/dotnet-clean-architecture-skills --skill permission-authorization
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/ronnythedev/dotnet-clean-architecture-skills --skill permission-authorization

简介

用于辅助安全审计、权限检查、凭据风险、认证流程和常见漏洞排查。

  • 它适合让 Agent 梳理敏感配置、检查依赖风险、分析鉴权逻辑或生成安全复核清单。
  • 使用时不能把工具输出直接当最终结论,涉及密钥、令牌、用户数据或生产系统时,应先确认最小权限、脱敏方式和操作边界。
  • 它属于待分类工具,适用于安全审计场景。
  • permission-authorization 属于待分类类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

Permission-Based Authorization Setup

Overview

This skill implements fine-grained permission-based authorization:

  • Custom [HasPermission] attribute - Declarative permission requirements
  • Policy provider - Dynamically creates policies from permissions
  • Authorization handler - Validates user permissions
  • Claims transformation - Converts roles to permissions

Quick Reference

ComponentPurpose
PermissionsStatic permission constants
RolesStatic role constants
HasPermissionAttributeCustom authorize attribute
PermissionAuthorizationHandlerValidates permissions
PermissionAuthorizationPolicyProviderCreates policies dynamically
RoleToPermissionClaimsTransformationMaps roles to permissions

Authorization Structure

/Infrastructure/Authorization/
├── Permissions.cs
├── Roles.cs
├── HasPermissionAttribute.cs
├── PermissionRequirement.cs
├── PermissionAuthorizationHandler.cs
├── PermissionAuthorizationPolicyProvider.cs
├── RoleToPermissionClaimsTransformation.cs
└── AuthorizationExtensions.cs

Template: Permissions Definition

// src/{name}.infrastructure/Authorization/Permissions.cs
namespace {name}.infrastructure.authorization;

/// <summary>
/// All available permissions in the system
/// Format: {resource}:{action}
/// </summary>
public static class Permissions
{
    // ═══════════════════════════════════════════════════════════════
    // ORGANIZATION PERMISSIONS
    // ═══════════════════════════════════════════════════════════════
    public const string OrganizationsRead = "organizations:read";
    public const string OrganizationsWrite = "organizations:write";
    public const string OrganizationsDelete = "organizations:delete";
    public const string OrganizationsManageSettings = "organizations:manage_settings";

    // ═══════════════════════════════════════════════════════════════
    // USER PERMISSIONS
    // ═══════════════════════════════════════════════════════════════
    public const string UsersRead = "users:read";
    public const string UsersWrite = "users:write";
    public const string UsersDelete = "users:delete";
    public const string UsersManageRoles = "users:manage_roles";

    // ═══════════════════════════════════════════════════════════════
    // DEPARTMENT PERMISSIONS
    // ═══════════════════════════════════════════════════════════════
    public const string DepartmentsRead = "departments:read";
    public const string DepartmentsWrite = "departments:write";
    public const string DepartmentsDelete = "departments:delete";

    // ═══════════════════════════════════════════════════════════════
    // ASSESSMENT PERMISSIONS
    // ═══════════════════════════════════════════════════════════════
    public const string AssessmentsRead = "assessments:read";
    public const string AssessmentsWrite = "assessments:write";
    public const string AssessmentsSubmit = "assessments:submit";
    public const string AssessmentsReview = "assessments:review";

    // ═══════════════════════════════════════════════════════════════
    // REPORT PERMISSIONS
    // ═══════════════════════════════════════════════════════════════
    public const string ReportsRead = "reports:read";
    public const string ReportsExport = "reports:export";
    public const string ReportsViewSensitive = "reports:view_sensitive";

    // ═══════════════════════════════════════════════════════════════
    // ADMIN PERMISSIONS
    // ═══════════════════════════════════════════════════════════════
    public const string AdminAccess = "admin:access";
    public const string AdminManageSystem = "admin:manage_system";
}

Template: Roles Definition

// src/{name}.infrastructure/Authorization/Roles.cs
namespace {name}.infrastructure.authorization;

/// <summary>
/// All available roles in the system
/// </summary>
public static class Roles
{
    public const string SuperAdmin = "SuperAdmin";
    public const string Admin = "Admin";
    public const string Consultant = "Consultant";
    public const string Manager = "Manager";
    public const string Associate = "Associate";
    public const string Viewer = "Viewer";
}

Template: Role-Permission Mapping

// src/{name}.infrastructure/Authorization/RolePermissions.cs
namespace {name}.infrastructure.authorization;

/// <summary>
/// Maps roles to their granted permissions
/// </summary>
public static class RolePermissions
{
    private static readonly Dictionary<string, HashSet<string>> RolePermissionMap = new()
    {
        // ═══════════════════════════════════════════════════════════════
        // SUPER ADMIN - Full system access
        // ═══════════════════════════════════════════════════════════════
        [Roles.SuperAdmin] = new HashSet<string>
        {
            Permissions.OrganizationsRead,
            Permissions.OrganizationsWrite,
            Permissions.OrganizationsDelete,
            Permissions.OrganizationsManageSettings,
            Permissions.UsersRead,
            Permissions.UsersWrite,
            Permissions.UsersDelete,
            Permissions.UsersManageRoles,
            Permissions.DepartmentsRead,
            Permissions.DepartmentsWrite,
            Permissions.DepartmentsDelete,
            Permissions.AssessmentsRead,
            Permissions.AssessmentsWrite,
            Permissions.AssessmentsSubmit,
            Permissions.AssessmentsReview,
            Permissions.ReportsRead,
            Permissions.ReportsExport,
            Permissions.ReportsViewSensitive,
            Permissions.AdminAccess,
            Permissions.AdminManageSystem
        },

        // ═══════════════════════════════════════════════════════════════
        // ADMIN - Organization-level admin
        // ═══════════════════════════════════════════════════════════════
        [Roles.Admin] = new HashSet<string>
        {
            Permissions.OrganizationsRead,
            Permissions.OrganizationsWrite,
            Permissions.OrganizationsManageSettings,
            Permissions.UsersRead,
            Permissions.UsersWrite,
            Permissions.UsersManageRoles,
            Permissions.DepartmentsRead,
            Permissions.DepartmentsWrite,
            Permissions.DepartmentsDelete,
            Permissions.AssessmentsRead,
            Permissions.AssessmentsWrite,
            Permissions.AssessmentsReview,
            Permissions.ReportsRead,
            Permissions.ReportsExport,
            Permissions.ReportsViewSensitive,
            Permissions.AdminAccess
        },

        // ═══════════════════════════════════════════════════════════════
        // CONSULTANT - External consultants
        // ═══════════════════════════════════════════════════════════════
        [Roles.Consultant] = new HashSet<string>
        {
            Permissions.OrganizationsRead,
            Permissions.UsersRead,
            Permissions.DepartmentsRead,
            Permissions.AssessmentsRead,
            Permissions.AssessmentsReview,
            Permissions.ReportsRead,
            Permissions.ReportsExport
        },

        // ═══════════════════════════════════════════════════════════════
        // MANAGER - Department managers
        // ═══════════════════════════════════════════════════════════════
        [Roles.Manager] = new HashSet<string>
        {
            Permissions.OrganizationsRead,
            Permissions.UsersRead,
            Permissions.DepartmentsRead,
            Permissions.DepartmentsWrite,
            Permissions.AssessmentsRead,
            Permissions.AssessmentsWrite,
            Permissions.AssessmentsSubmit,
            Permissions.AssessmentsReview,
            Permissions.ReportsRead
        },

        // ═══════════════════════════════════════════════════════════════
        // ASSOCIATE - Regular employees
        // ═══════════════════════════════════════════════════════════════
        [Roles.Associate] = new HashSet<string>
        {
            Permissions.OrganizationsRead,
            Permissions.UsersRead,
            Permissions.DepartmentsRead,
            Permissions.AssessmentsRead,
            Permissions.AssessmentsSubmit
        },

        // ═══════════════════════════════════════════════════════════════
        // VIEWER - Read-only access
        // ═══════════════════════════════════════════════════════════════
        [Roles.Viewer] = new HashSet<string>
        {
            Permissions.OrganizationsRead,
            Permissions.DepartmentsRead,
            Permissions.AssessmentsRead,
            Permissions.ReportsRead
        }
    };

    /// <summary>
    /// Gets all permissions for a role
    /// </summary>
    public static IReadOnlySet<string> GetPermissionsForRole(string role)
    {
        return RolePermissionMap.TryGetValue(role, out var permissions)
            ? permissions
            : new HashSet<string>();
    }

    /// <summary>
    /// Gets all permissions for multiple roles
    /// </summary>
    public static IReadOnlySet<string> GetPermissionsForRoles(IEnumerable<string> roles)
    {
        var allPermissions = new HashSet<string>();

        foreach (var role in roles)
        {
            var permissions = GetPermissionsForRole(role);
            allPermissions.UnionWith(permissions);
        }

        return allPermissions;
    }

    /// <summary>
    /// Checks if a role has a specific permission
    /// </summary>
    public static bool HasPermission(string role, string permission)
    {
        return RolePermissionMap.TryGetValue(role, out var permissions)
            && permissions.Contains(permission);
    }
}

Template: HasPermission Attribute

// src/{name}.infrastructure/Authorization/HasPermissionAttribute.cs
using Microsoft.AspNetCore.Authorization;

namespace {name}.infrastructure.authorization;

/// <summary>
/// Custom authorization attribute that requires a specific permission
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public sealed class HasPermissionAttribute : AuthorizeAttribute
{
    public HasPermissionAttribute(string permission)
        : base(policy: permission)
    {
    }
}

Template: Permission Requirement

// src/{name}.infrastructure/Authorization/PermissionRequirement.cs
using Microsoft.AspNetCore.Authorization;

namespace {name}.infrastructure.authorization;

/// <summary>
/// Authorization requirement for a specific permission
/// </summary>
public sealed class PermissionRequirement : IAuthorizationRequirement
{
    public string Permission { get; }

    public PermissionRequirement(string permission)
    {
        Permission = permission;
    }
}

Template: Permission Authorization Handler

// src/{name}.infrastructure/Authorization/PermissionAuthorizationHandler.cs
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;

namespace {name}.infrastructure.authorization;

/// <summary>
/// Handles permission-based authorization requirements
/// </summary>
internal sealed class PermissionAuthorizationHandler
    : AuthorizationHandler<PermissionRequirement>
{
    private readonly ILogger<PermissionAuthorizationHandler> _logger;

    public PermissionAuthorizationHandler(
        ILogger<PermissionAuthorizationHandler> logger)
    {
        _logger = logger;
    }

    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        PermissionRequirement requirement)
    {
        // Get permissions from claims (added by claims transformation)
        var permissions = context.User
            .FindAll("permission")
            .Select(c => c.Value)
            .ToHashSet();

        if (permissions.Contains(requirement.Permission))
        {
            _logger.LogDebug(
                "User {UserId} authorized for permission {Permission}",
                context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value,
                requirement.Permission);

            context.Succeed(requirement);
        }
        else
        {
            _logger.LogWarning(
                "User {UserId} denied permission {Permission}. User has permissions: {Permissions}",
                context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value,
                requirement.Permission,
                string.Join(", ", permissions));
        }

        return Task.CompletedTask;
    }
}

Template: Permission Policy Provider

// src/{name}.infrastructure/Authorization/PermissionAuthorizationPolicyProvider.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;

namespace {name}.infrastructure.authorization;

/// <summary>
/// Dynamically creates authorization policies based on permission names
/// </summary>
internal sealed class PermissionAuthorizationPolicyProvider
    : DefaultAuthorizationPolicyProvider
{
    private readonly AuthorizationOptions _options;

    public PermissionAuthorizationPolicyProvider(
        IOptions<AuthorizationOptions> options)
        : base(options)
    {
        _options = options.Value;
    }

    public override async Task<AuthorizationPolicy?> GetPolicyAsync(string policyName)
    {
        // First check if policy exists in options
        var policy = await base.GetPolicyAsync(policyName);

        if (policy is not null)
        {
            return policy;
        }

        // If not found, create a permission-based policy
        // Policy name is the permission (e.g., "users:read")
        policy = new AuthorizationPolicyBuilder()
            .AddRequirements(new PermissionRequirement(policyName))
            .Build();

        // Cache the policy
        _options.AddPolicy(policyName, policy);

        return policy;
    }
}

Template: Claims Transformation

// src/{name}.infrastructure/Authorization/RoleToPermissionClaimsTransformation.cs
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;

namespace {name}.infrastructure.authorization;

/// <summary>
/// Transforms role claims into permission claims
/// </summary>
internal sealed class RoleToPermissionClaimsTransformation
    : IClaimsTransformation
{
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        // Get all role claims
        var roles = principal
            .FindAll(ClaimTypes.Role)
            .Select(c => c.Value)
            .ToList();

        if (!roles.Any())
        {
            return Task.FromResult(principal);
        }

        // Get permissions for all roles
        var permissions = RolePermissions.GetPermissionsForRoles(roles);

        // Create new identity with permission claims
        var identity = principal.Identity as ClaimsIdentity;

        if (identity is null)
        {
            return Task.FromResult(principal);
        }

        // Add permission claims (only if not already present)
        foreach (var permission in permissions)
        {
            if (!principal.HasClaim("permission", permission))
            {
                identity.AddClaim(new Claim("permission", permission));
            }
        }

        return Task.FromResult(principal);
    }
}

Template: Authorization Registration

// src/{name}.infrastructure/Authorization/AuthorizationExtensions.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;

namespace {name}.infrastructure.authorization;

public static class AuthorizationExtensions
{
    public static IServiceCollection AddPermissionAuthorization(
        this IServiceCollection services)
    {
        // Register policy provider
        services.AddSingleton<IAuthorizationPolicyProvider,
            PermissionAuthorizationPolicyProvider>();

        // Register authorization handler
        services.AddScoped<IAuthorizationHandler,
            PermissionAuthorizationHandler>();

        // Register claims transformation
        services.AddScoped<IClaimsTransformation,
            RoleToPermissionClaimsTransformation>();

        // Configure authorization
        services.AddAuthorization(options =>
        {
            // Default policy requires authentication
            options.DefaultPolicy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();

            // Fallback policy for endpoints without [Authorize]
            options.FallbackPolicy = null;  // Allow anonymous by default

            // Add named policies for common scenarios
            options.AddPolicy("AdminOnly", policy =>
                policy.RequireRole(Roles.SuperAdmin, Roles.Admin));

            options.AddPolicy("ManagerOrAbove", policy =>
                policy.RequireRole(Roles.SuperAdmin, Roles.Admin, Roles.Manager));
        });

        return services;
    }
}

Usage in Controllers

// src/{name}.api/Controllers/Users/UserController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using {name}.infrastructure.authorization;

[Authorize]  // Requires authentication
[ApiController]
[Route("api/v1/users")]
public class UserController : ControllerBase
{
    // ═══════════════════════════════════════════════════════════════
    // PUBLIC: Any authenticated user
    // ═══════════════════════════════════════════════════════════════
    [HttpGet("{id}")]
    [HasPermission(Permissions.UsersRead)]
    public async Task<IActionResult> GetById(Guid id) { }

    // ═══════════════════════════════════════════════════════════════
    // CREATE: Requires write permission
    // ═══════════════════════════════════════════════════════════════
    [HttpPost]
    [HasPermission(Permissions.UsersWrite)]
    public async Task<IActionResult> Create([FromBody] CreateUserRequest request) { }

    // ═══════════════════════════════════════════════════════════════
    // DELETE: Requires delete permission
    // ═══════════════════════════════════════════════════════════════
    [HttpDelete("{id}")]
    [HasPermission(Permissions.UsersDelete)]
    public async Task<IActionResult> Delete(Guid id) { }

    // ═══════════════════════════════════════════════════════════════
    // MULTIPLE PERMISSIONS: All required
    // ═══════════════════════════════════════════════════════════════
    [HttpPost("{id}/roles")]
    [HasPermission(Permissions.UsersWrite)]
    [HasPermission(Permissions.UsersManageRoles)]
    public async Task<IActionResult> AssignRole(Guid id, [FromBody] AssignRoleRequest request) { }

    // ═══════════════════════════════════════════════════════════════
    // ROLE-BASED: Use built-in attribute
    // ═══════════════════════════════════════════════════════════════
    [HttpGet("admin/dashboard")]
    [Authorize(Roles = Roles.SuperAdmin + "," + Roles.Admin)]
    public async Task<IActionResult> GetAdminDashboard() { }

    // ═══════════════════════════════════════════════════════════════
    // NAMED POLICY
    // ═══════════════════════════════════════════════════════════════
    [HttpDelete("organization/{orgId}")]
    [Authorize(Policy = "AdminOnly")]
    public async Task<IActionResult> DeleteOrganization(Guid orgId) { }
}

Usage in Handlers (Imperative)

// src/{name}.application/{Feature}/DoSomething/DoSomethingCommandHandler.cs
using Microsoft.AspNetCore.Authorization;
using {name}.application.abstractions.authentication;

internal sealed class DoSomethingCommandHandler
    : ICommandHandler<DoSomethingCommand, Guid>
{
    private readonly IUserContext _userContext;
    private readonly IAuthorizationService _authorizationService;

    public DoSomethingCommandHandler(
        IUserContext userContext,
        IAuthorizationService authorizationService)
    {
        _userContext = userContext;
        _authorizationService = authorizationService;
    }

    public async Task<Result<Guid>> Handle(
        DoSomethingCommand request,
        CancellationToken cancellationToken)
    {
        // Check permission imperatively
        var authResult = await _authorizationService.AuthorizeAsync(
            _userContext.User,
            Permissions.SomethingWrite);

        if (!authResult.Succeeded)
        {
            return Result.Failure<Guid>(CommonErrors.Forbidden);
        }

        // Continue with operation...
    }
}

Resource-Based Authorization

// src/{name}.infrastructure/Authorization/DocumentAuthorizationHandler.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Infrastructure;

/// <summary>
/// Authorizes access to documents based on ownership
/// </summary>
internal sealed class DocumentAuthorizationHandler
    : AuthorizationHandler<OperationAuthorizationRequirement, Document>
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        OperationAuthorizationRequirement requirement,
        Document resource)
    {
        var userId = context.User.FindFirst("sub")?.Value;

        if (string.IsNullOrEmpty(userId))
        {
            return Task.CompletedTask;
        }

        // Owner can do anything
        if (resource.OwnerId.ToString() == userId)
        {
            context.Succeed(requirement);
            return Task.CompletedTask;
        }

        // Others need explicit permission based on operation
        if (requirement.Name == Operations.Read.Name)
        {
            if (context.User.HasClaim("permission", Permissions.DocumentsRead))
            {
                context.Succeed(requirement);
            }
        }

        return Task.CompletedTask;
    }
}

// Define operations
public static class Operations
{
    public static readonly OperationAuthorizationRequirement Create = new() { Name = "Create" };
    public static readonly OperationAuthorizationRequirement Read = new() { Name = "Read" };
    public static readonly OperationAuthorizationRequirement Update = new() { Name = "Update" };
    public static readonly OperationAuthorizationRequirement Delete = new() { Name = "Delete" };
}

Critical Rules

  1. Use constants for permissions - No magic strings
  2. Permission naming convention - {resource}:{action}
  3. Roles aggregate permissions - Don't check roles directly
  4. Claims transformation - Convert roles to permissions early
  5. Cache policies - Policy provider caches dynamically created policies
  6. Multiple attributes = AND - All permissions required
  7. Log authorization failures - For security auditing
  8. Don't trust client claims - Always validate on server
  9. Separate authn from authz - Authentication ≠ Authorization
  10. Resource-based when needed - For ownership checks

Anti-Patterns to Avoid

// ❌ WRONG: Checking roles directly in code
if (user.IsInRole("Admin") || user.IsInRole("Manager"))
{
    // This scatters role logic everywhere
}

// ✅ CORRECT: Check permission
[HasPermission(Permissions.UsersWrite)]
public async Task<IActionResult> CreateUser() { }

// ❌ WRONG: Magic strings for permissions
[Authorize(Policy = "users:write")]  // Typo risk!

// ✅ CORRECT: Use constants
[HasPermission(Permissions.UsersWrite)]

// ❌ WRONG: Trusting client-provided permissions
var permissions = request.UserPermissions;  // Client can't set permissions!

// ✅ CORRECT: Derive from authenticated roles
// Claims transformation handles this automatically

Related Skills

  • jwt-authentication - Authentication setup
  • api-controller-generator - Protected endpoints
  • dotnet-clean-architecture - Infrastructure layer

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

37.45%
按下载量换算31

Claude

29.1%
按下载量换算24

Cursor

20.65%
按下载量换算17

Gemini CLI

10.26%
按下载量换算9

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills