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认证、访问日志的更多相关文章

  1. ASP.NET WebApi 基于OAuth2.0实现Token签名认证

    一.课程介绍 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将是我们需要思考的问题.为了保护我们的WebApi数 ...

  2. ASP.NET WebApi 基于JWT实现Token签名认证

    一.前言 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebServi ...

  3. ASP.NET WebApi 基于分布式Session方式实现Token签名认证

    一.课程介绍 明人不说暗话,跟着阿笨一起学玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NETWebSer ...

  4. ASP.NET WebApi 基于分布式Session方式实现Token签名认证(发布版)

    一.课程介绍 明人不说暗话,跟着阿笨一起学玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NETWebSer ...

  5. apache用户认证、域名跳转、Apache访问日志(两种格式)

    1.apache 设置,用户访问时 目录或文件的认证: 对目录的认证: <Directory /var/www/222> //指定认证的目录AllowOverride AuthConfig ...

  6. centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 访问控制 apache rewrite 配置开机启动apache tcpdump 第二十节课

    centos    LAMP第二部分apache配置  下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转  配置apache的访问日志  配置静态文件缓存  配置防盗链 ...

  7. Apache用户认证、域名跳转、Apache访问日志

    5月29日任务 课程内容: 11.18 Apache用户认证11.19/11.20 域名跳转11.21 Apache访问日志扩展 apache虚拟主机开启php的短标签 http://ask.apel ...

  8. Linux CentOS7 VMware LAMP架构Apache用户认证、域名跳转、Apache访问日志

    一.Apache用户认证 vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf //把111.com那个虚拟主机编辑成如下内容 <Virtu ...

  9. C# WebApi 过滤器的使用开发接口必备利器

    在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想 ...

随机推荐

  1. javascript之随机密码[必包含大写,小写,数字]

    js取两个数字之间的随机数: parseInt(Math.random()*(上限-下限+1)+下限) 如:取1-10之间的随机数   parseInt(Math.random()*(10-1+1)+ ...

  2. es6学习1:let和const

    一:let   类似var 但是所声明的变量,只在let命令所在的代码块内有效. 1) 不存在变量提升 // var 的情况 console.log(foo); // 输出undefined var ...

  3. GIT 安装和升级

    git 安装: http://git-scm.com/download/mac git 升级: $ git clone git://git.kernel.org/pub/scm/git/git.git

  4. [开源] FreeSql.AdminLTE.Tools 根据实体类生成后台管理代码

    前言 FreeSql 发布至今已经有9个月,功能渐渐完善,自身的生态也逐步形成,早在几个月前写过一篇文章<ORM 开发环境之利器:MVC 中间件 FreeSql.AdminLTE>,您可以 ...

  5. Node.js之删除文件夹(含递归删除)

    应用场景:比如像Eclipse这样的IDE,右击项目,出现选项,点击选项中的删除,就可以删除这个项目及其下的子目录包含文件(使用electron开发的桌面端项目多少都会用到). 核心代码如下: /** ...

  6. Jquery创建动态表单

    $(document).ready(function(){ $("#button1").click(function(){ //获取html <body></bo ...

  7. uniapp - picker

    [普通json数组] 针对官方的普通json数组示例,做些填充 <template> <view> <view class="uni-title uni-com ...

  8. 系统树图 | Dendrogram construction | Phylogenetic Analysis

    Molecular Architecture of the Mouse Nervous System 表示亲缘关系的树状图解 先看文章里是怎么做的: Dendrogram construction A ...

  9. 【mybatis源码学习】mybatis的插件功能

    一.mybatis的插件功能可拦截的目标 org.apache.ibatis.executor.parameter.ParameterHandler org.apache.ibatis.executo ...

  10. openresty开发系列31--openresty执行流程

    openresty开发系列31--openresty执行流程 我们先看个例子 location /test {    set $a 32;    echo $a;    set $a 56;    e ...