• 自定义分布式RESTful API鉴权机制


    微软利用OAuth2为RESTful API提供了完整的鉴权机制,但是可能微软保姆做的太完整了,在这个机制中指定了数据持久化的方法是用EF,而且对于用户、权限等已经进行了封装,对于系统中已经有了自己的用户表,和不是采用EF做持久化的系统来说限制太大,不自由,而且现实中很多情况下,授权服务器和资源服务器并不是同一个服务器,甚至数据库用的都不是同一个数据库,这种情况下直接利用微软的授权机制会有一定的麻烦,基于这种情况不如自己实现一套完整的分布式的鉴权机制。

    自定义的鉴权机制中利用redis来缓存授权令牌信息,结构大体如下:

    从图上可以看出,用户登录成功后的用户信息缓存在redis,用户带着令牌访问资源服务器时再对令牌进行解密,获取到key,然后就可以获取到用户信息,可以根据判断redis中是否有这个key来校验用户是否经过授权,大体思路就是这些,下边就是具体的代码实现

    redis的操作帮助类,帮助类中实现了redis的读写分离

      public class RedisBase
        {
    #if DEBUG
            private static string[] ReadWriteHosts = { "127.0.0.1:6379" };
            private static string[] ReadOnlyHosts = { "127.0.0.1:6379" };
    #endif
    #if !DEBUG
             private static string[] ReadWriteHosts = System.Configuration.ConfigurationSettings.AppSettings["RedisWriteHosts"].Split(new char[] { ';' });
             private static string[] ReadOnlyHosts = System.Configuration.ConfigurationSettings.AppSettings["RedisReadOnlyHosts"].Split(new char[] { ';' });
    #endif
    
    
            #region -- 连接信息 --
            public static PooledRedisClientManager prcm = CreateManager(ReadWriteHosts, ReadOnlyHosts);
    
            private static PooledRedisClientManager CreateManager(string[] readWriteHosts, string[] readOnlyHosts)
            {
                // 支持读写分离,均衡负载  
                return new PooledRedisClientManager(readWriteHosts, readOnlyHosts, new RedisClientManagerConfig
                {
                    MaxWritePoolSize = 5, // “写”链接池链接数  
                    MaxReadPoolSize = 5, // “读”链接池链接数  
                    AutoStart = true,
                });
            }
    #endregion
    #region KEY
       
    #endregion
    
    #region -- Item String --
            /// <summary> 
            /// 设置单体 
            /// </summary> 
            /// <typeparam name="T"></typeparam> 
            /// <param name="key"></param> 
            /// <param name="t"></param> 
            /// <param name="timeSpan"></param> 
            /// <returns></returns> 
            public static bool Item_Set<T>(string key, T t)
            {
                try
                {
                    using (IRedisClient redis = prcm.GetClient())
                    {
                        return redis.Set<T>(key, t, new TimeSpan(1, 0, 0));
                    }
                }
                catch (Exception ex)
                {
                    // LogInfo 
                }
                return false;
            }
            public static int String_Append(string key, string value)
            {
                try
                {
                    using (IRedisClient redis = prcm.GetClient())
                    {
                        return redis.AppendToValue(key, value);
                    }
                }
                catch (Exception ex) { }
                return 0;
            }
            /// <summary> 
            /// 获取单体 
            /// </summary> 
            /// <typeparam name="T"></typeparam> 
            /// <param name="key"></param> 
            /// <returns></returns> 
            public static T Item_Get<T>(string key) where T : class
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    return redis.Get<T>(key);
                }
            }
    
            /// <summary> 
            /// 移除单体 
            /// </summary> 
            /// <param name="key"></param> 
            public static bool Item_Remove(string key)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    return redis.Remove(key);
                }
            }
            /// <summary>
            /// 根据指定的Key,将值加1(仅整型有效)
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public static long IncrementValue(string key)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    return redis.IncrementValue(key);
                }
            }
            /// <summary>
            /// 根据指定的Key,将值加上指定值(仅整型有效)
            /// </summary>
            /// <param name="key"></param>
            /// <param name="count"></param>
            /// <returns></returns>
            public static long IncrementValueBy(string key,int count)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    return redis.IncrementValueBy(key,count);
                }
            }
            /// <summary>
            /// 设置过期时间
            /// </summary>
            /// <param name="key"></param>
            /// <param name="time"></param>
            /// <returns></returns>
            public static bool ExpireEntryIn(string key, TimeSpan time)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    return redis.ExpireEntryIn(key, time);
                }
            }
            /// <summary>
            /// 设置过期时间
            /// </summary>
            /// <param name="key"></param>
            /// <param name="expireAt"></param>
            /// <returns></returns>
            public static bool ExpireEntryAt(string key, DateTime expireAt)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    return redis.ExpireEntryAt(key, expireAt);
                }
            }
            /// <summary>
            /// 判断key是否已存在
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public static bool ContainsKey(string key)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    return redis.ContainsKey(key);
                }
            }
    #endregion
    
            #region -- List --
    
            public static void List_Add<T>(string key, T t)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    var redisTypedClient = redis.As<T>();
                    redisTypedClient.AddItemToList(redisTypedClient.Lists[key], t);
                }
            }
    
    
    
            public static bool List_Remove<T>(string key, T t)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    var redisTypedClient = redis.As<T>();
                    return redisTypedClient.RemoveItemFromList(redisTypedClient.Lists[key], t) > 0;
                }
            }
            public static void List_RemoveAll<T>(string key)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    var redisTypedClient = redis.As<T>();
                    redisTypedClient.Lists[key].RemoveAll();
                }
            }
    
            public static long List_Count(string key)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    return redis.GetListCount(key);
                }
            }
    
            public static List<T> List_GetRange<T>(string key, int start, int count)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    var c = redis.As<T>();
                    return c.Lists[key].GetRange(start, start + count - 1);
                }
            }
    
    
            public static List<T> List_GetList<T>(string key)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    var c = redis.As<T>();
                    return c.Lists[key].GetRange(0, c.Lists[key].Count);
                }
            }
    
            public static List<T> List_GetList<T>(string key, int pageIndex, int pageSize)
            {
                int start = pageSize * (pageIndex - 1);
                return List_GetRange<T>(key, start, pageSize);
            }
    
            /// <summary> 
            /// 设置缓存过期 
            /// </summary> 
            /// <param name="key"></param> 
            /// <param name="datetime"></param> 
            public static void List_SetExpire(string key, DateTime datetime)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    redis.ExpireEntryAt(key, datetime);
                }
            }
    #endregion
    
    #region -- Set --
            public static void Set_Add<T>(string key, T t)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    var redisTypedClient = redis.As<T>();
                    redisTypedClient.Sets[key].Add(t);
                }
            }
            public static bool Set_Contains<T>(string key, T t)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    var redisTypedClient = redis.As<T>();
                    return redisTypedClient.Sets[key].Contains(t);
                }
            }
            public static bool Set_Remove<T>(string key, T t)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    var redisTypedClient = redis.As<T>();
                    return redisTypedClient.Sets[key].Remove(t);
                }
            }
    #endregion
    
    #region -- Hash --
            /// <summary> 
            /// 判断某个数据是否已经被缓存 
            /// </summary> 
            /// <typeparam name="T"></typeparam> 
            /// <param name="key"></param> 
            /// <param name="dataKey"></param> 
            /// <returns></returns> 
            public static bool Hash_Exist<T>(string key, string dataKey)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    return redis.HashContainsEntry(key, dataKey);
                }
            }
    
            /// <summary> 
            /// 存储数据到hash表 
            /// </summary> 
            /// <typeparam name="T"></typeparam> 
            /// <param name="key"></param> 
            /// <param name="dataKey"></param> 
            /// <returns></returns> 
            public static bool Hash_Set<T>(string key, string dataKey, T t)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    string value = ServiceStack.Text.JsonSerializer.SerializeToString<T>(t);
                    return redis.SetEntryInHash(key, dataKey, value);
                }
            }
            /// <summary> 
            /// 移除hash中的某值 
            /// </summary> 
            /// <typeparam name="T"></typeparam> 
            /// <param name="key"></param> 
            /// <param name="dataKey"></param> 
            /// <returns></returns> 
            public static bool Hash_Remove(string key, string dataKey)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    return redis.RemoveEntryFromHash(key, dataKey);
                }
            }
            /// <summary> 
            /// 移除整个hash 
            /// </summary> 
            /// <typeparam name="T"></typeparam> 
            /// <param name="key"></param> 
            /// <param name="dataKey"></param> 
            /// <returns></returns> 
            public static bool Hash_Remove(string key)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    return redis.Remove(key);
                }
            }
            /// <summary> 
            /// 从hash表获取数据 
            /// </summary> 
            /// <typeparam name="T"></typeparam> 
            /// <param name="key"></param> 
            /// <param name="dataKey"></param> 
            /// <returns></returns> 
            public static T Hash_Get<T>(string key, string dataKey)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    string value = redis.GetValueFromHash(key, dataKey);
                    return ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(value);
                }
            }
            /// <summary> 
            /// 获取整个hash的数据 
            /// </summary> 
            /// <typeparam name="T"></typeparam> 
            /// <param name="key"></param> 
            /// <returns></returns> 
            public static List<T> Hash_GetAll<T>(string key)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    var list = redis.GetHashValues(key);
                    if (list != null && list.Count > 0)
                    {
                        List<T> result = new List<T>();
                        foreach (var item in list)
                        {
                            var value = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(item);
                            result.Add(value);
                        }
                        return result;
                    }
                    return null;
                }
            }
            /// <summary> 
            /// 设置缓存过期 
            /// </summary> 
            /// <param name="key"></param> 
            /// <param name="datetime"></param> 
            public static void Hash_SetExpire(string key, DateTime datetime)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    redis.ExpireEntryAt(key, datetime);
                }
            }
    #endregion
    
    #region -- SortedSet --
            /// <summary> 
            ///  添加数据到 SortedSet 
            /// </summary> 
            /// <typeparam name="T"></typeparam> 
            /// <param name="key"></param> 
            /// <param name="t"></param> 
            /// <param name="score"></param> 
            public static bool SortedSet_Add<T>(string key, T t, double score)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    string value = ServiceStack.Text.JsonSerializer.SerializeToString<T>(t);
                    return redis.AddItemToSortedSet(key, value, score);
                }
            }
            /// <summary>
            /// 为有序集 key 的成员 member 的 score 值加上增量 increment 
            /// 可以通过传递一个负数值 increment ,让 score 减去相应的值
            /// 当 key 不存在,或 member 不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="t"></param>
            /// <param name="incrementBy"></param>
            /// <returns></returns>
            public static double SortedSet_Zincrby<T>(string key,T t,double incrementBy)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    string value = ServiceStack.Text.JsonSerializer.SerializeToString<T>(t);
                    return redis.IncrementItemInSortedSet(key, value, incrementBy);
                }
            }
            /// <summary>
            /// 返回有序集 key 中,成员 member 的 score 值。
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="t">member</param>
            /// <returns></returns>
            public static double SortedSet_ZSCORE<T>(string key,T t)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    string value = ServiceStack.Text.JsonSerializer.SerializeToString<T>(t);
                    return redis.GetItemScoreInSortedSet(key, value);
                }
            }
            /// <summary> 
            /// 移除数据从SortedSet 
            /// </summary> 
            /// <typeparam name="T"></typeparam> 
            /// <param name="key"></param> 
            /// <param name="t"></param> 
            /// <returns></returns> 
            public static bool SortedSet_Remove<T>(string key, T t)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    string value = ServiceStack.Text.JsonSerializer.SerializeToString<T>(t);
                    return redis.RemoveItemFromSortedSet(key, value);
                }
            }
            /// <summary> 
            /// 修剪SortedSet 
            /// </summary> 
            /// <param name="key"></param> 
            /// <param name="size">保留的条数</param> 
            /// <returns></returns> 
            public static long SortedSet_Trim(string key, int size)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    return redis.RemoveRangeFromSortedSet(key, size, 9999999);
                }
            }
            /// <summary> 
            /// 获取SortedSet的长度 
            /// </summary> 
            /// <param name="key"></param> 
            /// <returns></returns> 
            public static long SortedSet_Count(string key)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    return redis.GetSortedSetCount(key);
                }
            }
    
            /// <summary> 
            /// 按照由小到大排序获取SortedSet的分页数据 
            /// </summary> 
            /// <typeparam name="T"></typeparam> 
            /// <param name="key"></param> 
            /// <param name="pageIndex"></param> 
            /// <param name="pageSize"></param> 
            /// <returns></returns> 
            public static List<T> SortedSet_GetList<T>(string key, int pageIndex, int pageSize)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    var list = redis.GetRangeFromSortedSet(key, (pageIndex - 1) * pageSize, pageIndex * pageSize - 1);
                    if (list != null && list.Count > 0)
                    {
                        List<T> result = new List<T>();
                        foreach (var item in list)
                        {
                            var data = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(item);
                            result.Add(data);
                        }
                        return result;
                    }
                }
                return null;
            }
            /// <summary>
            /// 按照由大到小顺序获取SortedSet的分页数据
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="pageIndex"></param>
            /// <param name="pageSize"></param>
            /// <returns></returns>
            public static List<T> SortedSet_GetListDesc<T>(string key, int pageIndex, int pageSize)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    var list = redis.GetRangeFromSortedSetDesc(key, (pageIndex - 1) * pageSize, pageIndex * pageSize - 1);
                    if (list != null && list.Count > 0)
                    {
                        List<T> result = new List<T>();
                        foreach (var item in list)
                        {
                            var data = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(item);
                            result.Add(data);
                        }
                        return result;
                    }
                }
                return null;
            }
            /// <summary>
            /// 按照由大到小的顺序获取SortedSet包含分数的分页数据
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="pageIndex"></param>
            /// <param name="pageSize"></param>
            /// <returns></returns>
            public static IDictionary<T,double> SortedSet_GetListWidthScoreDesc<T>(string key, int pageIndex, int pageSize)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    var list = redis.GetRangeWithScoresFromSortedSetDesc(key, (pageIndex - 1) * pageSize, pageIndex * pageSize - 1);
                    if (list != null && list.Count > 0)
                    {
                        IDictionary<T,double> result = new Dictionary<T,double>();
                        foreach (var item in list)
                        {
                            var data = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(item.Key);
                            result[data]=item.Value;
                        }
                        return result;
                    }
                }
                return null;
            }
    
            /// <summary> 
            /// 获取SortedSet的全部数据 
            /// </summary> 
            /// <typeparam name="T"></typeparam> 
            /// <param name="key"></param> 
            /// <param name="pageIndex"></param> 
            /// <param name="pageSize"></param> 
            /// <returns></returns> 
            public static List<T> SortedSet_GetListALL<T>(string key)
            {
                using (IRedisClient redis = prcm.GetReadOnlyClient())
                {
                    var list = redis.GetRangeFromSortedSet(key, 0, 9999999);
                    if (list != null && list.Count > 0)
                    {
                        List<T> result = new List<T>();
                        foreach (var item in list)
                        {
                            var data = ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(item);
                            result.Add(data);
                        }
                        return result;
                    }
                }
                return null;
            }
    
            /// <summary> 
            /// 设置缓存过期 
            /// </summary> 
            /// <param name="key"></param> 
            /// <param name="datetime"></param> 
            public static void SortedSet_SetExpire(string key, DateTime datetime)
            {
                using (IRedisClient redis = prcm.GetClient())
                {
                    redis.ExpireEntryAt(key, datetime);
                }
            }
    #endregion
        }

    用户类UserInfo

    public class UserInfo
    {
    }

    用户管理类,在asp.net web api中添加一个用户管理类,用来管理用户信息

    public class ApiUserManager
        {
            private HttpActionContext actionContext;
            public ApiUserManager(HttpActionContext actionContext)
            {
                this.actionContext = actionContext;
            }
            
    
            private UserInfo _User;
            /// <summary>
            /// 当前用户
            /// </summary>
            public UserInfo User
            {
                get
                {
                    if (_User==null)
                    {
                        string key = GetKey();
                        if (!string.IsNullOrEmpty(key) && RedisBase.ContainsKey(key))
                        {
                            _User = RedisBase.Item_Get<UserInfo>(key);
                        }
                    }
                    return _User;
                }
            }
    
            string GetKey()
            {
                if (actionContext.Request.Headers.Contains("Authorization"))
                {
                    string base64Code = actionContext.Request.Headers.GetValues("Authorization").FirstOrDefault();
                    //code结构为:userid-UserAgent.MD5()-随机数-时间戳
                    string code = EncryptUtil.UnBase64(base64Code);
                    string[] para = code.Split(new[] { "-" }, StringSplitOptions.RemoveEmptyEntries);
                    string key = (para[0] + para[1] + para[3]).MD5();
                    return key;
                }
                return string.Empty;
            }
            /// <summary>
            /// 用户是否已经登录
            /// </summary>
            /// <returns></returns>
            public bool ExistsLogin()
            {
                string base64Code = string.Empty;
                if (actionContext.Request.Headers.Contains("Authorization"))
                {
                    base64Code = actionContext.Request.Headers.GetValues("Authorization").FirstOrDefault();
                }
                if (base64Code.IsNull())
                {
                    return false;
                }
                //code结构为:userid-UserAgent.MD5()-随机数-时间戳
                string code = EncryptUtil.UnBase64(base64Code);
                string[] para = code.Split(new[] { "-" }, StringSplitOptions.RemoveEmptyEntries);
                if (para.Length != 4)
                {
                    return false;
                }
                string key = (para[0] + para[1] + para[3]).MD5();
                if (!RedisBase.ContainsKey(key))
                {
                    return false;
                }
                return true;
            }
            /// <summary>
            /// 用户登录返回令牌
            /// </summary>
            /// <param name="user"></param>
            /// <returns></returns>
            public string GetUserToken(UserInfo user)
            {
                string uagin = actionContext.Request.Headers.UserAgent.TryToString().MD5();
                string rm = Utils.GenPsw(11,11);
                long time = Utils.GetUnixTime();
                string code = string.Format("{0}-{1}-{2}-{3}", user.ID, uagin, rm, time);
                string token = EncryptUtil.Base64(code);
                string key = (user.ID + uagin + time).MD5();
                RedisBase.Item_Set(key,user);
                RedisBase.ExpireEntryAt(key,DateTime.Now.AddDays(2));
                return token;
            }
            /// <summary>
            /// 刷新当前用户信息【修改用户信息后刷新用户信息到缓存中】
            /// </summary>
            public void RefreshUser()
            {
                string key = GetKey();
                if (RedisBase.ContainsKey(key))
                {
                    RedisBase.Item_Set(key,User);
                }
            }
        }

    获取授权接口【用户登录接口】,在授权接口中校验用户名密码,成功后将用户信息存入redis,产生令牌,并返回

    public class AccountController : ApiController
    {
         UserInfoBll ubll = new UserInfoBll();
            /// <summary>
            /// 登录、根据用户名密码获取令牌
            /// </summary>
            /// <param name="username"></param>
            /// <param name="password"></param>
            /// <returns></returns>
            [HttpGet]
            [Route("token")]
            public JsonResult<string> Token(string username, string password)
            {
                JsonResult<string> result = new JsonResult<string>();
                result.code = 0;
                result.msg = "OK";
                UserInfo user = ubll.UserLogin(username, password);
                if (user == null)
                {
                    result.Result = "用户名或者密码错误";
                }
                else
                {
                    ApiUserManager userManager = new ApiUserManager(ActionContext);
                    result.Result = userManager.GetUserToken(user);
                    result.code = 1;
                    result.msg = "OK";
                }
                return result;
            }
    }

    自定义webAPI的过滤器,在过滤器中校验用户是否已经登录,过滤器中还可以设置只能指定的UserAgent可以访问接口,这样就可以让不同的客户端在请求的时候自定义不同的UserAgent,并且可以限制浏览器访问,做到一定的安全性,针对客户端的限制除了利用UserAgent之外还可以在http请求头自定义一个ClientID,为每个客户端配备一个ID,在过滤器中校验ClientID是否合法即可

     public class ApiActionFilterAttribute: ActionFilterAttribute
        {
            /// <summary>
            /// 签名参数
            /// </summary>
            public string[] Signpara { get; set; }
    
            public string[] Cachepara { get; set; }
    
            private bool _IsCache = false;
            public bool IsCache
            {
                get
                {
                    return _IsCache;
                }
                set { _IsCache = value; }
            }
    
            private bool _IsSigna = false;
            public bool IsSigna
            {
                get { return _IsSigna; }
                set { _IsSigna = value; }
            }
    
            private bool _IsUrlDecode = false;
            /// <summary>
            /// 是否解码
            /// </summary>
            public bool IsUrlDecode
            {
                get { return _IsUrlDecode; }
                set { _IsUrlDecode = value; }
            }
    
            private ClientEnum _CheckClient = ClientEnum.NoCheck;
            public ClientEnum CheckClient
            {
                get { return _CheckClient; }
                set { _CheckClient = value; }
            }
            private bool _IsLogin;
            /// <summary>
            /// 是否登录
            /// </summary>
            public bool IsLogin
            {
                get
                {
                    return _IsLogin;
                }
                set
                {
                    _IsLogin = value;
                }
            }
            /// <summary>
            /// 缓存超时时间
            /// </summary>
            public int TimeOut { get; set; }
    
            public override void OnActionExecuting(HttpActionContext actionContext)
            {
                JsonResult<string> result = new JsonResult<string>();
                if (CheckClient == ClientEnum.WindowsClient && !actionContext.Request.Headers.UserAgent.TryToString().Equals(SystemSet.WindowsClientUserAgent))
                {
                    result.code = -21;
                    result.msg = "illegal client";
                    //filterContext.HttpContext.Response.Status = HttpStatusCode.OK;
                    actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, result);
                    return;
                }
                if (CheckClient == ClientEnum.WebClient && !actionContext.Request.Headers.UserAgent.TryToString().Equals(SystemSet.WebClientUserAgent))
                {
                    result.code = -21;
                    result.msg = "illegal client";
                    //filterContext.HttpContext.Response.Status = HttpStatusCode.OK;
                    actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, result);
                    return;
                }
                if (IsLogin)
                {
                    ApiUserManager userManager = new ApiUserManager(actionContext);
                    if (!userManager.ExistsLogin())
                    {
                        result.code = -22;
                        result.msg = "illegal user";
                        actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, result);
                        return;
                    }
                }
                base.OnActionExecuting(actionContext);
            }
        }

    过滤器的使用可以针对单独一个接口进行限制,也可以针对一个控制器中的所有接口进行限制。

    针对单独一个接口限制

    /// <summary>
            /// 获取当前登录用户信息
            /// </summary>
            /// <returns></returns>
            [HttpGet]
            [Route("userinfo")]
            [ApiActionFilterAttribute(IsLogin = true)]
            public async Task<IHttpActionResult> Userinfo()
            {
                JsonResult<UserInfo> result = new JsonResult<UserInfo>();
                result.code = 1;
                result.msg = "OK";
                ApiUserManager userManager = new ApiUserManager(ActionContext);
                result.Result = userManager.User;
                return Ok(result);
            }

    针对整个控制器进行限制的话可以自定义一个控制器基类BaseApiController,所有需要验证用户登录的控制器继承它就可以

        [DExceptionFilterAttribute]
        [ApiActionFilterAttribute(IsLogin = true)]
        public class BaseApiController: ApiController
        {
            private UserInfo _User;
            /// <summary>
            /// 当前登录用户
            /// </summary>
            public UserInfo User
            {
                get
                {
                    if (_User==null)
                    {
                        ApiUserManager userManager = new ApiUserManager(this.ActionContext);
                        _User = userManager.User;
                    }
                    return _User;
                }
            }
        }

    至此授权和鉴权的机制基本已经完成,单独的资源服务器只需要使用公用的redis服务即可,而且redis也可以进行读写分离,就可以进行分布式部署。

    项目源码地址:

    https://github.com/liemei/asp.netOpenService.git

    作者: 刘帅超

    出处: http://www.cnblogs.com/liemei

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接

    如有问题, 可邮件(liushuaichao159@163.com)咨询.

  • 相关阅读:
    随机-byte编码
    dataframe骚操作,待续
    oracle中的rowid
    java提高篇-----理解java的三大特性之继承
    staruml使用教程
    黑马程序员:HTML习题1
    Cocos2d-x-->CCSprite 动画
    地址栏传参中文乱码详解
    Qt学习第二天
    Lync 2010 升级到2013 之部署2013前端服务器!
  • 原文地址:https://www.cnblogs.com/liemei/p/7063354.html
Copyright © 2020-2023  润新知