Как авторизовать пользователя OpenID на контроллере MVC

Я смотрю на [Authorize(Roles = "DefaultUser")], доступный в MVC, но я не могу понять, могу ли я использовать его с DotNetOpenAuth.

Я использую OpenID в качестве единственного поставщика членства, но у меня есть несколько общих элементов в таблице UserProfile. Я не хочу, чтобы кто-либо, кроме соответствующего пользователя, имел доступ к контроллеру редактирования.

ПРИМЕР:
UserID 2 не должен иметь доступ к /Users/Edit/1, но он МОЖЕТ получить доступ к /Users/Edit/2


person Chase Florell    schedule 25.06.2010    source источник


Ответы (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
}

Конечно, для того, чтобы это работало, userID и userEmail в примерах действий должны быть связаны привязкой моделей (параметры должны существовать в RouteData.Values), чтобы он работал.

person Terje    schedule 26.06.2010
comment
это помещается в void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e)? - person Chase Florell; 26.06.2010
comment
Нет. Вы создаете свой UserIDAuthorizeAttribute (или эквивалент), который расширяет AuthorizeAttribute и переопределяет AuthorizeCore. Здесь вы проверяете, если (base.AuthorizeCore (context)) {... поместите сюда код выше ...} - person Terje; 26.06.2010
comment
Прости ... Я действительно понятия не имею. - person Chase Florell; 27.06.2010

Я не думаю, что [Authorize(Roles = "DefaultUser")] означает, что люди могут редактировать только свой профиль. Это скорее означает, что каждый в роли DefaultUser может редактировать профили ... Вот обсуждение этого, это почти тот же вопрос: авторизация asp.net mvc с использованием ролей

РЕДАКТИРОВАТЬ: Хорошо, тогда ваша проблема в том, что роли и личность не работают с 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 ...

person apolka    schedule 25.06.2010
comment
Нет, я это понимаю. Наверное, мне следовало использовать [Authorize(Users = "DefaultUser")] в моем примере - person Chase Florell; 25.06.2010