Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
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
GET /spec.html HTTP/1.1 Host: www.example.org Cookie: name=value; name2=value2 Accept: */*
public ActionResult Index() { var cookie = new HttpCookie() { Name ="test_cookie", Value = DateTime.Now.ToString("dd.MM.yyyy"), Expires = DateTime.Now.AddMinutes(10), }; Response.SetCookie(cookie); return View(); }
var cookie = Request.Cookies["test_cookie"];
HttpContext.User
to verify the roles and IIdentity
interface. public interface IAuthentication { /// <summary> /// ( ) /// </summary> HttpContext HttpContext { get; set; } User Login(string login, string password, bool isPersistent); User Login(string login); void LogOut(); IPrincipal CurrentUser { get; } }
public class CustomAuthentication : IAuthentication { private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); private const string cookieName = "__AUTH_COOKIE"; 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 => 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("Failed authentication: " + ex.Message); _currentUser = new UserProvider(null, null); } } return _currentUser; } } #endregion }
HttpContext.Request.Cookies
and initialize the UserProvider
: var ticket = FormsAuthentication.Decrypt(authCookie.Value); _currentUser = new UserProvider(ticket.Name, Repository);
public User Login(string email, string password) { return Db.Users.FirstOrDefault(p => string.Compare(p.Email, email, true) == 0 && p.Password == password); }
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; }
UserProvider
knows that its IIdentity
class is UserIdentity
, and therefore it knows about the User
class, inside which we implement the InRoles(role)
method: public bool InRoles(string roles) { if (string.IsNullOrWhiteSpace(roles)) { return false; } var rolesArray = roles.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); foreach (var role in rolesArray) { var hasRole = UserRoles.Any(p => string.Compare(p.Role.Code, role, true) == 0); if (hasRole) { return true; } } return false; }
InRoles
method InRoles
we expect to InRoles
query about the roles that are allowed to the resource, separated by commas. Ie, for example, “admin, moderator, editor”, if at least one of the roles is in our User
- then we return the value “true” (access is available). We compare the field Role.Code, and not Role.Name. 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; } // return "anonym"; } } public void Init(string email, IRepository repository) { if (!string.IsNullOrEmpty(email)) { User = repository.GetUser(email); } } }
IRepository
add a new method GetUser(email)
. Implementation for SqlRepository.GetUser()
(LessonProject.Model: /SqlRepository/User.cs): public User GetUser(string email) { return Db.Users.FirstOrDefault(p => string.Compare(p.Email, email, true) == 0); }
[Inject] public IAuthentication Auth { get; set; } public User CurrentUser { get { return ((UserIndentity)Auth.CurrentUser.Identity).User; } }
IUserProvider
, from which we will demand to return us an authorized User
: public interface IUserProvider { User User { get; set; } } … public class UserIndentity : IIdentity, IUserProvider { /// <summary> /// /// </summary> public User User { get; set; } … [Inject] public IAuthentication Auth { get; set; } public User CurrentUser { get { return ((IUserProvider)Auth.CurrentUser.Identity).User; } }
kernel.Bind<IAuthentication>().To<CustomAuthentication>().InRequestScope();
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<IAuthentication>(); auth.HttpContext = context; context.User = auth.CurrentUser; } public void Dispose() { } }
auth.HttpContext = context context.User = auth.CurrentUser
. As soon as our authorization module learns about the context and the cookies it contains, the same instantly gets access to the name, it receives the user data in the repository and returns it to the BaseController. But not all at once, but on demand. <system.web> … <httpModules> <add name="AuthHttpModule" type="LessonProject.Global.Auth.AuthHttpModule"/> </httpModules> </system.web>
Html.Action(“UserLogin”, “Home”)
- this is a partial view (ie, a piece of code that does not have a Layout) - that is, it is displayed where it is registered, and not in RenderBody (). <body> <div class="navbar navbar-fixed-top"> <div class="navbar-inner"> <div class="container"> <ul class="nav nav-pills pull-right"> @Html.Action("UserLogin", "Home") </ul> </div> </div> </div> @RenderBody() HomeController.cs: public ActionResult UserLogin() { return View(CurrentUser); }
@model LessonProject.Model.User @if (Model != null) { <li>@Model.Email</li> <li>@Html.ActionLink("", "Logout", "Login")</li> } else { <li>@Html.ActionLink("", "Index", "Login")</li> <li>@Html.ActionLink("", "Register", "User")</li> }
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("Index", "Home"); } ModelState["Password"].Errors.Add(" "); } return View(loginView); } public ActionResult Logout() { Auth.LogOut(); return RedirectToAction("Index", "Home"); } }
public class LoginView { [Required(ErrorMessage = " email")] public string Email { get; set; } [Required(ErrorMessage = " ")] public string Password { get; set; } public bool IsPersistent { get; set; } }
@model LessonProject.Models.ViewModels.LoginView @{ ViewBag.Title = ""; Layout = "~/Areas/Default/Views/Shared/_Layout.cshtml"; } <h2></h2> @using (Html.BeginForm("Index", "Login", FormMethod.Post, new { @class = "form-horizontal" })) { <fieldset> <legend></legend> <div class="control-group"> <label class="control-label" for="Email"> Email</label> <div class="controls"> @Html.TextBox("Email", Model.Email, new { @class = "input-xlarge" }) <p class="help-block"> Email</p> @Html.ValidationMessage("Email") </div> </div> <div class="control-group"> <label class="control-label" for="Password"> </label> <div class="controls"> @Html.Password("Password", Model.Password, new { @class = "input-xlarge" }) @Html.ValidationMessage("Password") </div> </div> <div class="form-actions"> <button type="submit" class="btn btn-primary"> </button> </div> </fieldset> }
Source: https://habr.com/ru/post/176043/
All Articles