2009-09-14 3 views
1

Я создаю веб-приложение с использованием ASP.NET MVC с двумя очень разными типами пользователей. Я приведу пример и скажу, что один тип - производители контента (издатели), а другой - потребители контента (подписчики).Пользовательская авторизация ASP.NET MVC

Я не планирую использовать встроенные средства авторизации ASP.NET, поскольку разделение моих типов пользователей является дихотомией, вы либо издатель, либо подписчик, а не оба. Таким образом, встроенная авторизация более сложна, чем мне нужно. Плюс я планирую использовать MySQL.

Я думал о хранении их в одной таблице с полем перечисления (технически поле int). Затем создадим атрибут CustomAuthorizationAttribute, в котором я бы перешел в userType, необходимый для этой страницы.

Например, для страницы PublishContent потребуется userType == UserType.Publisher, поэтому доступ к ней могут получить только издатели. Таким образом, создание этого атрибута дает мне доступ к HttpContextBase, который содержит стандартное поле пользователя (типа IPrincipal). Как получить поле UserType на этом IPrincipal? Итак, тогда мой атрибут будет выглядеть так:

Или кто-нибудь думает, что мой весь подход испорчен?

ответ

3

Я бы по-прежнему использовал встроенную аутентификацию форм ASP.NET, но просто настраивал ее под свои нужды.

Таким образом, вам нужно получить свой пользовательский класс для реализации интерфейса IPrincipal, а затем написать свою собственную обработку файлов cookie. Затем вы можете просто использовать встроенный атрибут [Авторизовать].

В настоящее время у меня есть что-то похожее на следующее ...

В моей global.asax

protected void Application_AuthenticateRequest() 
{ 
    HttpCookie cookie = Request.Cookies.Get(FormsAuthentication.FormsCookieName); 
    if (cookie == null) 
     return; 

    bool isPersistent; 
    int webuserid = GetUserId(cookie, out isPersistent); 

    //Lets see if the user exists 
    var webUserRepository = Kernel.Get<IWebUserRepository>(); 

    try 
    { 
     WebUser current = webUserRepository.GetById(webuserid); 

     //Refresh the cookie 
     var formsAuth = Kernel.Get<IFormsAuthService>(); 

     Response.Cookies.Add(formsAuth.GetAuthCookie(current, isPersistent)); 
     Context.User = current; 
    } 
    catch (Exception ex) 
    { 
     //TODO: Logging 
     RemoveAuthCookieAndRedirectToDefaultPage(); 
    } 
} 

private int GetUserId(HttpCookie cookie, out bool isPersistent) 
{ 
    try 
    { 
     FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value); 
     isPersistent = ticket.IsPersistent; 
     return int.Parse(ticket.UserData); 
    } 
    catch (Exception ex) 
    { 
     //TODO: Logging 

     RemoveAuthCookieAndRedirectToDefaultPage(); 
     isPersistent = false; 
     return -1; 
    } 
} 

AccountController.cs

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult LogOn(LogOnForm logOnForm) 
{ 
    try 
    { 
     if (ModelState.IsValid) 
     { 
      WebUser user = AccountService.GetWebUserFromLogOnForm(logOnForm); 

      Response.Cookies.Add(FormsAuth.GetAuthCookie(user, logOnForm.RememberMe)); 

      return Redirect(logOnForm.ReturnUrl); 
     } 
    } 
    catch (ServiceLayerException ex) 
    { 
     ex.BindToModelState(ModelState); 
    } 
    catch 
    { 
     ModelState.AddModelError("*", "There was server error trying to log on, try again. If your problem persists, please contact us."); 
    } 

    return View("LogOn", logOnForm); 
} 

И, наконец, моя FormsAuthService:

public HttpCookie GetAuthCookie(WebUser webUser, bool createPersistentCookie) 
{ 
    var ticket = new FormsAuthenticationTicket(1, 
               webUser.Email, 
               DateTime.Now, 
               DateTime.Now.AddMonths(1), 
               createPersistentCookie, 
               webUser.Id.ToString()); 

    string cookieValue = FormsAuthentication.Encrypt(ticket); 

    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue) 
         { 
          Path = "/" 
         }; 

    if (createPersistentCookie) 
     authCookie.Expires = ticket.Expiration; 

    return authCookie; 
} 

HTHs
Charles

+0

Это сделало бы для непроверенного беспорядка в MVC. Определенно не правильный подход. –

+1

Неустойчивый беспорядок? Едва. Это очень недальновидно. И служба 'AccountService', и' FormsAuth' являются интерфейсами, которые вводятся в 'AccountController', что делает это полностью проверяемым. Все остальное зависит от FormsAuthentication (как еще вы делаете formauth?), Который, как вам известно, как правило, трудно проверить - как указывает проект ASP.NET MVC по умолчанию. Конечно, вы можете извлечь вызовы FormsAuthentication в службу, но что действительно нужно достичь, учитывая, где это вызовы? – Charlino