Filter implementation Token Authentication (login authentication + expired validation) --- simple implementation

Features: + login authentication verification expired cookie + + written off under clear not log off or shut down can still refresh the browser to directly access action
Overview: there is only token client cookie, back-end AES encryption decryption + + authentication, access every successful action will refresh token including the expiration time

1. Filter

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace TokenTest.MyActionFilter
{
    /// <summary>
    /// <param name="Die_Time">Die_Time//设置token过期时间小于7days</param>
    /// <param name="Jump_Page">Jump_Page//设置token验证失败后跳转页面如/Login/Index;可携带参数/Login/Index?******</param>
    /// </summary>
    public class Token_Filter:ActionFilterAttribute//继承ActionFilterAttribute类
    {
        public  int Die_Time { get; set;}//设置token过期时间<7days
        public  string Jump_Page { get; set; }//设置token验证失败后跳转页面如/Login/Index;可携带参数/Login/Index?******
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var token = HttpContext.Current.Request.Cookies["Token"];
            if (token==null)
            {
                HttpContext.Current.Response.Write("<script language='javascript'>alert('您未登陆,请先登陆!');location.href='" + Jump_Page + "' ;</script>");
            }
            else
            {
                string U_ID = AESDecrypt(token.Value.ToString(), "jjq").Split('_')[0];
                DateTime Token_Time = Convert.ToDateTime(AESDecrypt(token.Value.ToString(), "jjq").Split('_')[1]);
                //检验过期时间;token理论上验证有效期:Die_Time<7天/////每次加载过滤action都会重新设置时间(可改)
                if (Token_Time.AddDays(Die_Time) < DateTime.Now)
                {
                    HttpContext.Current.Response.Write("<script language='javascript'>alert('登陆过期,请重新登录!');location.href='" + Jump_Page + "' ;</script>");
                }
                else
                {
                    //完全验证通过后重新改写token并覆写在cookie里
                    Set_Token(U_ID);
                }
            }
            
        }
        public static void Set_Token(string user_name)
        {
            var Token = AESEncrypt(user_name + "_" + DateTime.Now.ToString() + "_" + Guid.NewGuid(), "jjq");//Token加密;;jjq加密密匙
            HttpContext.Current.Response.Cookies["Token"].Value = Token;
            HttpContext.Current.Response.Cookies["Token"].Expires = DateTime.Now.AddDays(7);//设置Token客户端保留时间7天
        }

        #region
        /// <summary>
        /// 加密解密功能代码片段
        /// </summary>
        //AES密钥向量
        private static readonly byte[] _aeskeys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
        /// <summary>
        /// AES加密
        /// </summary>
        /// <param name="encryptStr">加密字符串</param>
        /// <param name="encryptKey">密钥</param>
        /// <returns></returns>
        public static string AESEncrypt(string encryptStr, string encryptKey)
        {
            if (string.IsNullOrWhiteSpace(encryptStr))
                return string.Empty;

            encryptKey = SubString(encryptKey, 0, 32);
            encryptKey = encryptKey.PadRight(32, ' ');

            //分组加密算法
            SymmetricAlgorithm des = Rijndael.Create();
            byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptStr);//得到需要加密的字节数组 
            //设置密钥及密钥向量
            des.Key = Encoding.UTF8.GetBytes(encryptKey);
            des.IV = _aeskeys;
            byte[] cipherBytes = null;
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cipherBytes = ms.ToArray();//得到加密后的字节数组
                    cs.Close();
                    ms.Close();
                }
            }
            return Convert.ToBase64String(cipherBytes);
        }
        /// <summary>
        /// AES解密
        /// </summary>
        /// <param name="decryptStr">解密字符串</param>
        /// <param name="decryptKey">密钥</param>
        /// <returns></returns>
        public static string AESDecrypt(string decryptStr, string decryptKey)
        {
            if (string.IsNullOrWhiteSpace(decryptStr))
                return string.Empty;

            decryptKey = SubString(decryptKey, 0, 32);
            decryptKey = decryptKey.PadRight(32, ' ');

            byte[] cipherText = Convert.FromBase64String(decryptStr);

            SymmetricAlgorithm des = Rijndael.Create();
            des.Key = Encoding.UTF8.GetBytes(decryptKey);
            des.IV = _aeskeys;
            byte[] decryptBytes = new byte[cipherText.Length];
            using (MemoryStream ms = new MemoryStream(cipherText))
            {
                using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read))
                {
                    cs.Read(decryptBytes, 0, decryptBytes.Length);
                    cs.Close();
                    ms.Close();
                }
            }
            return Encoding.UTF8.GetString(decryptBytes).Replace("\0", "");//将字符串后尾的'\0'去掉
        }

        public static string SubString(string sourceStr, int startIndex, int length)
        {
            if (!string.IsNullOrEmpty(sourceStr))
            {
                if (sourceStr.Length >= (startIndex + length))
                    return sourceStr.Substring(startIndex, length);
                else
                    return sourceStr.Substring(startIndex);
            }

            return "";
        }
        #endregion
    }
}

2. Use 1

1. Controller referenced to be filtered (note to the parameter)

using System.Web.Mvc;
using TokenTest.MyActionFilter;

namespace TokenTest.Controllers
{

    public class adminController : Controller
    {
        // GET: admin
        [Token_Filter(Die_Time=3,Jump_Page = "/Login/Index")]
        public ActionResult Index()
        {
            return View();
        }
    }
}

2.LoginController cited Token_Filter.Set_Token () method; activation settings token + logout button (clear cookie)

using System;
using System.Web.Mvc;
using TokenTest.MyActionFilter;

namespace TokenTest.Controllers
{/// <summary>
 /// ////////////////////////////////////////////////
 /// </summary>

    public class LoginController : Controller
    {
        // GET: Login
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult Logout()
        {
            //注销按钮---清除cookie
            Response.Cookies["Token"].Expires = DateTime.Now.AddDays(-1);
            return View("Index");
        }
        public ActionResult Login()
        {
            var get_name = Request["name"];
            var get_pwd = Request["pwd"];
            JJQPractice visitor = JJQPractice.SingleOrDefault(new { name = get_name });//得到对应输入的账号的集
            if (visitor != null)//验证输入的账号是否存在
            {
                if (visitor.pwd == get_pwd)//验证密码是否正确
                {
                    Token_Filter.Set_Token(get_name);
                    return RedirectToAction("Index", "admin"); //密码正确后跳转到查询视图
                }
                else
                {
                    Response.Write("登录失败!密码错误.");
                    return View("Index");
                }
            }
            else
            {
                Response.Write("登录失败,用户名不存在.");
                return View("Index");
            }
        }
    }
}
<h2>Logn-Index</h2>
<br><br>
<form action="/Login/Login" method="post">
    姓名:<input type="text" name="name"/><br><br>
    密码:<input type="text" name="pwd"/><br><br>
    <input type="submit" value="提交"/><br><br>
</form>
<h2>Index</h2>
<form action="/admin/Index" method="post">
    <input  name="h" value="6666"/>
    <input type="submit" value="按钮"/><br /><br />
</form>
<form action="/Login/Logout" method="post">
    <input type="submit" value="注销_清除cookie" />
</form>

Guess you like

Origin www.cnblogs.com/jsll/p/11746412.html