Вопрос

Проблема, которую я вижу в этом коде, заключается в том, что его придется часто использовать повторно;все, что редактируется/создается аутентифицированным пользователем (за исключением администраторов сайта), будет иметь доступ только к объектам их «студий».

Мой вопрос ко всем вам;как бы вы изменили это, чтобы уровень обслуживания можно было абстрагировать от знаний клиента.Позже я планирую повторно использовать уровень сервиса в автономном настольном приложении.

Пожалуйста, пролейте свет на мои ошибочные пути!Я очень ценю это.

Авторизеовнератрибуте.cs (Атрибут Авторизации)

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    // Get the authentication cookie
    string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = httpContext.Request.Cookies[cookieName];

    // If the cookie can't be found, don't issue the ticket
    if (authCookie == null) return false;

    // Get the authentication ticket and rebuild the principal & identity
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    string[] userData = authTicket.UserData.Split(new[] { '|' });

    int userId = Int32.Parse(userData[0]);
    int studioID = Int32.Parse(userData[1]);
    GenericIdentity userIdentity = new GenericIdentity(authTicket.Name);
    WebPrincipal userPrincipal = new WebPrincipal(userIdentity, userId, studioID);
    httpContext.User = userPrincipal;

    return true;
}

Внутри моего «Пользовательского» контроллера прикрепите этот атрибут к любому методу, для которого требуется владелец.

    [AuthorizeOwner]
    public ActionResult Edit(int Id)
    {
        IUser user = userService.GetById(HttpContext.User, Id);
        return View(user);
    }

Теперь на моем уровне обслуживания я проверяю переданный IPrincipal, имеет ли он доступ к запрашиваемому объекту. Вот здесь и воняло:

Пользовательская служба.cs

    public IUser GetById(IPrincipal authUser, int id)
    {
        if (authUser == null) throw new ArgumentException("user");

        WebPrincipal webPrincipal = authUser as WebPrincipal;
        if (webPrincipal == null) throw new AuthenticationException("User is not logged in");

        IUser user = repository.GetByID(id).FirstOrDefault();
        if (user != null)
        {
            if (user.StudioID != webPrincipal.StudioID) throw new AuthenticationException("User does not have ownership of this object");
            return user;
        }

        throw new ArgumentException("Couldn't find a user by the id specified", "id");
    }
Это было полезно?

Решение

Я не уверен, что буду хранить настоящие идентификаторы в файле cookie, это слишком открыто.Я был бы более склонен использовать хеш сеанса для хранения этих данных, сохраняя их на сервере и не раскрывая.

Я бы также использовал Модель (путем передачи идентификатора пользователя), чтобы определить, какие объекты возвращать, т.е.те, у которых есть соответствующий studioID.Таким образом, вашему контроллеру придется вызывать только «GetObjects(int id)», если у него нет доступа ни к чему, вы получите обратно нулевую или пустую коллекцию.Мне кажется, это чище.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top