1, token authentication
Allocation token string after a successful login server. Record cache server, you can set validity period
var token = Guid.NewGuid().ToString().Replace("-", ""); var expire = DateTime.Now.AddHours(2); var timespan = ( expire- DateTime.Now); var key = string.Format("login-{0}", apiRm.Result.UserID); RedisCacheHelper.SetCacheByKey<string>(key, JsonHelper.ToJson(apiRm.Result), timespan);
Perform server authentication token validity after passing through the header
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'token: 1000-e0622f06a9a842a5b79a5295e6d4b235' -d
Or action may be provided in the controller to verify whether the attribute token
Controller: [RoutePrefix ( " API / Out " ), OperateTrack, an AuthToken (AuthTypeEnum.Driver)]
or
action: [HttpPost, Route ( " GetOutInfo"), AuthToken (AuthTypeEnum.Driver)]
read pass over the filter information:
User ControllerContext.RouteData.Values = var [ "User"];
var user1 = HttpContext.Current.User;
Creating AuthTokenAttribute inherited AuthorizeAttribute
public class AuthTokenAttribute : AuthorizeAttribute { public AuthTypeEnum VerifyAuth { get; set; } public AuthTokenAttribute() { this.VerifyAuth = AuthTypeEnum.Common; } public AuthTokenAttribute(AuthTypeEnum verifyAuth) { this.VerifyAuth = verifyAuth; } protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext) { var request = actionContext.Request; if(VerifyAuth== AuthTypeEnum.Driver) { var rm= AuthDriver(actionContext); if (!rm.IsSuccess) return false; } return true; } protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext) { StringBuilder sbMsg = new StringBuilder(); if (VerifyAuth == AuthTypeEnum.Driver) { var rm = AuthDriver(actionContext); if (!rm.IsSuccess) sbMsg.Append(rm.Message); } var content = JsonConvert.SerializeObject(new ResultApiModel { IsSuccess = false, Message = sbMsg.ToString() + ",验证失败,状态:" + (int)HttpStatusCode.Unauthorized, Code = ((int)HttpStatusCode.Unauthorized).ToString() }); actionContext.Response = new HttpResponseMessage { Content = new StringContent(content, Encoding.UTF8, "application/json"), StatusCode = HttpStatusCode.Unauthorized }; } private ResultApiModel AuthDriver(System.Web.Http.Controllers.HttpActionContext actionContext) { // TODO authentication token // the traditional values action, the action may be used: var user = ControllerContext.RouteData.Values [ "user "]; acquired actionContext.ControllerContext.RouteData.Values [ " User " ] = V; SetPrincipal(new UserPrincipal<int>(tokenV)); return ResultApiModel.Create(true); } public static void SetPrincipal(IPrincipal principal) { Thread.CurrentPrincipal = Principal; // each time re-covering user, to avoid different users access to different action of IF (HttpContext.Current =! Null ) { HttpContext.Current.User = principal; } } } public enum AuthTypeEnum { Common=0, Driver=1 }
IPrincipal:
public class UserIdentity<TKey> : IIdentity { public UserIdentity(IUser<TKey> user) { if (user != null) { IsAuthenticated = true; UserID = user.UserID; LoginNo = user.LoginNo.ToString(); Name = user.LoginNo.ToString(); UserName = user.UserName; RoleCode = user.RoleCode; token = user.token; } } public string AuthenticationType { get { return "CustomAuthentication"; } } public TKey UserID { get; private set; } public bool IsAuthenticated { get; private set; } public string LoginNo { get; private set; } public string Name { get; private set; } public string UserName { get; private set; } public string RoleCode { get; private set; } public string token { get; private set; } } public class UserPrincipal<TKey> : IPrincipal { public UserPrincipal(UserIdentity<TKey> identity) { Identity = identity; } public UserPrincipal(IUser<TKey> user) : this(new UserIdentity<TKey>(user)) { } /// <summary> /// /// </summary> public UserIdentity<TKey> Identity { get; private set; } IIdentity IPrincipal.Identity { get { return Identity; } } bool IPrincipal.IsInRole(string role) { throw new NotImplementedException(); } } public interface IUser<T> { /// <summary> /// 用户id /// </summary> T UserID { get; set; } /// <Summary> /// login Account /// </ Summary> String LoginNo { GET ; SET ;} /// <Summary> /// username /// </ Summary> String UserName { GET ; SET ;} /// <Summary> /// role ID /// </ Summary> String RoleCode { GET ; SET ;} /// <Summary> /// assigned login token /// </ Summary> String token { GET ; SET ;} }
2, verify the signature:
Conventions signature rules
controller increases or action property validation
[AuthSign(AuthSignTypeEnum.Common)]
Creating AuthSignAttribute inherited AuthorizeAttribute
public class AuthSignAttribute : AuthorizeAttribute { public AuthSignTypeEnum AuthSignType { get; set; } public AuthSignAttribute() { this.AuthSignType = AuthSignTypeEnum.Common; } public AuthSignAttribute(AuthSignTypeEnum authSignType) { this.AuthSignType = authSignType; } /// <Summary> /// public data request body /// </ Summary> Private String CommonRequestBodyData { GET ; SET ;} /// <summary> /// 权限验证 /// </summary> /// <param name="actionContext"></param> /// <returns></returns> protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext) { var request = actionContext.Request; var requestBodyData = StreamHelper.GetStream2String(request.Content.ReadAsStreamAsync().Result); if (AuthSignType == AuthSignTypeEnum.Common) { CommonRequestBodyData = requestBodyData.TrimStart("data=".ToCharArray()); var urlParam = GetUrlParam(actionContext); if (!urlParam.IsSuccess) return false; var rm = AuthSignCommon(urlParam.Result, CommonRequestBodyData); if (!rm.IsSuccess) return false; } return true; } private ResultApiModel AuthSignCommon(CommonRequestApiModel request, string requestBodyData) { //todo 验证signreturn ResultApiModel.Create(true); } /// <Summary> /// process unauthorized request /// </ Summary> /// <param name = "ActionContext"> </ param> protected the override void HandleUnauthorizedRequest (System.Web.Http.Controllers. HttpActionContext actionContext) { StringBuilder sbMsg = new StringBuilder(); if (AuthSignType == AuthSignTypeEnum.Common) { // todo process validation failure information } var Content = JsonConvert.SerializeObject ( new new ResultApiModel = {isSuccess to false , the Message sbMsg.ToString = () + " signature verification fails, the state: " + HttpStatusCode.Unauthorized}); actionContext.Response = new HttpResponseMessage { Content = new StringContent(content, Encoding.UTF8, "application/json"), StatusCode = HttpStatusCode.Unauthorized }; } } /// <Summary> /// signature type /// </ Summary> public enum AuthSignTypeEnum { Common = 0 }
3, access log:
controller or action to increase property
[RoutePrefix("api/Out"), OperateTrack, AuthToken(AuthTypeEnum.Driver)]
May not need to log [NoLog]
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)] public class NoLogAttribute : Attribute { }
Inheritance: ActionFilterAttribute
public class OperateTrackAttribute : ActionFilterAttribute { /// <Summary> /// custom parameter /// </ Summary> public String MSG { GET ; SET ;} public OperateTrackAttribute () { } /// <Summary> /// Description class initialization filled /// </ Summary> /// <param name = "Message"> </ param> public OperateTrackAttribute ( String Message) { msg = message; } private static readonly string key = "enterTime"; public override Task OnActionExecutingAsync(System.Web.Http.Controllers.HttpActionContext actionContext, CancellationToken cancellationToken) { if (SkipLogging(actionContext)) { return base.OnActionExecutingAsync(actionContext, cancellationToken); } // record the time of incoming requests actionContext.Request.Properties [Key] = DateTime.Now.ToBinary (); return base.OnActionExecutingAsync(actionContext, cancellationToken); } /// <Summary> /// request after performing the data recording request and return the data /// </ Summary> /// <param name = "actionExecutedContext"> </ param> /// <param name = "CancellationToken"> </ param> /// <Returns> </ Returns> public the override the Task OnActionExecutedAsync (HttpActionExecutedContext actionExecutedContext, a CancellationToken CancellationToken) { object beginTime = null; if (actionExecutedContext.Request.Properties.TryGetValue(key, out beginTime)) { DateTime time = DateTime.FromBinary(Convert.ToInt64(beginTime)); HttpRequest request = HttpContext.Current.Request; string token = request.Headers["token"]; WebApiActionLogModel apiActionLog = new WebApiActionLogModel { The above mentioned id = Guid.NewGuid (), // get action name actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName, // get Controller name controllername = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName, // get time action begins execution enterTime = Time, // get time-consuming to perform the action costTime = (DateTime.Now - Time) .TotalMilliseconds, navigator = request.UserAgent, token = token, // get the user token userId = getUserByToken (token), // get access to ip ip = request.UserHostAddress, userHostName = request.UserHostName, urlReferrer = request.UrlReferrer != null ? request.UrlReferrer.AbsoluteUri : "", browser = request.Browser.Browser + " - " + request.Browser.Version + " - " + request.Browser.Type, //获取request提交的参数 paramaters = StreamHelper.GetStream2String(actionExecutedContext.Request.Content.ReadAsStreamAsync().Result), //获取response响应的结果 executeResult = StreamHelper.GetStream2String(actionExecutedContext.Response.Content.ReadAsStreamAsync().Result), comments = msg, RequestUri = request.Url.AbsoluteUri }; //记debug Log.DefaultLogDebug(string.Format("actionExecutedContext {0} 请求:{1}", apiActionLog.controllerName + "/" + apiActionLog.actionName, JsonHelper.ToJson(apiActionLog))); } return base.OnActionExecutedAsync(actionExecutedContext, cancellationToken); } /// <the Summary> /// Gets the currently logged-on user id /// </ the Summary> /// <param name = "token"> </ param> /// <returns A> </ returns A> public static String getUserByToken ( String token) { UserIdentity<int> u = HttpContext.Current.User.Identity as UserIdentity<int>; if (u == null) return "未登录用户" + token; return u.LoginNo.ToString(); } /// <Summary> /// characteristic determining the class and method to be performed if the head Action intercept /// </ Summary> /// <param name = "ActionContext"> </ param> /// <Returns> </ Returns> Private static BOOL SkipLogging (System.Web.Http.Controllers.HttpActionContext ActionContext) { return actionContext.ActionDescriptor.GetCustomAttributes<NoLogAttribute>().Any() || actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<NoLogAttribute>().Any(); } }