通过网上查看相关WebAPI接口验证的方法,整理了一下,直接上代码,功能不复杂,有问题留言,

//-----------------------------------------------------------------------
// <copyright file="ApiAuthenticationFilter.cs" company="FenSiShengHuo, Ltd.">
//     Copyright (c) 2018 , All rights reserved.
// </copyright>
//-----------------------------------------------------------------------using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Principal;
using System.Threading;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;namespace DotNet.WeChat.API.Attribute
{using DotNet.Business;using DotNet.Model;using DotNet.Utilities;/// <summary>/// ApiAuthenticationFilter/// /// 2018-07-19 版本:1.0 JiShiYu 创建。    ////// <author>///        <name>JiShiYu</name>///        <date>2018-07-19</date>/// </author> /// </summary>public class ApiAuthenticationFilter : AuthorizationFilterAttribute{public override void OnAuthorization(HttpActionContext filterContext){// 判断是否是不做授权检查的var apiNoAuthenticationFilter = filterContext.ActionDescriptor.GetCustomAttributes<ApiNoAuthenticationFilter>();if (apiNoAuthenticationFilter != null && apiNoAuthenticationFilter.Any()){return;}BaseResult result = null;var identity = ParseHeader(filterContext, out result); //取得資料內容if (identity == null){ChallengeAuthRequest(filterContext, result); //回傳錯誤訊息return;}var genericPrincipal = new GenericPrincipal(identity, null);//  在认证成功后将认证身份设置给当前线程中Principal属性Thread.CurrentPrincipal = genericPrincipal;result = OnAuthorizeUser(identity, filterContext);if (!result.Status){ChallengeAuthRequest(filterContext, result);return;}}/// <summary>/// 定义一个方法便校验,并将其修饰为虚方法,以免后续要添加其他有关用户数据/// </summary>/// <param name="appKey"></param>/// <param name="appSecret"></param>/// <param name="token"></param>/// <param name="actionContext"></param>/// <returns></returns>protected virtual BaseResult OnAuthorizeUser(BasicAuthenticationIdentity identity, HttpActionContext actionContext){BaseResult result = new BaseResult();result.Status = false;result.StatusCode = Status.ParameterError.ToString();if (string.IsNullOrWhiteSpace(identity.SystemCode)){result.Status = false;result.StatusCode = Status.ParameterError.ToString();result.StatusMessage = "systemCode " + Status.ParameterError.ToDescription();return result;}// 判断参数if (identity.UserInfo != null){// 防止伪造、判断用户的有效性if (!ServiceUtil.VerifySignature(identity.UserInfo)){result.StatusCode = Status.SignatureError.ToString();result.StatusMessage = "userInfo " + Status.SignatureError.ToDescription();return result;}// 这里需要是已经登录的用户,不是已经被踢掉的用户if (!Utilities.ValidateOpenId(identity.UserInfo.Id, identity.UserInfo.OpenId)){result.StatusCode = Status.SignatureError.ToString();result.StatusMessage = "OpenId " + Status.SignatureError.ToDescription();return result;}}else{string ipAddress = Utilities.GetIPAddress(true);// 检查是否为内部ip地址发送出去的手机短信  //if (onlyLocalIp)//{//    if (!IpHelper.IsLocalIp(ipAddress))//    {//        // 不是内网发出的, 也不是信任的ip列表里的,直接给拒绝发送出去//        result.Status = false;//        result.StatusCode = Status.ErrorIPAddress.ToString();//        result.StatusMessage = ipAddress + " " + Status.ErrorIPAddress.ToDescription();//    }//}if (string.IsNullOrWhiteSpace(identity.AppKey)){result.StatusCode = Status.ParameterError.ToString();result.StatusMessage = "appKey " + Status.ParameterError.ToDescription();return result;}if (string.IsNullOrWhiteSpace(identity.Signature)){result.StatusCode = Status.ParameterError.ToString();result.StatusMessage = "signature " + Status.ParameterError.ToDescription();return result;}if (string.IsNullOrWhiteSpace(identity.TimeSpan)){result.StatusCode = Status.ParameterError.ToString();result.StatusMessage = "TimeSpan " + Status.ParameterError.ToDescription();return result;}else{long unixTimeStamp;if (long.TryParse(identity.TimeSpan, out unixTimeStamp)){DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区DateTime dtStart = startTime.AddSeconds(unixTimeStamp);TimeSpan ts = DateTime.Now - dtStart;if (ts.TotalMinutes > 5){result.StatusCode = Status.ParameterError.ToString();result.StatusMessage = "请求时间已过期,请检查请求服务器时间,传递当前时间戳";return result;}}else{result.StatusCode = Status.ParameterError.ToString();result.StatusMessage = "TimeSpan时间戳参数错误,传递当前时间戳";return result;}}//  AppSecret 不应该传//if (string.IsNullOrWhiteSpace(identity.AppSecret))//{//    result.StatusCode = Status.ParameterError.ToString();//    result.StatusMessage = "appSecret " + Status.ParameterError.ToDescription();//    return result;//}// 取服务器上的var secret = BaseServicesLicenseManager.GetSecretByKeyByCache(identity.AppKey);if (string.IsNullOrWhiteSpace(secret)){result.StatusCode = Status.ParameterError.ToString();result.StatusMessage = "找不到appKey的密钥";return result;}else{string serverSignature = System.Web.HttpUtility.UrlEncode(SecretUtilitiesBase.md5(identity.AppKey + identity.TimeSpan + secret));if (!string.Equals(identity.Signature, serverSignature)){result.StatusCode = Status.ParameterError.ToString();result.StatusMessage = "Signature 签名不正确";return result;}}result = BaseServicesLicenseManager.CheckService(identity.AppKey, secret, true, false, 0, 0, identity.SystemCode, identity.PermissionCode);if (result.Status){// 从接口确定当前调用者BaseUserEntity userEntity = BaseUserManager.GetObjectByCodeByCache(identity.AppKey, true);if (userEntity != null){BaseUserInfo userInfo = new BaseUserInfo();userInfo.Id = userEntity.Id;userInfo.Code = userEntity.Code;userInfo.UserName = userEntity.UserName;userInfo.NickName = userEntity.NickName;userInfo.RealName = userEntity.RealName;userInfo.CompanyId = userEntity.CompanyId;userInfo.CompanyCode = userEntity.CompanyCode;userInfo.CompanyName = userEntity.CompanyName;userInfo.IPAddress = ipAddress;identity.UserInfo = userInfo;}}}return result;}/// <summary>/// 解析Headers/// </summary>/// <param name="filterContext"></param>/// <returns></returns>protected virtual BasicAuthenticationIdentity ParseHeader(HttpActionContext filterContext, out BaseResult result){BasicAuthenticationIdentity authenticationIdentity = null;result = new BaseResult();BaseUserInfo userInfo = null;string systemCode = string.Empty;string appKey = string.Empty;string timeSpan = string.Empty;string signature = string.Empty;string permissionCode = string.Empty;string userInfoStr = string.Empty;try{var re = filterContext.Request;var headers = re.Headers;if (headers.Contains("systemCode")){systemCode = headers.GetValues("systemCode").First();}if (headers.Contains("appKey")){appKey = headers.GetValues("appKey").First();}if (headers.Contains("timeSpan")){timeSpan = headers.GetValues("timeSpan").First();}if (headers.Contains("signature")){signature = headers.GetValues("signature").First();}if (headers.Contains("permissionCode")){permissionCode = headers.GetValues("permissionCode").First();}if (headers.Contains("userInfoStr")){userInfoStr = headers.GetValues("userInfoStr").First();userInfo = BaseUserInfo.Deserialize(userInfoStr);}authenticationIdentity = new BasicAuthenticationIdentity(systemCode, appKey, timeSpan, signature, userInfo, permissionCode);result.Status = true;result.StatusCode = Status.OK.ToString();result.StatusMessage = "构建成功";}catch (Exception ex){NLogHelper.Warn(ex, "ParseHeader");result.Status = false;result.StatusCode = Status.Error.ToString();result.StatusMessage = "异常:" + ex.Message;}return authenticationIdentity;}/// <summary>/// 授权验证失败/// </summary>/// <param name="filterContext"></param>private static void ChallengeAuthRequest(HttpActionContext filterContext, BaseResult result){var dnsHost = filterContext.Request.RequestUri.DnsSafeHost;//filterContext.Response = filterContext.Request.CreateResponse(HttpStatusCode.Unauthorized);filterContext.Response = filterContext.Request.CreateResponse(HttpStatusCode.OK, result);filterContext.Response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", dnsHost));}}/// <summary>/// 认证实体类/// </summary>public class BasicAuthenticationIdentity : GenericIdentity{/// <summary>/// 系统编号/// </summary>public string SystemCode { get; set; }/// <summary>/// AppKey/// </summary>public string AppKey { get; set; }/// <summary>/// 请求时间戳/// </summary>public string TimeSpan { get; set; }/// <summary>/// Signature 签名值/// </summary>public string Signature { get; set; }/// <summary>/// 用户信息/// </summary>public BaseUserInfo UserInfo { get; set; }/// <summary>/// 权限编号/// </summary>public string PermissionCode { get; set; }/// <summary>/// 构造函数/// </summary>/// <param name="systemCode"></param>/// <param name="appKey"></param>/// <param name="timeSpan"></param>/// <param name="signature"></param>/// <param name="userInfo"></param>/// <param name="permissionCode"></param>public BasicAuthenticationIdentity(string systemCode, string appKey, string timeSpan, string signature, BaseUserInfo userInfo, string permissionCode): base(appKey, "Basic"){this.SystemCode = systemCode;this.AppKey = appKey;this.TimeSpan = timeSpan;this.Signature = signature;this.UserInfo = userInfo;this.PermissionCode = permissionCode;}}
}

