那么接下去大家就来分析下客户地点认证

授权

有了登陆平常都离不开授权。微软的东西好就幸好,平常都以整个成套的。

[Authorize]
public ActionResult LoginOk()
{
    return View();
}

直白给Action增加三个Authorize个性就好了,那人就能活动物检疫查是或不是登入。若无登入活动跳转到登陆页面。登入页面包车型地铁安装依旧在web.config里面

<system.web>
  <authentication mode="Forms" >
    <forms loginUrl="/home/index"></forms>

这种回顾的授权验证显著是非常不足的。非常多时候有些页面唯有某个人才具访谈。譬如VIP。那么我们又要扩张了。

//继承 AuthorizeAttribute
public class MyAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.User.Identity.Name != "农码一生")
        {
            filterContext.HttpContext.Response.Write("您不是vip用户,不能访问机密数据");
            filterContext.HttpContext.Response.End();
            return;
        }
        base.OnAuthorization(filterContext);
    }
}

[MyAuthorize]
public ActionResult LoginVIP()
{
    return View();
}

毫无疑问,正是那样简单。说了这样多,来张效果图吧:
永利网上娱乐 1

 

永利网上娱乐,推荐阅读:

 

阐明:本文示例使用的VS2017和MVC5。
系统无论大小、牛逼或土憋,平时都离不开注册、登入。那么接下去我们就来分析下客户地点验证。

自定义的身价验证标记

上面使用的记名相当粗略,但实则处境再三很复杂。明显不荒谬作业要求存的顾客消息会要越来越多。那么我们是否能够扩张身份标记呢?答案是迟早的。
后台代码:

public void Login3(string userName)
{
    if (!string.IsNullOrWhiteSpace(userName))  //为了方便演示,就不做真的验证了     
    {
        UserInfo user = new UserInfo()
        {
            Name = userName,
            LoginTime = DateTime.Now
        };
        //1、序列化要保存的用户信息
        var data = JsonConvert.SerializeObject(user);

        //2、创建一个FormsAuthenticationTicket,它包含登录名以及额外的用户数据。
        FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2, userName, DateTime.Now, DateTime.Now.AddDays(1), true, data);

        //3、加密保存
        string cookieValue = FormsAuthentication.Encrypt(ticket);

        // 4. 根据加密结果创建登录Cookie
        HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue);
        cookie.HttpOnly = true;
        cookie.Secure = FormsAuthentication.RequireSSL;
        cookie.Domain = FormsAuthentication.CookieDomain;
        cookie.Path = FormsAuthentication.FormsCookiePath;

        // 5. 写登录Cookie
        Response.Cookies.Remove(cookie.Name);
        Response.Cookies.Add(cookie);
    }
    Response.Redirect(Request.UrlReferrer.LocalPath);//重定向到原来页面
}

然后在Global.asax的Application_AuthenticateRequest方法:

protected void Application_AuthenticateRequest()
{
    GetUserInfo();
}

//通过coolie解密 读取用户信息到 HttpContext.Current.User
public void GetUserInfo()
{
    // 1. 读登录Cookie
    HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName];

    try
    {
        UserInfo userData = null;
        // 2. 解密Cookie值,获取FormsAuthenticationTicket对象
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);

        if (ticket != null && string.IsNullOrEmpty(ticket.UserData) == false)
            // 3. 还原用户数据
            userData = JsonConvert.DeserializeObject<UserInfo>(ticket.UserData);

        if (ticket != null && userData != null)
            // 4. 构造我们的MyFormsPrincipal实例,重新给context.User赋值。
            HttpContext.Current.User = new MyFormsPrincipal<UserInfo>(ticket, userData);
    }
    catch { /* 有异常也不要抛出,防止攻击者试探。 */ }
}

前面三个代码:

@{
    MyFormsPrincipal<UserInfo> user = Context.User as MyFormsPrincipal<UserInfo>;
    if (user == null)
    {
        <form action="/home/login3">
            <input type="text" name="userName" />
            <input type="submit" value="登录" />
        </form>
    }
    else
    {

        <form action="/home/logout2">
            <div>当前用户已登录,登录名:@Context.User.Identity.Name</div>
            <div>当前用户已登录,登录时间:@user.UserData.LoginTime</div>
            <input type="submit" value="退出" />
        </form>
    }
}

实在任何经过和FormsAuthentication.SetAuthCookie(userName, true); //登录是同样的。只是大家通过扩张,存了作者们想要存款和储蓄的多少。
进度也比较容易:

  • 协会要存款和储蓄的多寡
  • 序列化
  • 把系列化消息放入FormsAuthenticationTicket对象
  • 通过FormsAuthentication.Encrypt加密对象
  • 发送cookie到浏览器

