You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在ServiceStack OrmLite中重写AuthenticateAttribute的ExecuteAsync无效问题排查

解决ServiceStack自定义权限属性ExecuteAsync不执行的问题

问题根源

ServiceStack的AuthenticateAttribute和RequiredPermissionAttribute在.NET MVC控制器中是作为**MVC授权过滤器(Authorization Filter)**工作的,而非ServiceStack自身Service接口的请求过滤器。MVC的过滤器管道不会调用ServiceStack定义的ExecuteAsync方法,而是触发MVC标准Filter接口的方法(如IAsyncAuthorizationFilter.OnAuthorizationAsync),这就是你重写的ExecuteAsync从未执行的核心原因。

正确实现方式

自定义权限属性需要实现MVC的异步授权过滤器接口IAsyncAuthorizationFilter,在OnAuthorizationAsync方法中整合ServiceStack内置权限校验与你的自定义扩展权限逻辑。这样既保留ServiceStack原生权限校验的能力,又能针对admin区域等特定场景执行额外权限检查。

代码示例

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using ServiceStack;
using ServiceStack.Auth;
using ServiceStack.Data;

public class CustomRequiredPermissionAttribute : RequiredPermissionAttribute, IAsyncAuthorizationFilter
{
    public CustomRequiredPermissionAttribute(params string[] permissions) : base(permissions)
    {
    }

    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        // 先执行ServiceStack内置的权限校验逻辑
        var request = context.HttpContext.RequestServices.GetRequiredService<IRequest>();
        await base.ExecuteAsync(request, null);

        // 针对admin区域执行扩展权限校验
        var isAdminArea = context.RouteData.Values["area"]?.ToString()?.Equals("Admin", StringComparison.OrdinalIgnoreCase) ?? false;
        if (!isAdminArea)
            return;

        // 获取自定义会话对象
        var session = request.SessionAs<CustomAuthUserSession>();
        if (session == null)
        {
            context.Result = new ForbidResult();
            return;
        }

        // 这里实现你的扩展权限查询逻辑(比如从数据库获取)
        using var db = context.HttpContext.RequestServices.GetRequiredService<IDbConnectionFactory>().OpenDbConnection();
        var userExtraPermissions = await db.SingleByIdAsync<UserExtraPermissions>(session.UserAuthId);
        
        if (userExtraPermissions == null || !userExtraPermissions.HasAdminExtendedAccess)
        {
            context.Result = new ForbidResult();
        }
    }
}

// 示例:自定义会话类
public class CustomAuthUserSession : AuthUserSession
{
    // 你的自定义会话字段
}

// 示例:存储扩展权限的实体类
public class UserExtraPermissions
{
    public string Id { get; set; }
    public bool HasAdminExtendedAccess { get; set; }
}

关键说明

  • 无需额外注册该属性,直接标注在MVC控制器或Action方法上即可生效。
  • 通过request.SessionAs<CustomAuthUserSession>()获取自定义会话对象,避免重复查询。
  • 仅在admin区域触发扩展权限校验,符合你“避免不必要数据库查询”的需求。

内容的提问来源于stack exchange,提问作者Irish Yobbo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 21:33:09