不需要做校验的接口,加一个标签

//-----------------------------------------------------------------------
// <copyright file="ApiAuthenticationFilter.cs" company="FenSiShengHuo, Ltd.">
//     Copyright (c) 2018 , All rights reserved.
// </copyright>
//-----------------------------------------------------------------------using System.Web.Http.Filters;namespace DotNet.WeChat.API.Attribute
{/// <summary>/// ApiNoAuthenticationFilter/// 不做授权检查/// /// 2018-07-19 版本:1.0 JiShiYu 创建。    ////// <author>///        <name>JiShiYu</name>///        <date>2018-07-19</date>/// </author> /// </summary>public class ApiNoAuthenticationFilter : AuthorizationFilterAttribute{ }
}

全局校验,放在哪里,你懂的

    public static class WebApiConfig{public static void Register(HttpConfiguration config){// 接口授权检查config.Filters.Add(new ApiAuthenticationFilter());}
}

  

测试效果

WebAPI接口安全校验相关推荐

  1. Springboot + redis + 注解 + 拦截器来实现接口幂等性校验

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:wangzaiplus www.jianshu.com/p/ ...

  2. SpringBoot实现通用的接口参数校验

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:cipher juejin.im/post/5af3c25b ...

  3. springboot + redis + 注解 + 拦截器 实现接口幂等性校验

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 来源:https://www.jianshu.com/p/6189275403ed 一.概念 ...

  4. c语言实现java接口_五分钟带你了解Java是如何从容而优雅地实现接口数据校验

    本篇文章给大家分享平时开发中总结的一点小技巧!在工作中写过Java程序的朋友都知道,目前使用Java开发服务最主流的方式就是通过Spring MVC定义一个Controller层接口,并将接口请求或返 ...

  5. java 接口参数验证_SpringBoot实现通用的接口参数校验

    作者:cipher 来源:http://39sd.cn/560BA 本文介绍基于Spring Boot和JDK8编写一个AOP,结合自定义注解实现通用的接口参数校验. 缘由 目前参数校验常用的方法是在 ...

  6. C#进阶系列——WebApi 接口参数不再困惑:传参详解

    看这边文章时的疑惑是:WebApi中的参数加了[FromBody],不知所以然,就百度了下,看到了以下文章,和大家分享下: 原文链接:http://www.cnblogs.com/landeanfen ...

  7. WebApi 接口参数不再困惑:传参详解

    阅读目录 一.get请求 1.基础类型参数 2.实体作为参数 3.数组作为参数 4."怪异"的get请求 二.post请求 1.基础类型参数 2.实体作为参数 3.数组作为参数 4 ...

  8. redis 判断存在性_实战 | springboot+redis+拦截器 实现接口幂等性校验

    来源:https://www.jianshu.com/p/6189275403ed 一.概念 幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次 比如: 订单接口, 不能 ...

  9. @slf4j注解_SpringBoot + Redis + 注解 + 拦截器 实现接口幂等性校验

    一.概念 幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次 比如: 订单接口, 不能多次创建订单 支付接口, 重复支付同一笔订单只能扣一次钱 支付宝回调接口, 可能会多 ...

最新文章

  1. ML之FE:数据随机抽样之利用pandas的sample函数对超大样本的数据集进行随机采样,并另存为csv文件
  2. 全球及中国婴儿痤疮药行业消费需求调研与竞争策略展望报告2022版
  3. 数据结构(二)算法基础与复杂度
  4. 周志華《機器學習》圖4.4和图4.9繪制(轉載+增加熵顯示功能)
  5. 计算机在社会服务方面的作用,计算机在档案管理中的作用
  6. oracle 11gdata guard,Oracle 11g Data Guard配置
  7. Beginning iCloud in iOS 5 Tutorial Part 2(转载)
  8. 【faster rcnn 实现via的自动框人】使用detectron2中faster rcnn 算法生成人的坐标,将坐标导入via(VGG Image Annotator)中,实现自动框选出人的区域
  9. 我的MYSQL学习心得(十三) 权限管理
  10. 优势java_Java的核心优势
  11. 如何:在 Windows 窗体 ListView 控件中启用平铺视图 【转载】
  12. 说文解字 —— 汉字的构成及语义的变化
  13. 找出唯一出现一次的数
  14. [转载] 七龙珠第一部——第012话 向神龙许愿
  15. java十大排序法_Java 十大排序算法
  16. mpeg1,mpeg2,mpeg4
  17. rebase和merge区别
  18. 【Golang】Slice数组组成和扩容机制
  19. explain 介绍
  20. 企业自动化运维ansible

热门文章

  1. RFM模型分析与客户细分
  2. Spark快速上手-WordCount案例
  3. mysql数据库---授权语句以及备份
  4. 三维渲染引擎设计与实践(四)
  5. scroll事件实现监控滚动条并分页显示示例(zepto.js)
  6. 理解VMware虚拟网络
  7. 通过form表单请求servlet资源代码
  8. 【转载】无需图片,使用CSS3实现圆角按钮
  9. c编写程序完成m名旅客和n辆汽车的同步程序代写
  10. io.h源码 检查文件是否存在