ASP MVC: путаница при реализации ASP MVC Security - PullRequest
6 голосов
/ 05 июля 2011

Я реализую часть безопасности приложения ASP MVC, и меня смущает вопрос о том, как реализовать пользовательский поставщик членства, поскольку, похоже, есть много функциональных возможностей, которые я бы не использовал.

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

Однако, когда я вижуМетоды MembershipProvider и тега AuthorizeAttribute предполагают, что я буду использовать роли, которые мое приложение не использует, у нас просто есть группы разрешений, которые представляют собой просто разрешения, сгруппированные вместе для определенных групп пользователей, но они имеют тенденцию изменяться во времени.

Таким образом, в принципе, единственное, что мне нужно, это что-то, что при выполнении запроса проверяет, хранится ли менеджер безопасности в сеансе (если это не так, пользователь не аутентифицирован и будет перенаправлен на страницу входа) изатем получите этот объект из сеанса и выполните операцию с ним, чтобы узнать, может ли пользователь получить доступ к представлению.

Каков наилучший подход для этого?Я читал, что обход пользовательского членства не был хорошей идеей.

1 Ответ

1 голос
/ 05 июля 2011

Обновление : я недавно столкнулся с этим и выяснил, как использовать AuthorizeAttribute, чтобы делать именно так, как вы хотели. Мой атрибут, который проверяет, является ли пользователь администратором, работает следующим образом:

public class AuthorizeAdminAttribute : AuthorizeAttribute
{
    public bool IsValidUser { get; protected set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null) { throw new ArgumentNullException("httpContext"); }

        // Make sure Forms authentication shows the user as authenticated
        if (httpContext.User.Identity.IsAuthenticated == false) return false;

        // Retrieve the unit of work from Windsor, and determine if the current user is an admin
        var unitOfWork = Bootstrapper.WindsorContainer.Resolve<IUnitOfWork>();
        var user = new UserByIdQuery(unitOfWork).WithUserId((int)Membership.GetUser().ProviderUserKey).Execute();

        if (user == null)
            return false;

        // Otherwise the logged in user is a real user in the system
        IsValidUser = true;

        return user.IsAdmin;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext == null) { throw new ArgumentNullException("filterContext"); }

        // If this user is a valid user but not an admin, redirect to the homepage
        if (IsValidUser)
        {
            // Redirect them to the homepage
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
            {
                { "area", "" },
                { "action", "Index" },
                { "controller", "Home" }
            });
        }
        else
        {
            // User isn't logged in, perform normal operations
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

По сути, вам нужно использовать AuthorizeCore(), чтобы определить, вошел ли пользователь в систему, сохранить этот результат и затем выполнить авторизацию для ролей в вашей системе. Затем в вашем HandleUnauthorizedRequest вы должны выяснить, был ли запрос неавторизованным, потому что пользователь не вошел в систему, или это было, потому что он не был авторизован.


Старый ответ Я использую атрибут Authorize, создав подкласс класса AuthorizeAttribute. Так, например:
public class MyCustomAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null) { throw new ArgumentNullException("httpContext"); }

        // Make sure Forms authentication shows the user as authenticated
        if (httpContext.User.Identity.IsAuthenticated == false) return false;

        // replace with whatever code you need to call to determine if the user is authorized
        return IsUserAuthorized();
    }
}

Теперь, когда контроллер или действие вызывается и имеет [MyCustomAuthorize], он запускает этот код, чтобы определить, авторизован ли пользователь на основе вашей пользовательской логики, и, если нет, перенаправит его точно так, как атрибут [Authorize] будет.

Я не знаю, является ли это лучшим подходом, но это то, что я придумал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...