那边稍微复杂点的地方正是解密然后给User赋值HttpContext.Current.User = new MyFormsPrincipal<UserInfo>(ticket, userData);
MyFormsPrincipal供给贯彻接口MyFormsPrincipal

public class MyFormsPrincipal<TUserData> : IPrincipal where TUserData : class, new()
{
    private IIdentity _identity;
    private TUserData _userData;

    public MyFormsPrincipal(FormsAuthenticationTicket ticket, TUserData userData)
    {
        if (ticket == null)
            throw new ArgumentNullException("ticket");
        if (userData == null)
            throw new ArgumentNullException("userData");

        _identity = new FormsIdentity(ticket);
        _userData = userData;
    }

    public TUserData UserData
    {
        get { return _userData; }
    }

    public IIdentity Identity
    {
        get { return _identity; }
    }

    public bool IsInRole(string role)//这里暂时不实现
    {
        return false;
    }
}

倒也远非怎么非常,便是实例化的时候传出票据和自定义数据就好了。

【转】权限工学习 黄金年代、ASP.NET
Forms身份验证

Forms认证登陆、注销

第生气勃勃在web.config里打开Forms居民身份注脚:

<system.web>
  <authentication mode="Forms"></authentication>

后台代码:

public void Login2(string userName)
{
    if (!string.IsNullOrWhiteSpace(userName))  //为了方便演示,就不做真的验证了
        FormsAuthentication.SetAuthCookie(userName, true); //登录
    Response.Redirect(Request.UrlReferrer.LocalPath);//重定向到原来页面
}

public void Logout2()
{
    FormsAuthentication.SignOut();//登出
    Response.Redirect(Request.UrlReferrer.LocalPath);//重定向到原来页面
}

前台代码:

@if (!Request.IsAuthenticated)
{
    <form action="/home/login2">
        <input type="text" name="userName" />
        <input type="submit" value="登录" />
    </form>
}
else
{
    <form action="/home/logout2">
        <div>当前用户已登录,登录名:@Context.User.Identity.Name</div>
        <input type="submit" value="退出" />
    </form>
}

这么几句代码就兑现了我们的登陆和注销。和大家相濡以沫用session管理登陆不相同。Forms身份验证是直接把新闻存cookie到浏览器的。通过SetAuthCookie这些艺术名也能够看出来。可是Cookie新闻经过了加密。
此处有不可或缺表明session和cookie的涉嫌。当我们运用session来保持顾客情形的时候,其实也选取了cookie。
永利网上娱乐 2
不过Forms居民身份证明仅仅只是把音讯存了cookie,而从未在服务端维护贰个对应的session。
不相信你能够测量试验。能够用二种情势都登陆,然后去掉session就可以测出来了。(怎么清session?重启iis,大概涂改下后台代码在重新编写翻译访谈)
【表明】客商认证为何要存cookie?因为HTTP是三个无状态的合计。对于服务器来讲,每回必要没什么分化的。所以,只好通过每一趟须求带的cookie来甄别顾客了。(一时不思虑任何方法)

归纳完毕登入、注销

以往在学习.net的时候不亮堂哪些Forms居民身份注明,直接用session完成登入,效果也相当好嘛。何况顾客消息存在服务端,安全。
前端代码:

@if (string.IsNullOrWhiteSpace(ViewBag.UserName))
{
    <form action="/home/login1">
        <input type="text" name="userName" />
        <input type="submit" value="登录" />
    </form>
}
else
{
    <form action="/home/logout1">
        <div>当前用户已登录,登录名:@ViewBag.UserName</div>
        <input type="submit" value="退出" />
    </form>
}

后台代码:

public ActionResult Index()
{
    ViewBag.UserName = Session["userName"]?.ToString();           
    return View();
}       

public void Login1(string userName)
{
    if (!string.IsNullOrWhiteSpace(userName))  //为了方便演示,就不做真的验证了     
        Session["userName"] = userName;
    else
        Session["userName"] = null;
    Response.Redirect(Request.UrlReferrer.LocalPath);//重定向到原来页面
}

public void Logout1()
{
    Session["userName"] = null;
    Response.Redirect(Request.UrlReferrer.LocalPath);//重定向到原来页面
}

是否,老妪能解。想要自个儿扩张或是定制什么效果与利益都不行好用。可是大家需求拥戴session。例如系统重新发布,或然iis被机关心爱戴启。就能够出现session错过的意况。也等于顾客会莫明其妙提高必要重新登陆。体验非常不佳。(这里先不斟酌session服务和数据库的情形)。既然微软有豆蔻梢头套成熟的权能管理大家为啥不要啊?

相关文章