ASP.NET Web api 身份认证原理解析

类图:

这里写图片描述

TestController.cs

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web;
using System.Web.Http;
using System.Web.Security;
using WebApiAuthentication.Core;

namespace WebApiAuthentication.Controllers
{
    [RoutePrefix("Test")]
    public class TestController : ApiController
    {
        [Route("SignIn")]
        [HttpGet]
        public IHttpActionResult SignIn()
        {
            MyFormsAuthenticationTicket ticket = new MyFormsAuthenticationTicket(2, new Random().Next().ToString(), DateTime.Now, DateTime.Now.AddDays(1), true, "admin,张三");
            string encryptStr = MyFormsAuthentication.EncryptDES(JsonConvert.SerializeObject(ticket), "11111111");
            HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptStr);
            //cookie.HttpOnly = true;
            cookie.Secure = FormsAuthentication.RequireSSL;
            HttpContext context = HttpContext.Current;
            if (context == null)
                throw new InvalidOperationException();
            //  写入Cookie
            context.Response.Cookies.Remove(cookie.Name);
            context.Response.Cookies.Add(cookie);
            return Ok("登陆成功");
        }
        [Route("SignOut")]
        [HttpGet]
        [Authorize]
        public IHttpActionResult SignOut()
        {
            HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, "");
            cookie.Expires = DateTime.Now.AddDays(-1);
            HttpContext.Current.Response.Cookies.Add(cookie);
            return Ok("退出成功");
        }

        /// <summary>
        /// 测试是否登陆后可以访问
        /// </summary>
        /// <returns></returns>
        [Route("TestSuccess")]
        [HttpGet]
        [Authorize]
        public IHttpActionResult TestSuccess()
        {
            return Ok("访问成功");
        }
        /// <summary>
        /// 测试指定角色
        /// </summary>
        /// <returns></returns>
        [Route("TestRoles")]
        [HttpGet]
        [Authorize(Roles="找刘")]
        public IHttpActionResult TestRoles()
        {
            return Ok("访问成功");
        }
        /// <summary>
        /// 测试指定角色
        /// </summary>
        /// <returns></returns>
        [Route("TestZhangsan")]
        [HttpGet]
        [Authorize(Roles = "张三")]
        public IHttpActionResult TestZhangsan()
        {
            return Ok("访问成功");
        }
    }
}

MyFormsAuthenticationTicket.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;

namespace WebApiAuthentication.Core
{
    public class MyFormsAuthenticationTicket
    {
        public MyFormsAuthenticationTicket(int version, string name, DateTime issueDate, DateTime expiration, bool isPersistent, string userData)
        {
            this.Version = version;
            this.Name = name;
            this.Expiration = expiration;
            this.IssueDate = issueDate;
            this.IsPersistent = isPersistent;
            this.UserData = userData;
            this.CookiePath = FormsAuthentication.FormsCookiePath;
            DtNow = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ssss");
        }

        public string CookiePath { get; set; }

        public DateTime Expiration { get; set; }

        public bool Expired { get; set; }

        public bool IsPersistent { get; set; }

        public DateTime IssueDate { get; set; }

        public string Name { get; set; }

        public string UserData { get; set; }

        public int Version { get; set; }

        public string DtNow { get; set; }
    }
}

MyFormsAuthentication.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace WebApiAuthentication.Core
{
    public static class MyFormsAuthentication
    {
        /// <summary>
        /// DES加密字符串
        /// </summary>
        /// <param name="encryptString">待加密的字符串</param>
        /// <param name="encryptKey">加密密钥,要求为8位</param>
        /// <returns>加密成功返回加密后的字符串,失败返回源串</returns>
        public static string EncryptDES(string encryptString, string key)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(key);
                byte[] rgbIV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Convert.ToBase64String(mStream.ToArray());
            }
            catch
            {
                return encryptString;
            }
        }

        /// <summary>
        /// DES解密字符串
        /// </summary>
        /// <param name="decryptString">待解密的字符串</param>
        /// <param name="key">解密密钥,要求8位</param>
        /// <returns></returns>
        public static string DecryptDES(string decryptString, string key)
        {
            try
            {
                //默认密钥向量
                byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
                byte[] rgbKey = Encoding.UTF8.GetBytes(key);
                byte[] rgbIV = Keys;
                byte[] inputByteArray = Convert.FromBase64String(decryptString);
                DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Encoding.UTF8.GetString(mStream.ToArray());
            }
            catch
            {
                return decryptString;
            }
        }
    }
}

