在Web API(.Net Framework)中创建自定义AuthorizeAttribute [英] Creating Custom AuthorizeAttribute in Web API (.Net Framework)

查看:158
本文介绍了在Web API(.Net Framework)中创建自定义AuthorizeAttribute的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在WebAPI中使用OAuth2.0 Owin(密码授予).我的初始令牌响应如下所示

I'm using OAuth2.0 Owin (password grant) in my WebAPI.My initial token Response is like below

{
    "access_token": "_ramSlQYasdsRTWEWew.....................",
    "token_type": "bearer",
    "expires_in": 17999,
    "permissions": {
        "user": [
            "Add",
            "Update",
            "Delete"
        ],
        "Product": [
            "Read",
            "Create"
        ]
    }
}

我已经已定制响应,方法是创建一个名为permissions的新密钥,该密钥具有相应用户的特权

I've customized the response by creating a new Key called permissions which hold the privileges for the corresponding user.

在这里,我需要通过检查用户是否具有使用Authorize Attribute调用API的足够权限,来验证Resource server中的每个请求.

From here I need to validate each Request from my Resource server,by checking whether the user has enough permissions to call the API using Authorize Attribute.

我从此处找到了类似的示例,该示例处理的是Dot net Core,这不适合我的情况.

I found a similar example from here where it deals with Dot net Core, which is not suitable for my case.

困难的部分是permission JSON密钥本身使ArrayList变得很复杂

The difficult part is that the permission JSON Key is itself making a complex with ArrayList

[CustomAuthorize(PermissionItem.Product, PermissionAction.Read)]
    public async Task<IActionResult> Index()
    {
        return View(Index);
    }

public class CustomAuthorize : AuthorizeAttribute {
    public AuthorizeAttribute (PermissionItem item, PermissionAction action) {
        //Need to initalize the Permission Enums
    }
    public override void OnAuthorization (HttpActionContext actionContext) {
        //Code to get the value from Permissions ArrayList and compare it with the Enum values
    }
}

以上是我的想法.但是由于Permissions键和枚举比较的复杂性,我无法前进.

The above is the idea I'm having. But due to the complexity of the Permissions Key and Enum comparison I'm couldn't able to move forward.

此外,还有一个问题,例如如果用户"的权限为添加"以及更新",则意味着我需要在控制器之前创建两个属性条件.

Also, there is a question like If the permission for User is Add as well as Update means I need to create two Attribute conditions before my Controller.

喜欢

[CustomAuthorize(PermissionItem.User, PermissionAction.Add)]
[CustomAuthorize(PermissionItem.User, PermissionAction.Update)]

这将导致添加更多行的属性.那么,有没有办法像在|分隔的单个条件中一样做到这一点?

Which leads to adding more lines of Attributes. So Is there is any way to make it as in a single Conditions with | separated?

[CustomAuthorize(PermissionItem.User, PermissionAction.Update|PermissionAction.Add)]

推荐答案

为什么不允许您的CustomAuthorize构造函数具有多个Permission操作.

Why don't you allow your CustomAuthorize constructor to have multiple Permission actions.

public class CustomAuthorize : AuthorizeAttribute
{
    private readonly PermissionAction[] permissionActions;

    public CustomAuthorize(PermissionItem item, params PermissionAction[] permissionActions)
    {
        this.permissionActions = permissionActions;
    }

    public override void OnAuthorization(HttpActionContext actionContext)
    {
        var currentIdentity = System.Threading.Thread.CurrentPrincipal.Identity;
        if (!currentIdentity.IsAuthenticated) {
            // redirect to access denied page
        }

        var userName = currentIdentity.Name;
        // step 1 : retrieve user object

        // step 2 : retrieve user permissions

        // step 3 : match user permission(s) agains class/method's required premissions

        // step 4 : continue/redirect to access denied page
    }
}

您将用以下注释您的班级: [CustomAuthorize(PermissionItem.User, PermissionAction.Update, PermissionAction.Add)]

And you'll annotate your class with: [CustomAuthorize(PermissionItem.User, PermissionAction.Update, PermissionAction.Add)]

我不确定,OP在这里想要实现什么.如果您依靠HTTP请求提供访问权限,那么这就是一个大安全漏洞.在每个请求上,您都应该从数据库中检索用户的访问权限信息,然后根据类/方法的必需权限进行匹配.

I'm not sure, what does OP want to achieve here. If you are relying on HTTP request to provide access rights then that is A BIG SECURITY HOLE. On each request you should retrieve user's access right information from the database and then match is against the required permission of the class/method.

根据经验,您不应依赖请求对象来告诉您当前用户拥有哪些权限.您应该从数据存储中检索它们.

As a rule of thumb you should not rely on request object to tell you what are the permissions that current user have. You should retrieve them from the datastore.

我对CustomAttribute的实现

public class CustomAuthorize : System.Web.Http.AuthorizeAttribute
{
    private readonly PermissionAction[] permissionActions;

    public CustomAuthorize(PermissionItem item, params PermissionAction[] permissionActions)
    {
        this.permissionActions = permissionActions;
    }

    protected override Boolean IsAuthorized(HttpActionContext actionContext)
    {
        var currentIdentity = actionContext.RequestContext.Principal.Identity;
        if (!currentIdentity.IsAuthenticated)
            return false;

        var userName = currentIdentity.Name;
        using (var context = new DataContext())
        {
            var userStore = new UserStore<AppUser>(context);
            var userManager = new UserManager<AppUser>(userStore);
            var user = userManager.FindByName(userName);

            if (user == null)
                return false;

            foreach (var role in permissionActions)
                if (!userManager.IsInRole(user.Id, Convert.ToString(role)))
                    return false;

            return true;
        }
    }
}

这篇关于在Web API(.Net Framework)中创建自定义AuthorizeAttribute的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