Token导航 LogoToken导航

Agent Skill · 研究检索

openiddict-authorization(openiddict 授权)

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

openiddict-authorization 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 52,216。

总安装 563周安装 23GitHub Stars 21下载 180核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

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

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

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/thapaliyabikendra/ai-artifacts --skill openiddict-authorization

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

用于辅助安全审计、权限检查和认证流程分析。openiddict-authorization 属于研究检索类 Skill,可作为该场景下的辅助能力补充。适合梳理敏感配置、检查依赖风险或生成安全复核清单。通过 GitHub 安装,使用时需确认最小权限和操作边界。涉及密钥或生产系统时应先脱敏并核实操作范围。

不能将工具输出直接作为最终结论,需人工复核关键结果。

来源仓库内路径:skills/openiddict-authorization

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/thapaliyabikendra/ai-artifacts --skill openidd…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

openiddict-authorization 怎么安装?

在终端执行 npx skills add https://github.com/thapaliyabikendra/ai-artifacts --skill openiddict-author…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

openiddict-authorization 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

openiddict-authorization 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

openiddict-authorization 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

openiddict-authorization 用的人多吗?

公开数据是累计安装 563 次,近一周安装 23 次,下载 180 次,GitHub 21 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

openiddict-authorization 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
openiddict-authorization

openiddict 授权 · 本页

56321需要联网未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

OpenIddict Authorization Patterns

OAuth 2.0 and authorization patterns for ABP Framework with OpenIddict.

When to Use

  • Implementing permission-based authorization
  • Configuring role-based access control (RBAC)
  • Adding custom claims to tokens
  • Securing API endpoints
  • Implementing multi-tenant authorization
  • Configuring OAuth 2.0 flows

ABP Permission System

Define Permissions

// Domain.Shared/Permissions/{ProjectName}Permissions.cs
public static class {ProjectName}Permissions
{
    public const string GroupName = "{ProjectName}";

    public static class {Feature1}
    {
        public const string Default = GroupName + ".{Feature1}";
        public const string Create = Default + ".Create";
        public const string Edit = Default + ".Edit";
        public const string Delete = Default + ".Delete";
        public const string Export = Default + ".Export";
    }

    public static class {Feature2}
    {
        public const string Default = GroupName + ".{Feature2}";
        public const string Create = Default + ".Create";
        public const string Edit = Default + ".Edit";
        public const string Delete = Default + ".Delete";
        public const string ViewAll = Default + ".ViewAll"; // Admin only
        public const string Cancel = Default + ".Cancel";
    }

    public static class {Feature3}
    {
        public const string Default = GroupName + ".{Feature3}";
        public const string Create = Default + ".Create";
        public const string Edit = Default + ".Edit";
        public const string Delete = Default + ".Delete";
        public const string Manage = Default + ".Manage";
    }
}

Register Permission Definitions

// Application.Contracts/Permissions/{ProjectName}PermissionDefinitionProvider.cs
public class {ProjectName}PermissionDefinitionProvider : PermissionDefinitionProvider
{
    public override void Define(IPermissionDefinitionContext context)
    {
        var mainGroup = context.AddGroup(
            {ProjectName}Permissions.GroupName,
            L("Permission:{ProjectName}"));

        // Feature1
        var feature1Permission = mainGroup.AddPermission(
            {ProjectName}Permissions.{Feature1}.Default,
            L("Permission:{Feature1}"));

        feature1Permission.AddChild(
            {ProjectName}Permissions.{Feature1}.Create,
            L("Permission:{Feature1}.Create"));

        feature1Permission.AddChild(
            {ProjectName}Permissions.{Feature1}.Edit,
            L("Permission:{Feature1}.Edit"));

        feature1Permission.AddChild(
            {ProjectName}Permissions.{Feature1}.Delete,
            L("Permission:{Feature1}.Delete"));

        feature1Permission.AddChild(
            {ProjectName}Permissions.{Feature1}.Export,
            L("Permission:{Feature1}.Export"));

        // Feature2
        var feature2Permission = mainGroup.AddPermission(
            {ProjectName}Permissions.{Feature2}.Default,
            L("Permission:{Feature2}"));

        feature2Permission.AddChild(
            {ProjectName}Permissions.{Feature2}.Create,
            L("Permission:{Feature2}.Create"));

        feature2Permission.AddChild(
            {ProjectName}Permissions.{Feature2}.ViewAll,
            L("Permission:{Feature2}.ViewAll"));

        // Feature3 - restricted to admin
        var feature3Permission = mainGroup.AddPermission(
            {ProjectName}Permissions.{Feature3}.Default,
            L("Permission:{Feature3}"),
            multiTenancySide: MultiTenancySides.Host); // Host-only permission
    }