DecryptHttpMoudle.cs

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;

namespace WebApiAuthentication.Core
{
    public class DecryptHttpMoudle : IHttpModule
    {
        public void Dispose()
        {

        }

        public void Init(HttpApplication context)
        {
            context.AuthenticateRequest += Context_AuthenticateRequest;
        }
        /// <summary>
        /// 替换HttpContext.Current.User实现
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Context_AuthenticateRequest(object sender, EventArgs e)
        {
            var app = sender as HttpApplication;
            if (app == null)
            {
                app.Context.User = null;
                return;
            }
            var cookie = HttpContext.Current.Request.Headers.GetValues("Cookie");
            if (cookie == null)
            {
                app.Context.User = new MyPrincipal("",null);
                return;
            }
            if (cookie.Count() < 1)
            {
                app.Context.User = new MyPrincipal("", null);
                return;
            }
            MyFormsAuthenticationTicket ticket;
            try
            {
                //获取cookie值的另一种方式,特殊符号会被省略
                //var sdd = Request.Headers.GetCookies(FormsAuthentication.FormsCookieName).FirstOrDefault();
                //var value=sdd[FormsAuthentication.FormsCookieName].Value;
                string decryptStr = MyFormsAuthentication.DecryptDES(cookie[0].Substring(cookie[0].IndexOf('=') + 1), "11111111");
                ticket = JsonConvert.DeserializeObject<MyFormsAuthenticationTicket>(decryptStr);
            }
            catch (Exception)
            {
                app.Context.User = new MyPrincipal("", null);
                return;
            }
            if (ticket == null)
            {
                app.Context.User = new MyPrincipal("", null);
                return;
            }
            app.Context.User = new MyPrincipal(ticket.Name,ticket.UserData);
        }
    }
}

MyPrincipal.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Web;

namespace WebApiAuthentication.Core
{
    public class MyPrincipal : IPrincipal
    {
        private string[] m_roles;
        public MyPrincipal(string name,string roles)
        {
            if (!string.IsNullOrEmpty(roles)) {
                string[] rolesArr = roles.Split(',');
                m_roles = new string[rolesArr.Count()];
                for (int i = 0; i < rolesArr.Count(); i++)
                {
                    m_roles[i] = rolesArr[i];
                }
            }
            _identity = new MyIdentity(name);
        }

        private IIdentity _identity;

        public IIdentity Identity
        {
            get
            {
                return _identity;
            }
        }
        public bool IsInRole(string role)
        {
            if ((role == null) || (this.m_roles == null))
            {
                return false;
            }
            for (int i = 0; i < this.m_roles.Length; i++)
            {
                if ((this.m_roles[i] != null) && (string.Compare(this.m_roles[i], role, StringComparison.OrdinalIgnoreCase) == 0))
                {
                    return true;
                }
            }
            return false;
        }

    }
}

MyIdentity.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Web;

namespace WebApiAuthentication.Core
{
    public class MyIdentity : IIdentity
    {
        public MyIdentity(string name) {
            this.m_name = name;
            this.m_type = "";
        }
        private string m_type;
        private string m_name;
        public  string Name
        {
            get
            {
                return this.m_name;
            }
        }
        public bool IsAuthenticated
        {
            get
            {
                return !this.m_name.Equals("");
            }
        }
        public string AuthenticationType
        {
            get
            {
                return this.m_type;
            }
        }

    }
}

Web.config

<system.webServer>
    ...
    <!--配置文件里注册的HttpModules-->
    <modules>
      <add name="DecryptHttpMoudle" type="WebApiAuthentication.Core.DecryptHttpMoudle"/>
    </modules>
  </system.webServer>

运行结果如图:

这里写图片描述


这里写图片描述


这里写图片描述


这里写图片描述


这里写图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值