玖富娱乐是一家为代理招商,直属主管信息发布为主的资讯网站,同时也兼顾玖富娱乐代理注册登录地址。

在一样平常的MVC项目中 我们广泛的运用Cookie来作为认证受权体式格局,运用简朴。登录胜利后将用户信息写入Cookie;但当我们做WebApi的时刻明显Cookie这类体式格局就有点不适用了。

在dotnet core 中 WebApi中现在对照盛行的认证受权体式格局是Jwt  (Json Web Token) 手艺。Jwt 是一种无状况的分布式身份考证体式格局,Jwt 是将用户登录信息加密后存放到返回的Token中 ,相当于用户信息是存储在客户端。Jwt的加密体式格局有两种 :对称加密与非对称加密,非对称加密即 RSA 加密的体式格局。

本身手写认证受权代码和Jwt的思绪是一样的;不同之处在于:

1、加密体式格局仅仅是接纳的对称加密体式格局 简朴高效。哈哈!(毛病就是没有非对称加密更平安);

2、用户登录信息重要保存在Redis中,即服务端。

本身写的优点:

1、扩大性强,可根据本身的须要举行种种扩大,好比在考证受权时可很轻易的增加多装备登录挤下线功用等。

2、可随时调解用户的Token失效时候。

认证及受权流程

1、先要求登录接口,登录胜利,为用户发生一个Token,

登录猎取Token 图片中ticket字段。

 

2、 客户端拿到Token在其他要求中将Token信息增加到要求头中通报到服务端。

开辟思绪

1、增加一个过滤器。在Startup 中ConfigureServices要领里增加一个Filters 即我们本身受权代码类。

public void ConfigureServices(IServiceCollection services)
 {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddMvc(mvc =>
            {
                //增加本身的受权考证
                mvc.Filters.Add(typeof(AuthorizeFilter));
            });
 }

  

-玖富娱乐是一家为代理招商,直属主管信息发布为主的资讯网站,同时也兼顾玖富娱乐代理注册登录地址。-

 增加过滤器以后我们的每次要求都邑优先实行过滤器的代码。在这里我们就能够推断用户是不是已登录,从而举行阻拦没有受权的的要求。

    /// <summary>
    /// 平安认证过滤器
    /// </summary>
    public class AuthorizeFilter : IActionFilter, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            //许可匿名接见
            if (context.HttpContext.User.Identity.IsAuthenticated ||
                context.Filters.Any(item => item is IAllowAnonymousFilter))
                return;
            var httpContext = context.HttpContext;
            var claimsIdentity = httpContext.User.Identity as ClaimsIdentity;
            var request = context.HttpContext.Request;
            var authorization = request.Headers["Authorization"].ToString();
            if (authorization != null && authorization.Contains("BasicAuth"))
            {
                //猎取要求头中通报的ticket
                var current_ticket = authorization.Split(" ")[1];
                //校验ticket并猎取用户信息
                var userInfo = TicketEncryption.VerifyTicket(current_ticket, out string dec_client);
                if (userInfo != null)
                {
                    //同一个终端屡次登录挤下线功用 返回403
                    if (userInfo.ticket != current_ticket && userInfo.client.ToString() == dec_client)
                    {
                        #region 多装备挤下线代码
                        var response = new HttpResponseMessage();
                        context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                        context.Result = new JsonResult("Forbidden:The current authorization has expired");
                        #endregion

                        return;
                    }
                    else
                    {
                        return;
                    }
                }

            }
            // 401 未受权
            context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            context.Result = new JsonResult("Forbidden:Tiket Invalid");

        }
    }

2、登录并猎取Token

由于增加了IAuthorizationFilter范例的过滤器,以是每一个要求都邑被阻拦。以是登录接口我们须要许可匿名接见。

3、加解密Token

加密:登录胜利后就要发生个Token了,发生也简朴。将用户的独一信息好比uid或许guid举行对称式加密。固然若是须要对登录装备做辨别或许多装备登录挤下线功用时最好也将登录装备一同加密进去。