    private static LocalizableString L(string name)
    {
        return LocalizableString.Create<{ProjectName}Resource>(name);
    }
}

Using Authorization in AppServices

Declarative Authorization

[Authorize({ProjectName}Permissions.{Feature}.Default)]
public class {Entity}AppService : ApplicationService, I{Entity}AppService
{
    [Authorize({ProjectName}Permissions.{Feature}.Create)]
    public async Task<{Entity}Dto> CreateAsync(CreateUpdate{Entity}Dto input)
    {
        // Only users with {Feature}.Create permission can execute
    }

    [Authorize({ProjectName}Permissions.{Feature}.Edit)]
    public async Task<{Entity}Dto> UpdateAsync(Guid id, CreateUpdate{Entity}Dto input)
    {
        // Only users with {Feature}.Edit permission can execute
    }

    [Authorize({ProjectName}Permissions.{Feature}.Delete)]
    public async Task DeleteAsync(Guid id)
    {
        // Only users with {Feature}.Delete permission can execute
    }

    [AllowAnonymous]
    public async Task<{Entity}Dto> GetPublicInfoAsync(Guid id)
    {
        // Anyone can access
    }
}

Imperative Authorization

public class {Entity}AppService : ApplicationService, I{Entity}AppService
{
    public async Task<{Entity}Dto> GetAsync(Guid id)
    {
        var entity = await _repository.GetAsync(id);

        // Check if user can view this entity
        if (entity.OwnerId != CurrentUser.Id &&
            entity.AssignedUserId != CurrentUser.Id)
        {
            // User is neither the owner nor assigned - check admin permission
            await AuthorizationService.CheckAsync(
                {ProjectName}Permissions.{Feature}.ViewAll);
        }

        return ObjectMapper.Map<{Entity}, {Entity}Dto>(entity);
    }

    public async Task<bool> CanCancelAsync(Guid id)
    {
        var entity = await _repository.GetAsync(id);

        // Check various conditions
        if (entity.Status == {Entity}Status.Completed)
            return false;

        // Owner can always cancel
        if (entity.OwnerId == CurrentUser.Id)
            return true;

        // Check cancel permission
        return await AuthorizationService.IsGrantedAsync(
            {ProjectName}Permissions.{Feature}.Cancel);
    }
}

Policy-Based Authorization

// Define policy
public override void ConfigureServices(ServiceConfigurationContext context)
{
    context.Services.AddAuthorization(options =>
    {
        options.AddPolicy("AdminOnly", policy =>
            policy.RequireRole("admin"));

        options.AddPolicy("DoctorOrAdmin", policy =>
            policy.RequireRole("admin", "doctor"));

        options.AddPolicy("CanManagePatients", policy =>
            policy.RequireAssertion(context =>
                context.User.HasClaim("Permission", ClinicPermissions.Patients.Default) ||
                context.User.IsInRole("admin")));
    });
}

// Use in AppService
[Authorize(Policy = "DoctorOrAdmin")]
public async Task<DoctorScheduleDto> GetScheduleAsync(Guid doctorId)
{
    // ...
}

Role-Based Access Control

Seed Default Roles

public class ClinicDataSeedContributor : IDataSeedContributor, ITransientDependency
{
    private readonly IIdentityRoleRepository _roleRepository;
    private readonly IdentityRoleManager _roleManager;
    private readonly IPermissionManager _permissionManager;

