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

2019-05-25 16:44:58于海丽

项目中有一个留言消息接口,接收其他系统的留言和展示留言,参考了网上的一些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(), Encoding.UTF8, "application/json");
      }
      else
      {
        // 检查 AppKey 和 AppSecret
        BaseResult result = BaseServicesLicenseManager.CheckService(appKey, appSecret, false, 0, 0, systemCode, permissionCode);
        if (!result.Status)
        {
          var response = actionContext.Response = actionContext.Response?? new HttpResponseMessage();
          response.Content = new StringContent(result.ToJson(), Encoding.UTF8, "application/json");
        }
      }
           
    }
  }