为了账号安全,请及时绑定邮箱和手机立即绑定

如何在运行时重新加载自定义属性?ASP.NET 核心 MVC

如何在运行时重新加载自定义属性?ASP.NET 核心 MVC

C#
鸿蒙传说 2022-12-31 13:39:43
我有一个应用程序,用户可以在其中创建新角色。某些操作只能由某些角色访问。要检查是否允许用户执行特定操作,我使用自定义 AuthorizeAttribute,类似于https://stackoverflow.com/a/40300184。[AuthorizeRoles(Permission.Unlink, Permission.Link)] [HttpGet("link")]    public IActionResult Link(int id)    {        ...    }AuthorizeRolesAttribute 类:public class AuthorizeRolesAttribute : AuthorizeAttribute{    public AuthorizeRolesAttribute(params Permission[] permissions)    {           Roles = GetRoles(permissions);    }}获取角色:public static string GetRoles(params Permission[] permissions){    DataRowCollection rows = DatabaseHelper.RoleTable.Rows;    List<string> allowedRoles = new List<string>();    foreach (DataRow row in rows)    {        bool allowed = true;        foreach (Permission permission in permissions)        {            if ((bool)row[permission.ToString()] == false)                allowed = false;        }        //if all required permissions are true in this role it is added to the allowed roles        if (allowed)            allowedRoles.Add(row["ROLE"].ToString());    }    return string.Join(",", allowedRoles);}当应用程序启动时,每个具有 AuthorizeRolesAttribute 的方法都会调用 GetRoles 方法来确定允许哪些角色使用该方法。但是,当添加新角色时,这适用于现有角色。该属性不会重新评估角色。我需要更新属性并允许新角色使用该方法而无需重新启动应用程序。添加新角色后,我尝试运行以下代码。(如https://stackoverflow.com/a/12196932所建议)typeof(UsersController).GetMethod(nameof(UsersController.Link)).GetCustomAttributes(false);这确实会导致 AuthorizeRolesAttribute 再次调用 GetRoles(),并且会返回一个包含新 Role 的字符串。但是,当尝试以具有新角色的用户身份访问“链接”方法时,我得到 403 Forbidden 状态。
查看完整描述

1 回答

?
MYYA

TA贡献1868条经验 获得超4个赞

我找到了解决办法。而不是这个:


public class AuthorizeRolesAttribute : AuthorizeAttribute

{

    public AuthorizeRolesAttribute(params Permission[] permissions)

    {   

        Roles = GetRoles(permissions);

    }

}

我现在有这个:


public class AuthorizeRolesAttribute : Attribute, IAuthorizationFilter 

{

    private readonly Permission[] permissions;

    public AuthorizeRolesAttribute(params Permission[] permissions)

    {

        this.permissions = permissions;

    }


    public void OnAuthorization(AuthorizationFilterContext context)

    {

        string[] roles = Authentication.GetRoles(permissions).Split(",");

        bool allowed = context.HttpContext.User.Claims.Any(c => c.Type.Contains("role") && roles.Contains(c.Value));

        if (!allowed)

            context.Result = new ForbidResult();

    }

}


查看完整回答
反对 回复 2022-12-31
  • 1 回答
  • 0 关注
  • 131 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号