.net web api 权限验证

做一个登录权限验证。

开始吧。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Security;
using Game.Web.Models;

namespace Game.Web.ApiControllers
{
    [Authorize.APIAuthorize]
    [RoutePrefix("api/home")]
    public class HomeController : BaseController
    {
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <returns></returns>
        [Route("loginUser"), HttpPost, AllowAnonymous]
        public AjaxJsonResult LoginUser(UserInfo info)
        {
            AjaxJsonResult ajax = new AjaxJsonResult() { code = (int)CodeStatus.NoLogin, msg = ajax.GetEnumDescription(CodeStatus.NoLogin) };
            try
            {
                //调用登录方法
                UserInfo _info = new UserInfo()
                {
                    UserName = "aaa",
                    PassWord = "123"
                };
                if (_info.UserName == info.UserName && _info.PassWord == info.PassWord)
                {
                    //登录成功,添加票证
                    FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
                        1
                        , $"UserToken"
                        , DateTime.Now
                        , DateTime.Now.AddMinutes(60)
                        , false
                        , $"{info.UserName}:{info.PassWord}"
                        , HttpContext.Current.Request.UserHostAddress);
                    string ticStr = FormsAuthentication.Encrypt(ticket);
                    ajax.code = (int)Models.CodeStatus.OK; ajax.msg = "登入成功!";
                }
                else
                {
                    ajax.msg = "登入失败!";
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("登录报错!", ex);
            }
            return ajax;
        }
    }
}

AllowAnonymous 特性 ,不需要验证

LogHelper 静态方法,这里用了Log4,进行错误日志记录,网上有自己百度哦。

这里只是简单的加入了票证,其实可以把它再加密成Token放到Response的Headers里面,具体这么操作自行百度吧。

登录成功后下面就是用API接口获取List数据拉。

不过在获取前,我们需要进行权限验证。using Game.Facade;

using Game.Utils.Cache;
using Game.Web.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Security;

namespace Game.Web.Authorize
{
    /// <summary>
    /// web api 权限验证
    /// </summary>
    public class APIAuthorize : AuthorizeAttribute
    {
        private HttpContext _context { get; set; }

        /// <summary>
        /// 管理员权限验证
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        public override void OnAuthorization(HttpActionContext httpContext)
        {
            //获取用户票证
            if (ValidateTicket(httpContext))
            {
                base.IsAuthorized(httpContext);
            }
            else
            {
                HandleUnauthorizedRequest(httpContext);
            }
        }

        /// <summary>
        /// 处理授权失败的 HTTP 请求。
        /// </summary>
        /// <param name="filterContext">封装用于 System.Web.Mvc.AuthorizeAttribute 的信息。 filterContext 对象包括控制器、HTTP 上下文、请求上下文、操作结果和路由数据。</param>
        protected override void HandleUnauthorizedRequest(HttpActionContext httpContext)
        {
            if (httpContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any() ||
             httpContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
            {
                return;
            }
            base.HandleUnauthorizedRequest(httpContext);
            var response = httpContext.Response = httpContext.Response ?? new HttpResponseMessage();
            response.StatusCode = HttpStatusCode.Forbidden;
            var ajax = new AjaxJson
            {
                code = (int)CodeStatus.NoAuthorization,
                msg = AjaxJson.GetEnumDescription(CodeStatus.NoAuthorization),
            };
            response.Content = new StringContent(ajax.SerializeToJson(), Encoding.UTF8, "application/json");
        }

        /// <summary>
        /// 验证用户票证
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        private bool ValidateTicket(HttpActionContext httpContext)
        {
            var res = false;
            //获取HttpContext
            dynamic ctx = httpContext.Request.Properties["MS_HttpContext"];
            if (ctx != null)
            {
                var ticObject = WHCache.Default.Get<CookiesCache>(FormsAuthentication.FormsCookieName);
                if (ticObject != null)
                {
                    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(ticObject.ToString());
                    if (!ticket.Expired && ticket.CookiePath == ctx.Request.UserHostAddress)
                    {
               //这里只是做了简单的获取到了票证,并且票证未有效和IP地址是否一致,进一步优化可以做到验证用户信息等。
               //如果没有登录,肯定是没有获取到票证的。
res
= true; } } } return res; } } }
using System;
using System.Web.Http;
using Game.Web.Models;

namespace Game.Web.ApiControllers
{
    [Authorize.APIAuthorize]
    [RoutePrefix("api/home")]
    public class HomeController : BaseController
    {
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <returns></returns>
        [Route("list"), HttpPost, AllowAnonymous]
        public AjaxJsonResult List(UserInfo info)
        {
            AjaxJsonResult ajax = new AjaxJsonResult() {  };
            try
            {
                //假装成功并返回了我们想要的数据,哈哈。
            }
            catch (Exception ex)
            {
                LogHelper.Error("获取报错!", ex);
            }
            return ajax;
        }
    }
}

再分享一下Json的返回格式吧。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using System.Web;

namespace Game.Web.Models
{
    /// <summary>
    /// Api返回类
    /// </summary>
    public class AjaxJsonResult
    {
        #region 属性
        /// <summary>
        /// 状态码
        /// </summary>
        public int code { get; set; }

        /// <summary>
        /// 消息
        /// </summary>
        public string msg { get; set; }

        /// <summary>
        /// 返回数据
        /// </summary>
        public object data { get; set; }

        /// <summary>
        /// 总行数
        /// </summary>
        public object count { get; set; }
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        public AjaxJsonResult()
        {
            code = (int)CodeStatus.OK;
            msg = string.Empty;
            data = "";
            count = string.Empty;
        }
        #endregion
    }

    /// <summary>
    /// 接口状态码
    /// </summary>
    public enum CodeStatus
    {
        #region 操作返回码
        /// <summary>
        /// 成功
        /// </summary>
        [Description("成功")]
        OK = 0,

        /// <summary>
        /// 失败
        /// </summary>
        [Description("失败")]
        Error = -1,

        #region 登录返回码
        /// <summary>
        /// 请先登陆
        /// </summary>
        [Description("请重新登陆")]
        NoLogin = -100,

        /// <summary>
        /// 密码不能为空
        /// </summary>
        [Description("密码不能为空")]
        NotPassEmtry = -101,

        /// <summary>
        /// 验证码错误
        /// </summary>
        [Description("验证码错误")]
        VerifyCodeError = -102,

        [Description("未授权,请重新登录")]
        NoAuthorization = -103,
        #endregion

        /// <summary>
        /// 其他
        /// </summary>
        [Description("其他")]
        EveryThing = -10000,
    }
}

以上就是我的Web API简单登录权限验证。

然后Web MVC 的登录权限验证,其实和这个也差不多,请看我的另一篇。

 https://www.cnblogs.com/nnnnnn/p/10923262.html

posted @ 2019-05-25 17:46  听海漫步  阅读(1458)  评论(0编辑  收藏  举报