如何在MVC控制器上授权OpenID用户

时间:2010-06-25 02:27:29

标签: asp.net-mvc permissions openid membership dotnetopenauth

我正在查看MVC中可用的[Authorize(Roles = "DefaultUser")],但我似乎无法弄清楚我是否可以将它与DotNetOpenAuth一起使用。

我使用OpenID作为我唯一的会员提供商,但我在UserProfile表中有一些通用项。我不希望除了适当的用户之外的任何人都能够访问编辑控制器。

例:
UserID 2 应该能够访问/Users/Edit/1,但他们 CAN 访问/Users/Edit/2

2 个答案:

答案 0 :(得分:2)

编辑/重写以获得更清晰的理解

public class AdvancedAuthorizeAttribute : AuthorizeAttribute
    {
            public string RouteDataValue
            {
                get;
                set;
            }

            protected override bool AuthorizeCore(HttpContextBase httpContext)
            {
                if(base.AuthorizeCore(httpContext))
                {
                    MvcHandler mvcHandler = httpContext.CurrentHandler as MvcHandler;
                    if (mvcHandler != null)
                    {
                        var paramValue = mvcHandler.RequestContext.RouteData.Values[RouteDataValue];
                        if (paramValue != null)
                        {
                            // Inside this IF-statement is where you'll have to customize for your code.

                            //I use the default user from HttpContext
                            string UserPrincipalName = httpContext.User.Identity.Name;
                            // I use email as login name, and here I try to fetch a user from my repository with that email.
                            User userObject = new Repository<User>().GetOne(x => x.Email == UserPrincipalName);
                            // If I find a user, and that user's UserID is equal to the value in paramValue, it's Ok! Otherwise, not.
                            return (userObject != null && userObject.UserID.ToString() == paramValue.ToString());
                        }
                    }
                }
                return false;
            }
    }

然后,使用它:

// Example usage (for instance from UserController)
[AdvancedAuthorize(RouteDataValue="userID")]
public ActionResult Edit(int userID)
{
     // everything as normal
}

[AdvancedAuthorize(RouteDataValue="userEmail")]
public ActionResult Delete(string userEmail)
{
     // everything as normal
}

当然,要使其工作,动作示例中的userIDuserEmail需要受到模型绑定器的约束(参数必须存在于RouteData.Values中)才能使其生效工作

答案 1 :(得分:0)

我不认为[Authorize(Roles = "DefaultUser")]意味着人们只能编辑自己的个人资料。这意味着DefaultUser角色中的每个人都可以编辑个人资料...以下是对它的讨论,这几乎是同一个问题:asp.net mvc authorization using roles

编辑: 好吧,那你的问题是角色和身份不适用于OpenID?只有当HttpContext.Current.User包含正确的主体时,授权才有效。如果您使用OpenID,这不是开箱即用的,但您必须在Global.asax中执行以下操作:

void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e)
{
    HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null)
    {
        string encTicket = authCookie.Value;
        if (!String.IsNullOrEmpty(encTicket))
        {
            FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encTicket);
            YourAppIdentity id = new YourAppIdentity(ticket);
            string username = ticket.Name;
            string[] roles = Roles.GetRolesForUser(username);
            GenericPrincipal prin = new GenericPrincipal(id, roles);
            HttpContext.Current.User = prin;
        }
    }
}

其中YourAppIdentity应该是实现IIdentity的东西......