{"id":176043,"date":"2013-04-09T22:56:09","date_gmt":"2013-04-09T18:56:09","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=176043"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=176043","title":{"rendered":"<span class=\"post_title\">ASP.NET MVC \u0423\u0440\u043e\u043a 6. \u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t<b>\u0426\u0435\u043b\u044c \u0443\u0440\u043e\u043a\u0430<\/b>: \u0418\u0437\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0447\u0435\u0440\u0435\u0437 Cookie, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443 \u0438 \u043c\u0435\u0442\u043e\u0434\u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 IPrincipal. \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f (IHttpModule) \u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0430 IActionFilter. <\/p>\n<p>  <i>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043e\u0442\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435: \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432 asp.net mvc \u0432\u0441\u0435 \u0443\u0447\u0435\u0431\u043d\u0438\u043a\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0436\u0435 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f AspNetMembershipProvider, \u043e\u043d\u0430 \u0431\u044b\u043b\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"http:\/\/habrahabr.ru\/post\/142711\/\">http:\/\/habrahabr.ru\/post\/142711\/<\/a> (\u0441\u0435\u0439\u0447\u0430\u0441 \u0434\u043e\u0441\u0442\u0443\u043f \u0443\u0436\u0435 \u0437\u0430\u043a\u0440\u044b\u0442), \u043d\u043e \u043e\u0431\u044c\u044f\u0441\u043d\u0435\u043d\u043e \u044d\u0442\u043e \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u00ab\u043d\u0430\u0436\u0438\u043c\u0430\u0439 \u0438 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u0439, \u0447\u0442\u043e \u0442\u0430\u043c \u0432\u043d\u0443\u0442\u0440\u0438\u00bb. \u041f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u0435 \u0441 asp.net mvc \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u0441\u043c\u0443\u0442\u0438\u043b\u043e. \u0414\u0430\u043b\u0435\u0435, \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"http:\/\/habrahabr.ru\/post\/143024\/\">http:\/\/habrahabr.ru\/post\/143024\/<\/a> \u2014 \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u0442\u0438\u043c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u043c \u2013 \u043d\u0435\u043b\u044c\u0437\u044f. \u0418 \u044f \u0441\u043e\u0433\u043b\u0430\u0441\u0435\u043d \u0441 \u044d\u0442\u0438\u043c. \u0417\u0434\u0435\u0441\u044c \u0436\u0435, \u043c\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u0438\u0437\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u044f\u043a\u0438\u0435 \u0445\u0438\u0442\u0440\u044b\u0435 asp.net mvc \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u043f\u0440\u0438\u0435\u043c\u044b, \u0442\u0430\u043a \u0447\u0442\u043e \u044d\u0442\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0443\u0440\u043e\u043a\u043e\u0432.<\/i><\/p>\n<p>  <a name=\"habracut\"><\/a>  <\/p>\n<h5>\u041a\u0443\u043a\u0438\u0441\u044b<\/h5>\n<p>  \u041a\u0443\u043a\u0438\u0441\u044b \u2013 \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u043e\u0442\u0441\u044b\u043b\u0430\u0435\u043c\u0430\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043a\u0430\u0436\u0434\u044b\u043c (\u043f\u043e\u0447\u0442\u0438 \u043a\u0430\u0436\u0434\u044b\u043c) \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c. <\/p>\n<p>  \u0421\u0435\u0440\u0432\u0435\u0440 \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043e\u0442\u0432\u0435\u0442\u0430 \u043f\u0438\u0448\u0435\u0442:  <\/p>\n<pre><code>Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure] <\/code><\/pre>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>HTTP\/1.1 200 OK Content-type: text\/html Set-Cookie: name=value Set-Cookie: name2=value2; Expires=Wed, 09-Jun-2021 10:18:14 GMT <\/code><\/pre>\n<p>  \u0411\u0440\u0430\u0443\u0437\u0435\u0440 (\u0435\u0441\u043b\u0438 \u043d\u0435 \u0438\u0441\u0442\u0435\u043a\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043a\u0443\u043a\u0438\u0441\u0430) \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435:  <\/p>\n<pre><code>GET \/spec.html HTTP\/1.1 Host: www.example.org Cookie: name=value; name2=value2 Accept: *\/* <\/code><\/pre>\n<p>  \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c cookie (\/Areas\/Default\/Controllers\/HomeController.cs):   <\/p>\n<pre><code class=\"cs\">public ActionResult Index()         {             var cookie = new HttpCookie()              {                 Name =&quot;test_cookie&quot;,                  Value = DateTime.Now.ToString(&quot;dd.MM.yyyy&quot;),                 Expires = DateTime.Now.AddMinutes(10),             };             Response.SetCookie(cookie);             return View();         } <\/code><\/pre>\n<p>  \u0412 Chrome \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443:<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/d87\/f54\/f2a\/d87f54f2affafbf53c677a1c22da5c37.jpg\"\/><\/p>\n<p>  \u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043a\u0443\u043a\u0438\u0441\u043e\u0432:  <\/p>\n<pre><code class=\"cs\">var cookie = Request.Cookies[&quot;test_cookie&quot;]; <\/code><\/pre>\n<p>  \u0414\u0435\u043b\u0430\u0435\u043c \u0442\u043e\u0447\u043a\u0443 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c:<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/67e\/876\/397\/67e87639765e24cfd8ef5b1cb74242b6.jpg\"\/><\/p>\n<p>  <i>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u043a\u0443\u043a\u0438\u0441\u044b \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0441\u044b\u043b\u043a\u0435:<br \/>  <a href=\"http:\/\/www.nczonline.net\/blog\/2009\/05\/05\/http-cookies-explained\/\">http:\/\/www.nczonline.net\/blog\/2009\/05\/05\/http-cookies-explained\/<\/a><br \/>  <\/i><\/p>\n<h5>\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f <\/h5>\n<p>  \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043a\u0443\u043a\u0438\u0441\u043e\u0432. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0437\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f:  <\/p>\n<ul>\n<li><b>FormsAuthenticationTicket <\/b>\u2013 \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u044d\u0442\u0438\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435<\/li>\n<li>\u041d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <b>IPrincipal <\/b>\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432 <code>HttpContext.User<\/code> \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u043e\u043b\u0435\u0439 \u0438 <code>IIdentity<\/code> \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430.<\/li>\n<li>\u0414\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <b>IIdentity<\/b> \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/li>\n<li>\u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u0432 <b>BaseController<\/b> \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <b>CurrentUser<\/b> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0435\u043d.<\/li>\n<\/ul>\n<p>  \u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c.<br \/>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 IAuthentication \u0438 \u0435\u0433\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e CustomAuthentication (\/Global\/Auth\/IAuthentication.cs):<\/p>\n<pre><code class=\"cs\">public interface IAuthentication     {         \/\/\/ &lt;summary&gt;         \/\/\/ \u041a\u043e\u043d\u0435\u043a\u0441\u0442 (\u0442\u0443\u0442 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u0438 \u043a\u0443\u043a\u0438\u0441\u0430\u043c)         \/\/\/ &lt;\/summary&gt;         HttpContext HttpContext { get; set; }          User Login(string login, string password, bool isPersistent);          User Login(string login);          void LogOut();          IPrincipal CurrentUser { get; }     } <\/code><\/pre>\n<p>  \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f (\/Global\/Auth\/CustomAuthentication.cs):  <\/p>\n<pre><code class=\"cs\">    public class CustomAuthentication : IAuthentication     {         private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();          private const string cookieName = &quot;__AUTH_COOKIE&quot;;          public HttpContext HttpContext { get; set; }          [Inject]         public IRepository Repository { get; set; }          #region IAuthentication Members          public User Login(string userName, string Password, bool isPersistent)         {             User retUser = Repository.Login(userName, Password);             if (retUser != null)             {                 CreateCookie(userName, isPersistent);             }             return retUser;         }          public User Login(string userName)         {             User retUser = Repository.Users.FirstOrDefault(p =&gt; string.Compare(p.Email, userName, true) == 0);             if (retUser != null)             {                 CreateCookie(userName);             }             return retUser;         }          private void CreateCookie(string userName, bool isPersistent = false)         {             var ticket = new FormsAuthenticationTicket(                   1,                   userName,                   DateTime.Now,                   DateTime.Now.Add(FormsAuthentication.Timeout),                   isPersistent,                   string.Empty,                   FormsAuthentication.FormsCookiePath);              \/\/ Encrypt the ticket.             var encTicket = FormsAuthentication.Encrypt(ticket);              \/\/ Create the cookie.             var AuthCookie = new HttpCookie(cookieName)             {                 Value = encTicket,                 Expires = DateTime.Now.Add(FormsAuthentication.Timeout)             };             HttpContext.Response.Cookies.Set(AuthCookie);         }          public void LogOut()         {             var httpCookie = HttpContext.Response.Cookies[cookieName];             if (httpCookie != null)             {                 httpCookie.Value = string.Empty;             }         }          private IPrincipal _currentUser;          public IPrincipal CurrentUser         {             get             {                 if (_currentUser == null)                 {                     try                     {                         HttpCookie authCookie = HttpContext.Request.Cookies.Get(cookieName);                         if (authCookie != null && !string.IsNullOrEmpty(authCookie.Value))                         {                             var ticket = FormsAuthentication.Decrypt(authCookie.Value);                             _currentUser = new UserProvider(ticket.Name, Repository);                         }                         else                         {                             _currentUser = new UserProvider(null, null);                         }                     }                     catch (Exception ex)                     {                         logger.Error(&quot;Failed authentication: &quot; + ex.Message);                         _currentUser = new UserProvider(null, null);                     }                 }                 return _currentUser;             }         }         #endregion     }  <\/code><\/pre>\n<p>  \u0421\u0443\u0442\u044c \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443, \u043c\u044b, \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u043a <code>HttpContext.Request.Cookies<\/code> \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c <code>UserProvider<\/code>:<\/p>\n<pre><code class=\"cs\">var ticket = FormsAuthentication.Decrypt(authCookie.Value); _currentUser = new UserProvider(ticket.Name, Repository); <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 IRepository \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 IRepository.Login. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432 SqlRepository:   <\/p>\n<pre><code class=\"cs\">  public User Login(string email, string password)         {             return Db.Users.FirstOrDefault(p =&gt; string.Compare(p.Email, email, true) == 0 && p.Password == password);         } <\/code><\/pre>\n<p>  UserProvider, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 IPrincipal (\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u043e\u043b\u0435\u0439 \u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a IIdentity).<br \/>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043b\u0430\u0441\u0441 UserProvider (\/Global\/Auth\/UserProvider.cs):<\/p>\n<pre><code class=\"cs\">public class UserProvider : IPrincipal     {         private UserIndentity userIdentity { get; set; }          #region IPrincipal Members          public IIdentity Identity         {             get             {                 return userIdentity;             }         }          public bool IsInRole(string role)         {             if (userIdentity.User == null)             {                 return false;             }             return userIdentity.User.InRoles(role);         }          #endregion                   public UserProvider(string name, IRepository repository)         {             userIdentity = new UserIndentity();             userIdentity.Init(name, repository);         }           public override string ToString()         {             return userIdentity.Name;         }  <\/code><\/pre>\n<p>  \u041d\u0430\u0448 <code>UserProvider<\/code> \u0437\u043d\u0430\u0435\u0442 \u043f\u0440\u043e \u0442\u043e, \u0447\u0442\u043e \u0435\u0433\u043e <code>IIdentity<\/code> \u043a\u043b\u0430\u0441\u0441\u043e\u043c \u0435\u0441\u0442\u044c <code>UserIdentity<\/code>, \u0430 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u043d\u0430\u0435\u0442 \u043f\u0440\u043e \u043a\u043b\u0430\u0441\u0441 <code>User<\/code>, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <code>InRoles(role)<\/code>:<\/p>\n<pre><code class=\"cs\">public bool InRoles(string roles)         {             if (string.IsNullOrWhiteSpace(roles))             {                 return false;             }  var rolesArray = roles.Split(new[] { &quot;,&quot; }, StringSplitOptions.RemoveEmptyEntries);             foreach (var role in rolesArray)             { var hasRole = UserRoles.Any(p =&gt; string.Compare(p.Role.Code, role, true) == 0);                 if (hasRole)                 {                     return true;                 }             }             return false;         } <\/code><\/pre>\n<p>  \u0412 \u043c\u0435\u0442\u043e\u0434 <code>InRoles<\/code> \u043c\u044b \u043e\u0436\u0438\u0434\u0430\u0435\u043c, \u0447\u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043e \u0440\u043e\u043b\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043f\u0443\u0449\u0435\u043d\u044b \u043a \u0440\u0435\u0441\u0443\u0440\u0441\u0443, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u044f\u0442\u043e\u0439. \u0422.\u0435., \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u201cadmin,moderator,editor\u201d, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u0430 \u0438\u0437 \u0440\u043e\u043b\u0435\u0439 \u0435\u0441\u0442\u044c \u0443 \u043d\u0430\u0448\u0435\u0433\u043e <code>User<\/code> \u2013 \u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0437\u0430\u0447\u0435\u043d\u0438\u0435 \u00ab\u0438\u0441\u0442\u0438\u043d\u0430\u00bb (\u0434\u043e\u0441\u0442\u0443\u043f \u0435\u0441\u0442\u044c). \u0421\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c \u043f\u043e \u043f\u043e\u043b\u044e Role.Code, \u0430 \u043d\u0435 Role.Name.<br \/>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043b\u0430\u0441\u0441 UserIdentity (\/Global\/Auth\/UserIdentity.cs):   <\/p>\n<pre><code class=\"cs\"> public class UserIndentity : IIdentity     {         public User User { get; set; }          public string AuthenticationType         {             get             {                 return typeof(User).ToString();             }         }          public bool IsAuthenticated         {             get             {                 return User != null;             }         }          public string Name         {             get             {                 if (User != null)                 {                     return User.Email;                 }                 \/\/\u0438\u043d\u0430\u0447\u0435 \u0430\u043d\u043e\u043d\u0438\u043c                 return &quot;anonym&quot;;             }         }          public void Init(string email, IRepository repository)         {             if (!string.IsNullOrEmpty(email))             {                 User = repository.GetUser(email);             }         }     } <\/code><\/pre>\n<p>  \u0412 <code>IRepository<\/code> \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <code>GetUser(email)<\/code>. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043b\u044f <code>SqlRepository.GetUser()<\/code> (LessonProject.Model:\/SqlRepository\/User.cs):<\/p>\n<pre><code class=\"cs\">   public User GetUser(string email)         { return Db.Users.FirstOrDefault(p =&gt; string.Compare(p.Email, email, true) == 0);         } <\/code><\/pre>\n<p>  \u041f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435 \u0433\u043e\u0442\u043e\u0432\u043e. \u0412\u044b\u0432\u0435\u0434\u0435\u043c CurrentUser \u0432 BaseController:   <\/p>\n<pre><code class=\"cs\">[Inject]         public IAuthentication Auth { get; set; } public User CurrentUser         {             get             {                 return ((UserIndentity)Auth.CurrentUser.Identity).User;             }         } <\/code><\/pre>\n<p>  \u0414\u0430, \u044d\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0438\u043b\u044c\u043d\u043e\u0435 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u043d\u0438\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a, \u0432\u0432\u0435\u0434\u0435\u043c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>IUserProvider<\/code>, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043d\u0430\u043c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e <code>User<\/code>:  <\/p>\n<pre><code class=\"cs\">public interface IUserProvider     {         User User { get; set; }     } \u2026 public class UserIndentity : IIdentity, IUserProvider     {         \/\/\/ &lt;summary&gt;         \/\/\/ \u0422\u0435\u043a\u0449\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c         \/\/\/ &lt;\/summary&gt;         public User User { get; set; } \u2026 [Inject] public IAuthentication Auth { get; set; }  public User CurrentUser {     get     {         return ((IUserProvider)Auth.CurrentUser.Identity).User;     } } <\/code><\/pre>\n<p>  \u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0432\u0441\u0451.<br \/>  \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0448 IAuthentication + CustomAuthentication \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044e \u043a Ninject (\/App_Start\/NinjectWebCommon.cs):<\/p>\n<pre><code class=\"cs\">kernel.Bind&lt;IAuthentication&gt;().To&lt;CustomAuthentication&gt;().InRequestScope(); <\/code><\/pre>\n<p>  \u041f\u043e\u0442\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 AuthenticateRequest \u0441\u043e\u0432\u0435\u0440\u0448\u0430\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438:  <\/p>\n<pre><code class=\"cs\">public class AuthHttpModule : IHttpModule     {         public void Init(HttpApplication context)         {             context.AuthenticateRequest += new EventHandler(this.Authenticate);         }          private void Authenticate(Object source, EventArgs e)         {             HttpApplication app = (HttpApplication)source;             HttpContext context = app.Context;              var auth = DependencyResolver.Current.GetService&lt;IAuthentication&gt;();             auth.HttpContext = context;      context.User = auth.CurrentUser;         }          public void Dispose()         {         }     }  <\/code><\/pre>\n<p>  \u0412\u0441\u044f \u0441\u043e\u043b\u044c \u0432 \u0441\u0442\u0440\u043e\u043a\u0430\u0445: <code>auth.HttpContext = context \u0438 context.User = auth.CurrentUser<\/code>. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0448 \u043c\u043e\u0434\u0443\u043b\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0443\u0437\u043d\u0430\u0435\u0442 \u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0445\u0441\u044f \u0432 \u043d\u0435\u043c \u043a\u0443\u043a\u0438\u0441\u0430\u0445, \u0442\u0443 \u0436\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0438\u043c\u0435\u043d\u0438, \u043f\u043e \u043d\u0435\u043c\u0443 \u043e\u043d \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432 BaseController. \u041d\u043e \u043d\u0435 \u0441\u0440\u0430\u0437\u0443 \u0432\u0441\u0451, \u0430 \u043f\u043e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044e.<br \/>  \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c \u0432 Web.config:   <\/p>\n<pre><code class=\"xml\"> &lt;system.web&gt; \u2026     &lt;httpModules&gt;       &lt;add name=&quot;AuthHttpModule&quot; type=&quot;LessonProject.Global.Auth.AuthHttpModule&quot;\/&gt;     &lt;\/httpModules&gt; &lt;\/system.web&gt; <\/code><\/pre>\n<p>  \u041f\u043b\u0430\u043d \u0442\u0430\u043a\u043e\u0432:  <\/p>\n<ul>\n<li>\u041d\u0430\u0432\u0435\u0440\u0445\u0443 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438\u043b\u0438 \u043d\u0435\u0442. \u0415\u0441\u043b\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d, \u0442\u043e \u0435\u0433\u043e email \u0438 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442, \u0442\u043e \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044e<\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u043e\u0440\u043c\u0443 \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u0430<\/li>\n<li>\u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0432\u0432\u0435\u043b \u0434\u0430\u043d\u043d\u044b\u0435 \u2013 \u0442\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443<\/li>\n<li>\u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u2013 \u0442\u043e \u0443\u0431\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e<\/li>\n<\/ul>\n<p>  \u041f\u043e\u0435\u0445\u0430\u043b\u0438. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c <code>Html.Action(\u201cUserLogin\u201d, \u201cHome\u201d)<\/code> \u2013 \u044d\u0442\u043e partial view (\u0442.\u0435. \u043a\u0443\u0441\u043e\u043a \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 Layout) \u2013 \u0442.\u0435. \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0433\u0434\u0435 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d, \u0430 \u043d\u0435 \u0432 RenderBody(). <br \/>  _Layout.cshtml (\/Areas\/Default\/Views\/Shared\/_Layout.cshtml):<\/p>\n<pre><code class=\"html\">&lt;body&gt; &lt;div class=&quot;navbar navbar-fixed-top&quot;&gt;         &lt;div class=&quot;navbar-inner&quot;&gt;             &lt;div class=&quot;container&quot;&gt;                 &lt;ul class=&quot;nav nav-pills pull-right&quot;&gt;                     @Html.Action(&quot;UserLogin&quot;, &quot;Home&quot;)                 &lt;\/ul&gt;             &lt;\/div&gt;         &lt;\/div&gt;     &lt;\/div&gt;      @RenderBody()  HomeController.cs: public ActionResult UserLogin()         {             return View(CurrentUser);         }  <\/code><\/pre>\n<p>  UserLogin.cshtml (\/Areas\/Default\/Views\/Home\/UserLogin.cshtml):<\/p>\n<pre><code class=\"html\">@model LessonProject.Model.User  @if (Model != null) {     &lt;li&gt;@Model.Email&lt;\/li&gt;     &lt;li&gt;@Html.ActionLink(&quot;\u0412\u044b\u0445\u043e\u0434&quot;, &quot;Logout&quot;, &quot;Login&quot;)&lt;\/li&gt; } else {     &lt;li&gt;@Html.ActionLink(&quot;\u0412\u0445\u043e\u0434&quot;, &quot;Index&quot;, &quot;Login&quot;)&lt;\/li&gt;     &lt;li&gt;@Html.ActionLink(&quot;\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f&quot;, &quot;Register&quot;, &quot;User&quot;)&lt;\/li&gt; } <\/code><\/pre>\n<p>  \u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0432\u0445\u043e\u0434\u0430 \u0432\u044b\u0445\u043e\u0434\u0430 LoginController (\/Areas\/Default\/Controllers\/LoginController.cs):<\/p>\n<pre><code class=\"cs\">public class LoginController : DefaultController     {         [HttpGet]         public ActionResult Index()         {             return View(new LoginView());         }          [HttpPost]         public ActionResult Index(LoginView loginView)         {             if (ModelState.IsValid)             { var user = Auth.Login(loginView.Email, loginView.Password, loginView.IsPersistent);                 if (user != null)                 {                     return RedirectToAction(&quot;Index&quot;, &quot;Home&quot;);                 }                 ModelState[&quot;Password&quot;].Errors.Add(&quot;\u041f\u0430\u0440\u043e\u043b\u0438 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442&quot;);             }             return View(loginView);         }          public ActionResult Logout()         {             Auth.LogOut();             return RedirectToAction(&quot;Index&quot;, &quot;Home&quot;);         }     }  <\/code><\/pre>\n<p>  LoginView.cs (\/Models\/ViewModels\/LoginView.cs):  <\/p>\n<pre><code class=\"cs\">    public class LoginView     {         [Required(ErrorMessage = &quot;\u0412\u0432\u0435\u0434\u0438\u0442\u0435 email&quot;)]         public string Email { get; set; }          [Required(ErrorMessage = &quot;\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c&quot;)]         public string Password { get; set; }          public bool IsPersistent { get; set; }     }  <\/code><\/pre>\n<p>  \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u0430 Index.cshtml (\/Areas\/Default\/Views\/Index.cshtml):<\/p>\n<pre><code class=\"html\">@model LessonProject.Models.ViewModels.LoginView @{     ViewBag.Title = &quot;\u0412\u0445\u043e\u0434&quot;;     Layout = &quot;~\/Areas\/Default\/Views\/Shared\/_Layout.cshtml&quot;; }  &lt;h2&gt;\u0412\u0445\u043e\u0434&lt;\/h2&gt;  @using (Html.BeginForm(&quot;Index&quot;, &quot;Login&quot;, FormMethod.Post, new { @class = &quot;form-horizontal&quot; })) {     &lt;fieldset&gt;         &lt;legend&gt;\u0412\u0445\u043e\u0434&lt;\/legend&gt;         &lt;div class=&quot;control-group&quot;&gt;             &lt;label class=&quot;control-label&quot; for=&quot;Email&quot;&gt;                 Email&lt;\/label&gt;             &lt;div class=&quot;controls&quot;&gt;                 @Html.TextBox(&quot;Email&quot;, Model.Email, new { @class = &quot;input-xlarge&quot; })                 &lt;p class=&quot;help-block&quot;&gt;\u0412\u0432\u0435\u0434\u0438\u0442\u0435 Email&lt;\/p&gt;                 @Html.ValidationMessage(&quot;Email&quot;)             &lt;\/div&gt;          &lt;\/div&gt;         &lt;div class=&quot;control-group&quot;&gt;             &lt;label class=&quot;control-label&quot; for=&quot;Password&quot;&gt;                 \u041f\u0430\u0440\u043e\u043b\u044c&lt;\/label&gt;             &lt;div class=&quot;controls&quot;&gt;                 @Html.Password(&quot;Password&quot;, Model.Password, new { @class = &quot;input-xlarge&quot; })                 @Html.ValidationMessage(&quot;Password&quot;)             &lt;\/div&gt;         &lt;\/div&gt;         &lt;div class=&quot;form-actions&quot;&gt;             &lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;                 \u0412\u043e\u0439\u0442\u0438&lt;\/button&gt;         &lt;\/div&gt;     &lt;\/fieldset&gt; }  <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c:<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/5f6\/1ae\/027\/5f61ae0277f1a97e5144eaca69343615.jpg\"\/><\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438:<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/d62\/e2c\/691\/d62e2c691614c8e8587ef6269e85b102.jpg\"\/><\/p>\n<p>  \u0412\u0441\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <a href=\"https:\/\/bitbucket.org\/chernikov\/lessons\">https:\/\/bitbucket.org\/chernikov\/lessons<\/a>    \t \t\t   \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/176043\/\"> http:\/\/habrahabr.ru\/post\/176043\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t<b>\u0426\u0435\u043b\u044c \u0443\u0440\u043e\u043a\u0430<\/b>: \u0418\u0437\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0447\u0435\u0440\u0435\u0437 Cookie, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443 \u0438 \u043c\u0435\u0442\u043e\u0434\u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 IPrincipal. \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f (IHttpModule) \u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0430 IActionFilter. <\/p>\n<p>  <i>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043e\u0442\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435: \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432 asp.net mvc \u0432\u0441\u0435 \u0443\u0447\u0435\u0431\u043d\u0438\u043a\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0436\u0435 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f AspNetMembershipProvider, \u043e\u043d\u0430 \u0431\u044b\u043b\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"http:\/\/habrahabr.ru\/post\/142711\/\">http:\/\/habrahabr.ru\/post\/142711\/<\/a> (\u0441\u0435\u0439\u0447\u0430\u0441 \u0434\u043e\u0441\u0442\u0443\u043f \u0443\u0436\u0435 \u0437\u0430\u043a\u0440\u044b\u0442), \u043d\u043e \u043e\u0431\u044c\u044f\u0441\u043d\u0435\u043d\u043e \u044d\u0442\u043e \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u00ab\u043d\u0430\u0436\u0438\u043c\u0430\u0439 \u0438 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u0439, \u0447\u0442\u043e \u0442\u0430\u043c \u0432\u043d\u0443\u0442\u0440\u0438\u00bb. \u041f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u0435 \u0441 asp.net mvc \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u0441\u043c\u0443\u0442\u0438\u043b\u043e. \u0414\u0430\u043b\u0435\u0435, \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"http:\/\/habrahabr.ru\/post\/143024\/\">http:\/\/habrahabr.ru\/post\/143024\/<\/a> \u2014 \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u0442\u0438\u043c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u043c \u2013 \u043d\u0435\u043b\u044c\u0437\u044f. \u0418 \u044f \u0441\u043e\u0433\u043b\u0430\u0441\u0435\u043d \u0441 \u044d\u0442\u0438\u043c. \u0417\u0434\u0435\u0441\u044c \u0436\u0435, \u043c\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u0438\u0437\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u044f\u043a\u0438\u0435 \u0445\u0438\u0442\u0440\u044b\u0435 asp.net mvc \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u043f\u0440\u0438\u0435\u043c\u044b, \u0442\u0430\u043a \u0447\u0442\u043e \u044d\u0442\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0443\u0440\u043e\u043a\u043e\u0432.<\/i><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-176043","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/176043","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=176043"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/176043\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=176043"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=176043"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=176043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}