一、Api提供登录接口,并在需要身份验证的接口上添加权限验证拦截器
using System;
using System.Web.Http;
namespace WebApiTest
{
public class UserController : ApiController
{
[HttpPost]
[AllowAnonymous]
public IHttpActionResult Login(string userName, string password)
{
Message msg = new Message();
msg.Title = Message.Error;
if (string.IsNullOrEmpty(userName))
{
throw new ArgumentNullException("用户名不能为空");
}
if (string.IsNullOrEmpty(password))
{
throw new ArgumentNullException("用户密码不能为空");
}
Message getMsg = UserAuthority.VerificationCacheUser(userName, password);
msg.Content = getMsg.Content;
return Ok(msg);
}
}
}
public static Message VerificationCacheUser(string userName, string password)
{
Message msg = new Message();
msg.Title = Message.Error;
msg.Content = "其他";
var model = Common.UserLists.Where(d => d.Name.Equals(userName) && d.Password.Equals(password)).FirstOrDefault();
if (model.Id == 0)
{
throw new ArgumentException("用户名或密码错误");
}
var expiresTime = model.OfflineTime > 0 ? model.OfflineTime : 5;
string sid = Guid.NewGuid().ToString("N");
UserToken us = new UserToken();
us.Id = model.Id;
us.Name = model.Name;
us.LastCorrespondTime = DateTime.Now;
us.Session.ExpiresTime = expiresTime;
us.Session.Sid = sid;
CacheHelper.Set(model.Name, us, DateTime.Now.AddMinutes(expiresTime));
var tokenValue = DESEncrypt.Encrypt(JsonConvert.SerializeObject(us));
if (string.IsNullOrEmpty(tokenValue))
{
throw new Exception("登录成功了,但token信息获取为空");
}
#region
model.LastLoginTime = DateTime.Now;
model.ExtendParas = tokenValue;
model.OfflineTime = expiresTime;
Common.UpdateUser(model);
#endregion
KeyValuePair<string, string> Token = new KeyValuePair<string, string>(Common.PublicAuthorityKey, tokenValue);
msg.Content = JsonConvert.SerializeObject(Token);
return msg;
}
二、权限验证拦截器
using System;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace WebApiTest
{
public class UserCacheVerificationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
Message msg = new Message();
msg.Title = Message.Error;
try
{
var res = UserCacheVerification.CheckUser(actionContext);
switch (res)
{
case UserVerificationResult.Success:
{
//actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
return;
}
case UserVerificationResult.LoginInvalid:
default:
msg.Content = "登录无效233";
break;
}
}
catch (Exception ex)
{
msg.Content = "登录异常";
}
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
actionContext.Response.Content = new ObjectContent(typeof(Message), msg, new JsonMediaTypeFormatter());
}
}
}
public static UserVerificationResult CheckUser(HttpActionContext actionContext)
{
try
{
string token = PublicMethod.GetSessionId(actionContext);
if (string.IsNullOrEmpty(token))
{
return UserVerificationResult.CookieInfoLost;
}
string json = DESEncrypt.Decrypt(token);
if (string.IsNullOrEmpty(json))
{
return UserVerificationResult.CookieInfoLost;
}
UserToken ut = JsonConvert.DeserializeObject<UserToken>(json);
if (ut == null)
{
return UserVerificationResult.CookieInfoLost;
}
UserToken utGetFromCache = (UserToken)CacheHelper.Get(ut.Name);
if (utGetFromCache == null)
{
return UserVerificationResult.CookieInvalid;
}
if (ut.Session.Sid == utGetFromCache.Session.Sid)
{
if (utGetFromCache.LastCorrespondTime.AddMinutes(utGetFromCache.Session.ExpiresTime) > DateTime.Now)
{
utGetFromCache.LastCorrespondTime = DateTime.Now;
CacheHelper.Set(ut.Name, utGetFromCache, DateTime.Now.AddMinutes(utGetFromCache.Session.ExpiresTime));
return UserVerificationResult.Success;
}
else
{
return UserVerificationResult.LoginInvalid;
}
}
else
{
return UserVerificationResult.CookieInvalid;
}
}
catch (Exception ex)
{
return UserVerificationResult.FormatError;
}
}
public static string GetSessionId(HttpActionContext actionContext)
{
try
{
IEnumerable<string> vals;
if (!actionContext.Request.Headers.TryGetValues(Common.PublicAuthorityKey, out vals))
{
return string.Empty;
}
if (vals == null || vals.Count() <= 0)
{
return string.Empty;
}
return vals.ElementAt(0);
}
catch (Exception ex)
{
return string.Empty;
}
}
三、CacheHelper与DES帮助类
using System;
using System.Collections;
using System.Threading.Tasks;
using System.Web;
namespace WebApiTest
{
public class CacheHelper
{
public static T GetOrSet<T>(string key, Func<T> getDataCallback, DateTime exp) where T : class
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentException("Invalid cache key");
T data;
if (HttpRuntime.Cache[key] == null)
{
data = getDataCallback();
if (data == null)
{
return default(T);//data
}
Set(key, data, exp);
}
else
{
data = HttpRuntime.Cache[key] as T;
}
return data;
}
public static async Task<T> GetOrSetAsync<T>(string key, Func<Task<T>> getDataCallback, DateTime exp)
where T : class
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentException("Invalid cache key");
T data = HttpRuntime.Cache[key] as T;
if (data == null)
{
data = await getDataCallback();
if (data == null)
{
return default(T);//data
}
Set(key, data, exp);
}
return data;
}
public static object Get(string key)
{
return HttpRuntime.Cache[key];
}
public static void Set(string key, object value, DateTime exp)
{
if (HttpRuntime.Cache.Get(key) != null)
{
HttpRuntime.Cache.Remove(key);
}
HttpRuntime.Cache.Insert(key, value, null, exp, TimeSpan.Zero);
}
public static void Set(string key, object value)
{
if (HttpRuntime.Cache.Get(key) != null)
{
HttpRuntime.Cache.Remove(key);
}
HttpRuntime.Cache.Insert(key, value, null, DateTime.MaxValue, TimeSpan.Zero);
}
public static void Remove(string cacheKey)
{
HttpRuntime.Cache.Remove(cacheKey);
}
/// <summary>
/// 移除全部缓存
/// </summary>
public static void Remove()
{
IDictionaryEnumerator CacheEnum = HttpRuntime.Cache.GetEnumerator();
while (CacheEnum.MoveNext())
{
HttpRuntime.Cache.Remove(CacheEnum.Key.ToString());
}
}
}
}
using System;
using System.Security.Cryptography;
using System.Text;
using System.Web.Security;
namespace WebApiTest
{
public class DESEncrypt
{
private static string DESKey = "WebApiTest";
#region ========加密========
/// <summary>
/// 加密
/// </summary>
/// <param name="Text"></param>
/// <returns></returns>
public static string Encrypt(string Text)
{
return Encrypt(Text, DESKey);
}
/// <summary>
/// 加密数据
/// </summary>
/// <param name="Text"></param>
/// <param name="sKey"></param>
/// <returns></returns>
public static string Encrypt(string Text, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray;
inputByteArray = Encoding.Default.GetBytes(Text);
des.Key = ASCIIEncoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
des.IV = ASCIIEncoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
return ret.ToString();
}
#endregion
#region ========解密========
/// <summary>
/// 解密
/// </summary>
/// <param name="Text"></param>
/// <returns></returns>
public static string Decrypt(string Text)
{
if (!string.IsNullOrEmpty(Text))
{
return Decrypt(Text, DESKey);
}
else
{
return "";
}
}
/// <summary>
/// 解密数据
/// </summary>
/// <param name="Text"></param>
/// <param name="sKey"></param>
/// <returns></returns>
public static string Decrypt(string Text, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
int len;
len = Text.Length / 2;
byte[] inputByteArray = new byte[len];
int x, i;
for (x = 0; x < len; x++)
{
i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
inputByteArray[x] = (byte)i;
}
des.Key = ASCIIEncoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
des.IV = ASCIIEncoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Encoding.Default.GetString(ms.ToArray());
}
#endregion
}
}