Как реализовать проверку авторизации в ASP.NET MVC на основе данных сеанса?

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

В частной области это даже еще больше ограничено определенными областями / пользователем. Эти «области» определяются настройками базовой области, которая настраивается для каждой группы пользователей.

Так, например, пользователь может перейти по URL-адресу /Area/Controller/Action. Им потребуется разрешение на доступ к защищенной области, иначе они будут перенаправлены в режим входа.

Я читал о AuthorizeAttribute, но не уверен, как и где мне следует выполнять эти базовые проверки. Моя первоначальная догадка заключалась в том, чтобы сохранить объект пользователя в сеансе после успешного входа в систему с IP-адресом пользователя и подробностями о том, к чему у них есть доступ и т. Д.

Проверка авторизации для каждого защищенного вызова контроллера будет подтверждать, что действительный объект пользователя существует в сеансе, IP-адреса все еще совпадают, и пользователь имеет доступ к определенной области. Есть ли в этой настройке очевидные дыры?

Изменить: Где / как мне реализовать эти проверки, чтобы, когда контроллер помечен тегом [Авторизовать], он выполнял эти проверки объекта сеанса?

Будем очень признательны за любые указатели или предложения. Спасибо.


person Kelsey    schedule 20.07.2009    source источник


Ответы (3)


Похоже, я использовал специальный атрибут AuthorizeAttribute. На самом деле это было очень просто. Вот код:

namespace MyApp.Custom.Security
{
    public class Secure : AuthorizeAttribute
    {
        /// <summary>
        /// Checks to see if the user is authenticated and has a valid session object
        /// </summary>        
        /// <param name="httpContext"></param>
        /// <returns></returns>
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null) throw new ArgumentNullException("httpContext");

            // Make sure the user is authenticated.
            if (httpContext.User.Identity.IsAuthenticated == false) return false;

            // This will check my session variable and a few other things.
            return Helpers.SecurityHelper.IsSignedIn();
        }
    }
}

Затем на моих контроллерах мне просто нужно поместить атрибут [Secure], и он будет использовать мою функцию выше при каждом доступе к этому контроллеру. Довольно просто. Я также сделал атрибут [SecureByRole], который выполняет те же функции, но также проверяет информацию о моей пользовательской роли. Нет необходимости в том, что встроено в вуду из консервированного членства :)

person Kelsey    schedule 10.08.2009

Попробуйте взглянуть на класс RoleProvider. Это основная структура того, как ASP.net использует авторизацию на основе ролей для пользователей. И я думаю, вам следует использовать [Authorize (Roles = '...' )], чтобы использовать это.

person xandy    schedule 20.07.2009
comment
По возможности я стараюсь держаться подальше от запеченного ролевого решения. Не уверен, насколько это настраиваемое. - person Kelsey; 20.07.2009
comment
нет .. roleprovider - это базовый класс, который вы должны / могли бы реализовать для него самостоятельно. Чтобы начать с авторизации пользовательской роли, вы просто расширяете класс roleprovider и изменяете файл web.config, чтобы уведомить его. - person xandy; 20.07.2009

В моем предыдущем приложении я использовал простой HttpModule для дополнения аутентифицированного пользователя дополнительными ролями и т. Д. (Я сделал это, потому что мои требования были очень ограничены).

public class AuthorisationModule : IHttpModule
{
    public void Init( HttpApplication context )
    {
        context.AuthorizeRequest += AuthorizeRequest;
    }

    private void AuthorizeRequest(object sender, EventArgs e)
    {
        var currentUser = HttpContext.Current.User;
        if( !currentUser.IsAuthenticated() )
        {
            return;
        }

        var roles = new List<string>();
        // Add roles here using whatever logic is required

        var principal = new GenericPrincipal( currentUser.Identity, roles.ToArray() );
        HttpContext.Current.User = principal;
    }

    public void Dispose()
    {
        if(HttpContext.Current == null )
        {
            return;
        }

        if(HttpContext.Current.ApplicationInstance == null)
        {
            return;
        }

        HttpContext.Current.ApplicationInstance.AuthorizeRequest -= AuthorizeRequest;
    }
}
person Neal    schedule 20.07.2009