ASP.NET MVC API 接口验证的示例代码

项目中有一个留言消息接口,接收其他系统的留言和展示留言,参考了网上的一些API验证方法,发现使用通用权限管理系统提供的验证方法最完美。

下面将实现的完整思路共享

1、WebApiConfig全局处理

/// <summary>
  /// WebApiConfig 
  /// 路由基础配置。
  /// 
  /// 
  /// 修改记录
  /// 
  ///    2016.11.01 版本:2.0 宋彪 对日期格式进行统一处理。
  ///    2016.10.30 版本:2.0 宋彪 解决json序列化时的循环引用问题。
  ///    2016.10.28 版本:2.0 宋彪 回传响应格式 $format 支持。
  ///    2016.09.01 版本:1.0 宋彪  创建。
  /// 
  /// 版本:1.0
  /// 
  /// <author>
  ///    <name>宋彪</name>
  ///    <date>2016.09.01</date>
  /// </author> 
  /// </summary>
  public static class WebApiConfig
  {
    /// <summary>
    /// 注册全局配置服务
    /// </summary>
    /// <param name="config"></param>
    public static void Register(HttpConfiguration config)
    {
      // Web API configuration and services

      //强制https访问
      //config.Filters.Add(new ForceHttpsAttribute());
      // 统一回传格式
      config.Filters.Add(new ApiResultAttribute());
      // 发生异常时处理
      config.Filters.Add(new ApiErrorHandleAttribute());
      // ToKen身份验证过滤器 更方便 不需要在这里了 具有改标签的就会自动检查
      //config.Filters.Add(new ApiAuthFilterAttribute());
      // 解决json序列化时的循环引用问题
      config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
      //对日期格式进行统一处理
      config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(
      new IsoDateTimeConverter()
      {
        DateTimeFormat = "yyyy-MM-dd hh:mm:ss"
      }
      );

      // Web API routes 路由
      config.MapHttpAttributeRoutes();

      config.Routes.MapHttpRoute(
        name: "DefaultApi",routeTemplate: "api/{controller}/{action}/{id}",defaults: new { id = RouteParameter.Optional }
      );

      // 干掉XML序列化器
      //config.Formatters.Remove(config.Formatters.XmlFormatter);
      //在请求的Url加上 ?$format=xml,便可以指定响应格式
      config.Formatters.XmlFormatter.AddQueryStringMapping("$format","xml","application/xml");
      config.Formatters.JsonFormatter.AddQueryStringMapping("$format","json","application/json");
    }
  }

2、身份验证过滤器

  using DotNet.Business;
  using DotNet.Utilities;
  using DotNet.Tracking.API.Common;

  /// <summary>
  /// ApiAuthFilterAttribute
  /// 身份验证过滤器,具有ApiAuthFilterAttribute标签属性的方法会自动检查
  /// 
  /// 
  /// 修改纪录
  /// 
  /// 2016-10-11 版本:1.0 SongBiao 创建文件。  
  /// 
  /// <author>
  ///   <name>SongBiao</name>
  ///   <date>2016-10-11</date>
  /// </author>
  /// </summary>
  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,Inherited = true,AllowMultiple = true)]
  public class ApiAuthFilterAttribute : AuthorizationFilterAttribute
  {
    /// <summary>
    /// 未授权时的提示信息
    /// </summary>
    private const string UnauthorizedMessage = "请求未授权,拒绝访问。";

    /// <summary>
    /// 权限进入
    /// </summary>
    /// <param name="actionContext"></param>
    public override void OnAuthorization(HttpActionContext actionContext)
    {
      base.OnAuthorization(actionContext);
      // 允许匿名访问
      if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count > 0) 
      {
        return;
      }

      string systemCode = APIOperateContext.Current.SystemCode;
      string permissionCode = APIOperateContext.Current.PermissionCode;
      string appKey = APIOperateContext.Current.AppKey;
      string appSecret = APIOperateContext.Current.AppSecret;      
      if (string.IsNullOrWhiteSpace(appKey) || string.IsNullOrWhiteSpace(appSecret))
      {
        //未验证(登录)的用户,而且是非匿名访问,则转向登录页面 
        //actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
        //actionContext.Response.Content = new StringContent("<p>Unauthorized</p>",Encoding.UTF8,"text/html");
        var response = actionContext.Response= actionContext.Response?? new HttpResponseMessage();
        response.StatusCode = HttpStatusCode.Unauthorized;
        BaseResult result = new BaseResult
        {
          Status = false,StatusMessage = UnauthorizedMessage
        };
        response.Content = new StringContent(result.ToJson(),"application/json");
      }
      else
      {
        // 检查 AppKey 和 AppSecret
        BaseResult result = BaseServicesLicenseManager.CheckService(appKey,appSecret,false,systemCode,permissionCode);
        if (!result.Status)
        {
          var response = actionContext.Response = actionContext.Response?? new HttpResponseMessage();
          response.Content = new StringContent(result.ToJson(),"application/json");
        }
      }
           
    }
  }