我们都晓得 在加密中一样平常状况下只需加密的数据及加密key稳定;那末加密后的内容也会一向连结稳定。若是我们每次登录发生的Token一向没有任何转变只需这个Token被泄露了那将很风险的。居然我们愿望每次登录发生的Token都有转变。那就要转变加密数据或许加密key了。加密数据是用户独一信息这个明显不可能发生转变。以是我们能转变的处所只能是加密key了;我们接纳流动key 随机key的体式格局。

由于加密key在我们解密时也是须要一一对应的。以是我们得想设施将我们的随机key通知我们解密的代码中。设施就是 我们将加密后的内容(一样平常状况举行base64编码)再加上随机key。(随机key一定是流动长度 否则背面没法剖析拆分)

好比加密内容是guid=73e01eab-210d-4d19-a72a-d0d64e053ec0 client=ios  流动key=123654 随机key=FEZaaWbyimaWiJHah 

即加密历程:

加密(73e01eab-210d-4d19-a72a-d0d64e053ec0&ios,123654FEZaaWbyimaWiJHah)=M0EzM0ZGRjk2QzgwRDY2RDJDMTdFOEJGRUE0NDI3NEE1RDlFNkU4NDQ0MERFNEIyMkQ5QjM4MjAxODcwj加随机keyFEZaaWbyimaWiJHah

以是我们返回给用户的Token现实上是包含了随机key的。固然这个随机key只要我们本身晓得。由于随机key的长度和地位只要我们本身晓得。这类体式格局纵然我们流动key被泄露了 只需他人不晓得我们随机key处置惩罚要领也杯水车薪。

解密:晓得加密历程后就好解密了。拿到用户提交的Token后首先依照随机key的流动地位举行截取。将加密内容和随机key拆开。然后将流动key和随机key组合一同解密加密的内容,获得用户guid和登录的客户端范例。

完全加解密代码

代码中的ticket代表本文中的Token。代码中运用的是DES加解密

 public class TicketEncryption
    {
        //加密key 现实中请用设置装备摆设文件设置装备摆设
        private static readonly string key = "yvDlky7GXGtlPCGr";
        /// <summary>
        /// 猎取一个新的ticket
        /// </summary>
        /// <param name="guid">用户的guid</param>
        /// <param name="client">客户端</param>
        /// <returns></returns>
        public static string GenerateTicket(string guid, string client)
        {
            //随机key
            string randomKey = Randoms.GetRandomString(15);
            var keys = key   randomKey;
            var desStr = Encryption.DesEncrypt(guid   "&"   client, keys);
            var base64Str = Encryption.Base64Encrypt(desStr)   randomKey;
            return base64Str;
        }

        /// <summary>
        /// 校验ticket
        /// </summary>
        /// <param name="encryptStr"></param>
        /// <returns></returns>
        public static UserInfo VerifyTicket(string encryptStr,out string client)
        {
            try
            {
                RedisHelper redisHelper = new RedisHelper("127.0.0.1:6379");
                //加密原型:guid&client; 如:08e80f78-95ad-427c-b506-a5f1504e29ac&ios
                string randomKey = encryptStr.Substring(encryptStr.Length - 15);
                var base64 = encryptStr.Substring(0, encryptStr.Length - 15);
                var deBase64 = Encryption.Base64Decrypt(base64);
                var keys = key   randomKey;
                string ticketInfo = Encryption.DesDecrypt(deBase64, keys);
                var guid = ticketInfo.Split("&")[0];
                client = ticketInfo.Split("&")[1];
                string redisKey = "ticket_"   guid;
                var obj = redisHelper.Get<UserInfo>(redisKey);
                return obj;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

 

完全demo代码请看github

https://github.com/cfan1236/NetCoreAuthorize

 

-玖富娱乐是一家为代理招商,直属主管信息发布为主的资讯网站,同时也兼顾玖富娱乐代理注册登录地址。