c# webapi 过滤器token、sign认证、访问日志
1、token认证
服务端登录成功后分配token字符串。记录缓存服务器,可设置有效期
- var token = Guid.NewGuid().ToString().Replace("-", "");
- var expire = DateTime.Now.AddHours();
- var timespan = ( expire- DateTime.Now);
- var key = string.Format("login-{0}", apiRm.Result.UserID);
- RedisCacheHelper.SetCacheByKey<string>(key, JsonHelper.ToJson(apiRm.Result), timespan);
通过header传入token后进行服务端认证有效性
- curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'token: 1000-e0622f06a9a842a5b79a5295e6d4b235' -d
在controller或action可设置属性是否要验证token
- controller:[RoutePrefix("api/Out"), OperateTrack, AuthToken(AuthTypeEnum.Driver)]
或
action:[HttpPost, Route("GetOutInfo"),AuthToken(AuthTypeEnum.Driver)]- 读取过滤器传过来的信息:
var user = ControllerContext.RouteData.Values["user"];
var user1 = HttpContext.Current.User;
创建AuthTokenAttribute继承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 验证token
- //向action传值,在action中可以使用:var user = ControllerContext.RouteData.Values["user"];获取到
- actionContext.ControllerContext.RouteData.Values["user"] = v;
- SetPrincipal(new UserPrincipal<int>(tokenV));
- return ResultApiModel.Create(true);
- }
- public static void SetPrincipal(IPrincipal principal)
- {
- Thread.CurrentPrincipal = principal;
- //每次都重新覆盖user,避免不同用户对不同action的访问
- if (HttpContext.Current != null)
- {
- HttpContext.Current.User = principal;
- }
- }
- }
- public enum AuthTypeEnum
- {
- Common=,
- Driver=
- }
- 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>
- /// 登录账号
- /// </summary>
- string LoginNo { get; set; }
- /// <summary>
- /// 用户名称
- /// </summary>
- string UserName { get; set; }
- /// <summary>
- /// 角色编号
- /// </summary>
- string RoleCode { get; set; }
- /// <summary>
- /// 登录后分配token
- /// </summary>
- string token { get; set; }
- }
2、验证签名:
约定签名规则
controller或action增加属性验证
- [AuthSign(AuthSignTypeEnum.Common)]
创建AuthSignAttribute继承AuthorizeAttribute
- public class AuthSignAttribute : AuthorizeAttribute
- {
- public AuthSignTypeEnum AuthSignType { get; set; }
- public AuthSignAttribute() { this.AuthSignType = AuthSignTypeEnum.Common; }
- public AuthSignAttribute(AuthSignTypeEnum authSignType)
- {
- this.AuthSignType = authSignType;
- }
- /// <summary>
- /// 公共请求主体数据
- /// </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>
- /// 处理未授权的请求
- /// </summary>
- /// <param name="actionContext"></param>
- protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
- {
- StringBuilder sbMsg = new StringBuilder();
- if (AuthSignType == AuthSignTypeEnum.Common)
- {
- //todo 处理验证失败信息
- }
- var content = JsonConvert.SerializeObject(new ResultApiModel { IsSuccess = false, Message = sbMsg.ToString() + " 签名验证失败,状态:" + HttpStatusCode.Unauthorized });
- actionContext.Response = new HttpResponseMessage
- {
- Content = new StringContent(content, Encoding.UTF8, "application/json"),
- StatusCode = HttpStatusCode.Unauthorized
- };
- }
- }
- /// <summary>
- /// 签名类型
- /// </summary>
- public enum AuthSignTypeEnum
- {
- Common =
- }
3、访问日志:
controller或action增加属性
[RoutePrefix("api/Out"), OperateTrack, AuthToken(AuthTypeEnum.Driver)]
不需要日志可以[NoLog]
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)]
- public class NoLogAttribute : Attribute
- {
- }
继承:ActionFilterAttribute
- public class OperateTrackAttribute : ActionFilterAttribute
- {
- /// <summary>
- /// 自定义参数
- /// </summary>
- public string msg { get; set; }
- public OperateTrackAttribute()
- {
- }
- /// <summary>
- /// 初始化时填入类的说明
- /// </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);
- }
- //记录进入请求的时间
- actionContext.Request.Properties[key] = DateTime.Now.ToBinary();
- return base.OnActionExecutingAsync(actionContext, cancellationToken);
- }
- /// <summary>
- /// 在请求执行完后 记录请求的数据以及返回数据
- /// </summary>
- /// <param name="actionExecutedContext"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, 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
- {
- Id = Guid.NewGuid(),
- //获取action名称
- actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName,
- //获取Controller 名称
- controllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName,
- //获取action开始执行的时间
- enterTime = time,
- //获取执行action的耗时
- costTime = (DateTime.Now - time).TotalMilliseconds,
- navigator = request.UserAgent,
- token = token,
- //获取用户token
- userId = getUserByToken(token),
- //获取访问的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);
- }
- /// <summary>
- /// 获取当前登录用户的id
- /// </summary>
- /// <param name="token"></param>
- /// <returns></returns>
- 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>
- /// 判断类和方法头上的特性是否要进行Action拦截
- /// </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();
- }
- }
c# webapi 过滤器token、sign认证、访问日志的更多相关文章
- ASP.NET WebApi 基于OAuth2.0实现Token签名认证
一.课程介绍 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将是我们需要思考的问题.为了保护我们的WebApi数 ...
- ASP.NET WebApi 基于JWT实现Token签名认证
一.前言 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebServi ...
- ASP.NET WebApi 基于分布式Session方式实现Token签名认证
一.课程介绍 明人不说暗话,跟着阿笨一起学玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NETWebSer ...
- ASP.NET WebApi 基于分布式Session方式实现Token签名认证(发布版)
一.课程介绍 明人不说暗话,跟着阿笨一起学玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NETWebSer ...
- apache用户认证、域名跳转、Apache访问日志(两种格式)
1.apache 设置,用户访问时 目录或文件的认证: 对目录的认证: <Directory /var/www/222> //指定认证的目录AllowOverride AuthConfig ...
- centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 访问控制 apache rewrite 配置开机启动apache tcpdump 第二十节课
centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 ...
- Apache用户认证、域名跳转、Apache访问日志
5月29日任务 课程内容: 11.18 Apache用户认证11.19/11.20 域名跳转11.21 Apache访问日志扩展 apache虚拟主机开启php的短标签 http://ask.apel ...
- Linux CentOS7 VMware LAMP架构Apache用户认证、域名跳转、Apache访问日志
一.Apache用户认证 vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf //把111.com那个虚拟主机编辑成如下内容 <Virtu ...
- C# WebApi 过滤器的使用开发接口必备利器
在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想 ...
随机推荐
- 洛谷P4047 [JSOI2010]部落划分题解
洛谷P4047 [JSOI2010]部落划分题解 题目描述 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落 ...
- Pandas使用实用技巧
Pandas实用使用技巧 1 列拆分成行 常见的需求是将某一列根据指定的分隔符拆分成多列.现有需求,根据指定的分隔符将其拆分为多行. 例: df = A B 0 a f 1 b;c h;g 2 d k ...
- 辨析Java方法参数中的值传递和引用传递
小方法大门道 小瓜瓜作为一个Java初学者,今天跟我说她想通过一个Java方法,将外部变量通过参数传递到方法中去,进行逻辑处理,方法执行完毕之后,再对修改过的变量进行判断处理,代码如下所示. publ ...
- photoshop 的安装破解
最近学习需要用到photoshop,但是photoshop试用期只有30天,于是尝试破解photoshop.参考了网上的很多博客,失败了好几次,终于找到一篇靠谱的博客,很顺利的成功了.在这里记录一下, ...
- 剑指offer:左旋转字符串
题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=”ab ...
- Dolly
dolly - 必应词典 美['dɑli]英['dɒli] n.洋娃娃:(搬运重物的)台车 v.用独轮车运(物):用搅拌棒洗(衣):用捣棒捣碎(矿石) 网络多莉:多利:移动式摄影小车 变形复数:dol ...
- Fabric.js canvas 图形库
1.github地址: https://github.com/fabricjs/fabric.js 2.简述 Fabric.js将canvas的编程变得简单.同时在canvas上添加了交互.交互包括: ...
- windows server2012 R2安装python3.x版本报错0x80240017
windows server2012 R2安装python3.x版本报错0x80240017 环境: windows server 2012 R2系统 问题: 安装python3.5版本时候出现错误0 ...
- Android 加密之文件级加密(CE/DE)
https://blog.csdn.net/myfriend0/article/details/77094890/ Android加密之文件级加密
- ROS tf监听编写
博客转载自:https://www.ncnynl.com/archives/201702/1311.html ROS与C++入门教程-tf-编写tf listener(监听) 说明: 介绍如何使用tf ...