    public async Task SeedAsync(DataSeedContext context)
    {
        await CreateRoleIfNotExistsAsync("Admin");
        await CreateRoleIfNotExistsAsync("Doctor");
        await CreateRoleIfNotExistsAsync("Receptionist");

        await AssignPermissionsToRolesAsync();
    }

    private async Task CreateRoleIfNotExistsAsync(string roleName)
    {
        var role = await _roleRepository.FindByNormalizedNameAsync(roleName.ToUpperInvariant());
        if (role == null)
        {
            role = new IdentityRole(GuidGenerator.Create(), roleName);
            await _roleManager.CreateAsync(role);
        }
    }

    private async Task AssignPermissionsToRolesAsync()
    {
        // Admin gets all permissions
        var allPermissions = new[]
        {
            ClinicPermissions.Patients.Default,
            ClinicPermissions.Patients.Create,
            ClinicPermissions.Patients.Edit,
            ClinicPermissions.Patients.Delete,
            ClinicPermissions.Appointments.Default,
            ClinicPermissions.Appointments.ViewAll,
            ClinicPermissions.Doctors.Default,
            ClinicPermissions.Doctors.ManageSchedule
        };

        foreach (var permission in allPermissions)
        {
            await _permissionManager.SetForRoleAsync("Admin", permission, true);
        }

        // Doctor permissions
        await _permissionManager.SetForRoleAsync("Doctor", ClinicPermissions.Appointments.Default, true);
        await _permissionManager.SetForRoleAsync("Doctor", ClinicPermissions.Patients.Default, true);

        // Receptionist permissions
        await _permissionManager.SetForRoleAsync("Receptionist", ClinicPermissions.Patients.Create, true);
        await _permissionManager.SetForRoleAsync("Receptionist", ClinicPermissions.Appointments.Create, true);
    }
}

Custom Claims

Add Custom Claims to Token

// AuthServer/ClaimsPrincipalContributor.cs
public class ClinicClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency
{
    private readonly IRepository<Doctor, Guid> _doctorRepository;

    public ClinicClaimsPrincipalContributor(IRepository<Doctor, Guid> doctorRepository)
    {
        _doctorRepository = doctorRepository;
    }

    public async Task ContributeAsync(AbpClaimsPrincipalContributorContext context)
    {
        var identity = context.ClaimsPrincipal.Identities.FirstOrDefault();
        if (identity == null) return;

        var userId = identity.FindUserId();
        if (!userId.HasValue) return;

        // Add custom claims
        var doctor = await _doctorRepository.FirstOrDefaultAsync(d => d.UserId == userId);
        if (doctor != null)
        {
            identity.AddClaim(new Claim("doctor_id", doctor.Id.ToString()));
            identity.AddClaim(new Claim("specialization", doctor.Specialization));
        }
    }
}

// Register in module
public override void ConfigureServices(ServiceConfigurationContext context)
{
    Configure<AbpClaimsServiceOptions>(options =>
    {
        options.RequestedClaims.Add("doctor_id");
        options.RequestedClaims.Add("specialization");
    });
}

Access Custom Claims

public class AppointmentAppService : ApplicationService
{
    public async Task<List<AppointmentDto>> GetMyAppointmentsAsync()
    {
        // Get doctor_id from claims
        var doctorIdClaim = CurrentUser.FindClaim("doctor_id");
        if (doctorIdClaim == null)
        {
            throw new BusinessException("User is not a doctor");
        }

        var doctorId = Guid.Parse(doctorIdClaim.Value);
        return await _appointmentRepository
            .GetListAsync(a => a.DoctorId == doctorId);
    }
}

Multi-Tenant Authorization

Tenant-Aware Permissions

public class TenantPermissionDefinitionProvider : PermissionDefinitionProvider
{
    public override void Define(IPermissionDefinitionContext context)
    {
        var group = context.AddGroup("TenantSettings");

        // Tenant-side permission (available in tenants)
        group.AddPermission(
            "TenantSettings.Manage",
            multiTenancySide: MultiTenancySides.Tenant);

        // Host-side permission (only host/admin)
        group.AddPermission(
            "TenantSettings.ManageAll",
            multiTenancySide: MultiTenancySides.Host);
    }
}

