打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
WebApi身份认证解决方案(1):Basic基础认证(下)


来源:赖的安分

链接:http://www.cnblogs.com/landeanfen/p/5287064.html


3、WebApiCORS验证部分(重点)


我们看到,上面的/Home/Index页面里面发送了ajax请求去访问服务的 http://localhost:27221/api/Charging/GetAllChargingData 这个接口,那么我们在WebApi里面怎么去验证这个请求和合法的请求呢?接下来我们重点看看验证的这个过程。


3.1、在WebApiCORS项目里面自定义一个类RequestAuthorizeAttribute,去继承我们的AuthorizeAttribute这个类。然后重写OnAuthorization方法,在这个方法里面取到请求头的Ticket信息,然后校验用户名密码是否合理。


    ///

    /// 自定义此特性用于接口的身份验证

    ///

    public class RequestAuthorizeAttribute : AuthorizeAttribute

    {

        //重写基类的验证方式,加入我们自定义的Ticket验证

        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)

        {

            //从http请求的头里面获取身份验证信息,验证是否是请求发起方的ticket

            var authorization = actionContext.Request.Headers.Authorization;

            if ((authorization != null) & (authorization.Parameter != null))

            {

                //解密用户ticket,并校验用户名密码是否匹配

                var encryptTicket = authorization.Parameter;

                if (ValidateTicket(encryptTicket))

                {

                    base.IsAuthorized(actionContext);

                }

                else

                {

                    HandleUnauthorizedRequest(actionContext);

                }

            }

            //如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401

            else

            {

                var attributes = actionContext.ActionDescriptor.GetCustomAttributes().OfType();

                bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);

                if (isAnonymous) base.OnAuthorization(actionContext);

                else HandleUnauthorizedRequest(actionContext);

            }

        }

        //校验用户名密码(正式环境中应该是数据库校验)

        private bool ValidateTicket(string encryptTicket)

        {

            //解密Ticket

            var strTicket = FormsAuthentication.Decrypt(encryptTicket).UserData;

 

            //从Ticket里面获取用户名和密码

            var index = strTicket.IndexOf('&');

            string strUser = strTicket.Substring(0, index);

            string strPwd = strTicket.Substring(index + 1);

 

            if (strUser == 'admin' & strPwd == '123456')

            {

                return true;

            }

            else

            {

                return false;

            }

        }

    }


3.2、在具体的Api接口增加我们上面自定义类的特性


[RequestAuthorize]

    public class ChargingController : ApiController

    {

        ///

        /// 得到所有数据

        ///

        /// 返回数据

        [HttpGet]

        public string GetAllChargingData()

        {

            return 'Success';

        }

 

        ///

        /// 得到当前Id的所有数据

        ///

        /// 参数Id

        /// 返回数据

        [HttpGet]

        public string GetAllChargingData(string id)

        {

            return 'ChargingData' + id;

        }

    }


增加了特性标注之后,每次请求这个API里面的接口之前,程序会先进入到我们override过的 OnAuthorization() 方法里面,验证通过之后,才会进到相应的方法里面去执行,否则返回401。


四、优化


通过上面的几步,基本就能达到我们想要的身份认证的效果,但是总是感觉不太方便,主要不太方便的点有以下几个。


  1. 每次新建一个API,对应的接口上面都要标注 [RequestAuthorize] 这个一个东西,感觉好麻烦。


  2. 每次发送ajax请求,都要在beforeSend事件里面加 XHR.setRequestHeader(‘Authorization’, ‘BasicAuth ‘ + Ticket); 这个,感觉也麻烦。


  3. 如果有些WebApi服务的某些方法,我们不想使用这个验证,让它可以匿名用户验证(比如我们的登录方法Login)。该怎么处理呢。


关于以上两点,我们优化下


1、解决API的问题


在API里面加一个公共的父类,在父类上面标注 [RequestAuthorize] 即可。


namespace WebApiCORS.Controllers

{

    [RequestAuthorize]

    [EnableCors(origins'*', headers'*', methods'*')]

    public class BaseApiController : ApiController

    {

    }

}


namespace WebApiCORS.Controllers

{

    public class ChargingController : BaseApiController

    {

        ///

        /// 得到所有数据

        ///

        /// 返回数据

        [HttpGet]

        public string GetAllChargingData()

        {

            return 'Success';

        }

 

        ///

        /// 得到当前Id的所有数据

        ///

        /// 参数Id

        /// 返回数据

        [HttpGet]

        public string GetAllChargingData(string id)

        {

            return 'ChargingData' + id;

        }

  }

}


注意:我们登录的请求是不需要验证的,因为登录的时候还没有产生票据,所以登录的API不能够继承 BaseApiController


2、解决ajax的问题


还记得我们在 JS组件系列——封装自己的JS组件,你也可以 这篇里面介绍的增加ajax的error事件的公共处理方法吗?我们是否也可以通过同样的机制去增加这个呢。新建一个文件Jquery_ajax_extention.js


(function ($) {

    //1.得到$.ajax的对象

    var _ajax = $.ajax;

    $.ajax = function (options) {

        //2.每次调用发送ajax请求的时候定义默认的error处理方法

        var fn = {

            errorfunction (XMLHttpRequest, textStatus, errorThrown) {

                toastr.error(XMLHttpRequest.responseText, '错误消息', { closeButtontrue, timeOut0, positionClass'toast-top-full-width' });

            },

            successfunction (data, textStatus) { },

            beforeSendfunction (XHR) { },

            completefunction (XHR, TS) { }

        }

        //3.扩展原生的$.ajax方法,返回最新的参数

        var _options = $.extend({}, {

            errorfunction (XMLHttpRequest, textStatus, errorThrown) {

                fn.error(XMLHttpRequest, textStatus, errorThrown);

            },

            successfunction (data, textStatus) {

                fn.success(data, textStatus);

            },

            beforeSendfunction (XHR) {

                XHR.setRequestHeader('Authorization', 'BasicAuth ' + Ticket);

                fn.beforeSend(XHR);

            },

            completefunction (XHR, TS) {

                fn.complete(XHR, TS);

            }

        }, options);

        //4.将最新的参数传回ajax对象

        _ajax(_options);

    };

})(jQuery);


引用这个js后再发送ajax不必在每个请求的beforeSend里面写了。


3、解决特殊不想使用验证的方法


如果我们某些方法不想使用验证,使得它可以让匿名用户访问,我们可以在方法的上面加特性标注 [AllowAnonymous] ,申明该方法运行匿名访问。比如:


public class ChargingController : BaseApiController

    {

        ///

        /// 得到所有数据

        ///

        /// 返回数据

        [HttpGet]

        public string GetAllChargingData()

        {

            return 'Success';

        }

 

        ///

        /// 得到当前Id的所有数据

        ///

        /// 参数Id

        /// 返回数据

        [HttpGet]

        [AllowAnonymous]

        public string GetAllChargingData(string id)

        {

            return 'ChargingData' + id;

        }

  }


五、总结


以上结合一个实例讲解了下Basic认证的实现原理以及简单使用,本文观点都是来自博主自己的理解。


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C# webApi
WebAPI+NLog实现接口调用日志输出
WebAPi接口安全之公钥私钥加密
C#实现JWT无状态验证的实战应用
.NET WebAPI 用ActionFilterAttribute实现token令牌验证与对Action的权限控制
ajax+asp.net+mssql无刷新聊天室
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服