Как реализовать проверки авторизации в ASP.NET MVC на основе данных сеанса? - PullRequest
8 голосов
/ 20 июля 2009

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

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

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

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

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

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

Любые указатели или предложения будут высоко оценены. Спасибо.

Ответы [ 4 ]

11 голосов
/ 10 августа 2009

Ну, похоже, я пошел с пользовательским атрибутом 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], который выполняет все те же функции, но также проверяет информацию о моих пользовательских ролях. Не надо за все то, что строили вуду из консервированного членства :)

2 голосов
/ 20 июля 2009

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

1 голос
/ 02 апреля 2013
[Authorize]
public class BaseController : Controller
{
    protected override void OnAuthorization(AuthorizationContext authContext)
    {
        if
            (
            !User.Identity.IsAuthenticated &&
            Request.LogonUserIdentity != null &&
            Request.LogonUserIdentity.IsAuthenticated
            )
        {
            var logonUserIdentity = Request.LogonUserIdentity.Name;
            if (!string.IsNullOrEmpty(logonUserIdentity))
            {
                if (logonUserIdentity.Contains("\\"))
                    logonUserIdentity = logonUserIdentity.Substring(logonUserIdentity.IndexOf("\\") + 1);

                var db = new UsersContext();
                var loginUser =
                    db.UserProfiles.FirstOrDefault(x => x.UserName == logonUserIdentity);

                //Auto-Login Windows Identity
                if (loginUser == null)
                    loginUser = CreateUser(db, logonUserIdentity);

                if (loginUser != null)
                {
                    FormsAuthentication.SetAuthCookie(loginUser.UserName, true);

                    string returnUrl = Request.RawUrl;
                    if (!string.IsNullOrEmpty(returnUrl))
                        Response.Redirect(returnUrl);
                    Response.Redirect("~/");

                }
            }
        }
    }

    private static UserProfile CreateUser(UsersContext db, string logonUserIdentity)
    {
        var user = new UserProfile {UserName = logonUserIdentity};
        db.UserProfiles.Add(user);
        db.SaveChanges();
        return user;
    }
}
1 голос
/ 20 июля 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...