Cross-Tenant Data Access

public class CrossTenantReportService : ApplicationService
{
    private readonly IDataFilter _dataFilter;
    private readonly ICurrentTenant _currentTenant;

    [Authorize("Reports.CrossTenant")]
    public async Task<ReportDto> GenerateCrossTenantReportAsync()
    {
        // Verify host-level access
        if (_currentTenant.Id.HasValue)
        {
            throw new BusinessException("Cross-tenant reports only available from host");
        }

        using (_dataFilter.Disable<IMultiTenant>())
        {
            // Access data across all tenants
            var allPatients = await _patientRepository.GetCountAsync();
            // ...
        }
    }
}

OpenIddict Configuration

AuthServer Setup

// AuthServer/AuthServerModule.cs
public override void PreConfigureServices(ServiceConfigurationContext context)
{
    PreConfigure<OpenIddictBuilder>(builder =>
    {
        builder.AddValidation(options =>
        {
            options.AddAudiences("ClinicManagementSystem");
            options.UseLocalServer();
            options.UseAspNetCore();
        });
    });
}

public override void ConfigureServices(ServiceConfigurationContext context)
{
    Configure<AbpOpenIddictOptions>(options =>
    {
        options.AddDevelopmentEncryptionAndSigningCertificate = true;
    });

    // Configure OpenIddict scopes
    Configure<OpenIddictServerOptions>(options =>
    {
        options.Scopes.Add("offline_access");
        options.Scopes.Add("profile");
        options.Scopes.Add("email");
        options.Scopes.Add("clinic_api");
    });
}

API Host JWT Configuration

// HttpApi.Host configuration
public override void ConfigureServices(ServiceConfigurationContext context)
{
    var configuration = context.Services.GetConfiguration();

    context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.Authority = configuration["AuthServer:Authority"];
            options.RequireHttpsMetadata = Convert.ToBoolean(
                configuration["AuthServer:RequireHttpsMetadata"]);
            options.Audience = "ClinicManagementSystem";

            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ClockSkew = TimeSpan.Zero
            };
        });
}

Security Best Practices

Input Validation in Authorization

public async Task<PatientDto> GetAsync(Guid id)
{
    // Validate input
    if (id == Guid.Empty)
    {
        throw new AbpValidationException("Invalid patient ID");
    }

    var patient = await _patientRepository.FindAsync(id);
    if (patient == null)
    {
        throw new EntityNotFoundException(typeof(Patient), id);
    }

    // Authorization check
    await AuthorizationService.CheckAsync(ClinicPermissions.Patients.Default);

    return ObjectMapper.Map<Patient, PatientDto>(patient);
}

Audit Logging

[Audited] // Enable audit logging for this service
public class PatientAppService : ApplicationService
{
    [DisableAuditing] // Disable for specific methods
    public async Task<List<PatientDto>> GetListAsync()
    {
        // ...
    }
}

Quality Checklist

  • Permissions defined for all features
  • Permission hierarchy established (parent/child)
  • Roles seeded with appropriate permissions
  • All mutation endpoints have [Authorize]
  • Custom claims added for domain-specific data
  • Multi-tenancy permissions configured correctly
  • Audit logging enabled for sensitive operations
  • Token validation configured properly

Shared Knowledge

For foundational patterns, see the shared knowledge base:

TopicFileDescription
Permission namingknowledge/conventions/permissions.mdPermission format and hierarchy
Naming conventionsknowledge/conventions/naming.mdPermission constant naming

Integration Points

This skill is used by:

  • abp-developer: Authorization implementation
  • security-engineer: Security audit and review
  • /review:permissions: Permission coverage analysis
  • backend-architect: Security architecture design

平台分布

Codex

33.57%
按下载量换算60

Claude

29.67%
按下载量换算53

Cursor

19.11%
按下载量换算34

Gemini CLI

10.12%
按下载量换算18

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

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

继续浏览同类 Skills