3、统一回传格式

  /// <summary>
  /// ApiResultAttribute
  /// 统一回传格式
  /// 
  /// 修改纪录
  /// 
  /// 2016-10-31 版本:1.0 宋彪 创建文件。
  /// 
  /// <author>
  ///   <name>宋彪</name>
  ///   <date>2016-10-31</date>
  /// </author>
  /// </summary>
  public class ApiResultAttribute : ActionFilterAttribute
  {
    /// <summary>
    /// 重写回传的处理
    /// </summary>
    /// <param name="actionExecutedContext"></param>
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
      // 快件跟踪接口传的是format,不用走这里
      if (actionExecutedContext.Request.Properties.ContainsKey("format"))
      {
        // 若发生例外则不在这边处理 在异常中处理 ApiErrorHandleAttribute
        if (actionExecutedContext.Exception != null)
          return;
        base.OnActionExecuted(actionExecutedContext);
        var result = new ApiResultModel();
        // 取得由 API 返回的状态码
        result.Status = actionExecutedContext.ActionContext.Response.StatusCode;
        // 取得由 API 返回的资料
        result.Data = actionExecutedContext.ActionContext.Response.Content.ReadAsAsync<object>().Result;
        // 重新封装回传格式
        actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(result.Status,result);
      }
    }
  }

4、全局异常处理

  using DotNet.Utilities;
  using DotNet.Tracking.API.Common;
  using DotNet.Tracking.API.Controllers;
  using DotNet.Tracking.API.Models;

  /// <summary>
  /// ApiErrorHandleAttribute
  /// 全局异常处理
  /// 
  /// 修改纪录
  /// 
  /// 2016-10-31 版本:1.0 宋彪 创建文件。
  /// 
  /// <author>
  ///   <name>宋彪</name>
  ///   <date>2016-10-31</date>
  /// </author>
  /// </summary>

  public class ApiErrorHandleAttribute : System.Web.Http.Filters.ExceptionFilterAttribute
  {
    /// <summary>
    /// 异常统一处理
    /// </summary>
    /// <param name="actionExecutedContext"></param>
    public override void OnException(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
    {
      base.OnException(actionExecutedContext);
      // 取得发生例外时的错误讯息
      var errorMessage = actionExecutedContext.Exception.Message;

      // 异常记录
      string parameters = APIOperateContext.GetRequestParameters();
      NLogHelper.Trace(actionExecutedContext.Exception,BaseSystemInfo.SystemCode + " ApiErrorHandleAttribute OnException 完整的请求地址及参数 : " + parameters);
      // 2016-11-01 加入异常邮件提醒
      NLogHelper.InfoMail(actionExecutedContext.Exception,BaseSystemInfo.SystemCode + " ApiErrorHandleAttribute OnException 完整的请求地址及参数 : " + parameters);

      var result = new ApiResultModel()
      {
        Status = HttpStatusCode.BadRequest,ErrorMessage = errorMessage
      };
      // 重新打包回传的讯息
      actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(result.Status,result);
    }
  }

dawei

【声明】:唐山站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。