基于路由参数的 ASP.NET Web API 角色权限控制

8

我正在使用ASP.NET Web API 2项目中的角色来限制对某些资源的访问。

现在我有以下情况:

俱乐部管理员只能获取他所管理的俱乐部。俱乐部管理员不应被授权访问他未管理的俱乐部。

这是获取俱乐部的方法:

[Authorize(Roles = "ClubManager")]
[Route("{clubId}")]
public Club GetClub(int clubId)

如您所见,我只允许拥有“ClubManager”角色的用户访问此资源。但我还必须确保该用户是路由参数中给定的俱乐部ID的经理。 我可以使用Authorize属性实现这一点吗?或者我的唯一选择是在方法内部进行此检查?

4个回答

4
您可以使用自定义的AuthorizeAttribute来实现此操作,例如:
public class ClubAuthoriseAttribute : System.Web.Http.AuthorizeAttribute
{
    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        int clubId;
        int.TryParse((string) actionContext.ActionArguments["clubId"], out clubId);

        if (!UserCanManageClub(clubId))
        {
            return false;
        }

        return base.IsAuthorized(actionContext);
    }
}

然后使用这个新属性:

[ClubAuthorise(Roles = "ClubManager")]
[Route("{clubId}")]
public Club GetClub(int clubId)

请注意,这是假设参数名为clubId,但您应该有足够的内容来根据自己的需求进行定制。

1
@NightOwl888 感谢您的编辑,但我是英国人,在这里我们拼写是正确的 :) - DavidG
1
好吧,要么就是更改GetClub方法上面的那个 - 它们不匹配。但是嘿,整个.NET框架都是美式英语,所以接受它吧(我对偏爱英式英语的Java也有同样的保留)。 - NightOwl888
@DavidG 你是如何维护经理和俱乐部之间的链接的?即UserCanManageClub的实现。它是在数据库表中还是你能够使用你的OpenID提供程序进行管理? - Pat Long - Munkii Yebee
@PatLong-MunkiiYebee 不确定你为什么问我,我只回答了被问的问题。无论如何,如果你有具体问题,应该在一个新的帖子中提出。 - DavidG
@DavidG 我意识到这只是理论上的问题,不是你要解决的问题,我只是想知道你是否有任何想法。关于“新帖子”,你是说我应该在这个SO问题的“回复”中提出吗? - Pat Long - Munkii Yebee
@PatLong-MunkiiYebee,您已经有了3k的声望值,应该知道如何在这个网站上提问和回答问题了。 - DavidG

2
在我的情况下,在IsAuthorized方法中,ActionArguments属性尚未填充(请参见ActionContext.ActionArguments Is Empty In IAuthenticationFilter的答案)。相反,我能够使用"最初的回答"。
actionContext.RequestContext.RouteData.Values["clubId"]

也许,这会帮助未来的某个人。最初的回答。

1
在我的情况下,我不希望客户端向我的终端发送用户ID。我从已经授权的请求中获取用户ID。
 [Authorize(Roles = "ClubManager")]
 public Club GetClub()
 {
    var userId = User.Identity.GetUserId();
    .
    .
    .
 }

使用该ID来恢复真正的合法用户。这样,您就不必担心用户试图获取其他用户的信息。

0

我有一个想法。我认为你可以创建自定义授权属性。

就像这样:

public class AuthorizeUserToClubAttribute : AuthorizeAttribute
{   
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool result = false;

        //Get route data from context
        //Get current user from context
        //Ceck does user has an access and write result into variable

        return result;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接