zoukankan      html  css  js  c++  java
  • WebApi 身份认 Basic基础认证

    <body>
        <div style="text-align:center;"> 
            <div>用户名:<input type="text" id="txt_username" /></div>
            <div>密  码:<input type="password" id="txt_password"  /></div>
            <div><input type="button" value="登录" id="btn_login" class="btn-default" /></div>
        </div>
    </body>
    

      

    $(function () {
        $("#btn_login").click(function () {
            $.ajax({
                type: "get",
                url: "http://localhost:27221/api/User/Login",
                data: { strUser: $("#txt_username").val(), strPwd: $("#txt_password").val() },
                success: function (data, status) {
                    if (status == "success") {
                        if (!data.bRes){
                            alert("登录失败");
                            return;
                        }
                        alert("登录成功");
                //登录成功之后将用户名和用户票据带到主界面
                        window.location = "/Home/Index?UserName=" + data.UserName + "&Ticket=" + data.Ticket;
                    }
                },
                error: function (e) {
                },
                complete: function () {
    
                }
    
            });
        });
    });
    

      

    public class UserController : ApiController
        {
            /// <summary>
            /// 用户登录
            /// </summary>
            /// <param name="strUser"></param>
            /// <param name="strPwd"></param>
            /// <returns></returns>
            [HttpGet]
            public object Login(string strUser, string strPwd)
            {
                if (!ValidateUser(strUser, strPwd))
                {
                    return new { bRes = false };
                }
                FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(0, strUser, DateTime.Now,
                                DateTime.Now.AddHours(1), true, string.Format("{0}&{1}", strUser, strPwd),
                                FormsAuthentication.FormsCookiePath);
                //返回登录结果、用户信息、用户验证票据信息
                var oUser = new UserInfo { bRes = true, UserName = strUser, Password = strPwd, Ticket = FormsAuthentication.Encrypt(ticket) };
                //将身份信息保存在session中,验证当前请求是否是有效请求
                HttpContext.Current.Session[strUser] = oUser;
                return oUser;
            }
    
            //校验用户名密码(正式环境中应该是数据库校验)
            private bool ValidateUser(string strUser, string strPwd)
            {
                if (strUser == "admin" && strPwd == "123456")
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
    
        public class UserInfo
        {
            public bool bRes { get; set; }
    
            public string UserName { get; set; }
    
            public string Password { get; set; }
    
            public string Ticket { get; set; }
        }
    

      如何开启WebApi里面的Session,请参考:http://www.cnblogs.com/tinya/p/4563641.html

    正如上面的原理部分说的,登录如果失败,则直接返回;如果成功,则将生成的票据Ticket带到前端,传到主界面/Home/Index,下面,我们就来看看主界面Home/Index。

    public class HomeController : Controller
        {
            // GET: Home
            public ActionResult Index(string UserName, string Ticket)
            {
                ViewBag.UserName = UserName;
                ViewBag.Ticket = Ticket;
                return View();
            }
        }
    

      

    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Index</title>
        <script src="~/Content/jquery-1.9.1.js"></script>
        <link href="~/Content/bootstrap/css/bootstrap.css" rel="stylesheet" />
        <script src="~/Content/bootstrap/js/bootstrap.js"></script>
        <script src="~/Scripts/Home/Index.js"></script>
        <script type="text/javascript">
            //打开页面的时候保存票据信息
            var UserName = '@ViewBag.UserName';
            var Ticket = '@ViewBag.Ticket';
        </script>
    </head>
    <body>
        <div>当前登录用户:'@ViewBag.UserName'</div>
    
        <div id="div_test">
    
        </div>
    </body>
    </html>
    

      

    $(function () {
        $.ajax({
            type: "get",
            url: "http://localhost:27221/api/Charging/GetAllChargingData",
            data: {},
            beforeSend: function (XHR) {
                //发送ajax请求之前向http的head里面加入验证信息
                XHR.setRequestHeader('Authorization', 'BasicAuth ' + Ticket);
            },
            success: function (data, status) {
                if (status == "success") {
                    $("#div_test").html(data);
                }
            },
            error: function (e) {
                $("#div_test").html("Error");
            },
            complete: function () {
    
            }
    
        });
    });
    

      继承我们的AuthorizeAttribute这个类。然后重写OnAuthorization方法,在这个方法里面取到请求头的Ticket信息,然后校验用户名密码是否合理。

    /// <summary>
        /// 自定义此特性用于接口的身份验证
        /// </summary>
        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<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
                    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;
                }
            }
        }
    

      

    [RequestAuthorize]
        public class ChargingController : ApiController
        {
            /// <summary>
            /// 得到所有数据
            /// </summary>
            /// <returns>返回数据</returns>
            [HttpGet]
            public string GetAllChargingData()
            {
                return "Success";
            }
    
            /// <summary>
            /// 得到当前Id的所有数据
            /// </summary>
            /// <param name="id">参数Id</param>
            /// <returns>返回数据</returns>
            [HttpGet]
            public string GetAllChargingData(string id)
            {
                return "ChargingData" + id;
            }
    
        }
    

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

    优化

    namespace WebApiCORS.Controllers
    {
        [RequestAuthorize]
        [EnableCors(origins: "*", headers: "*", methods: "*")]
        public class BaseApiController : ApiController
        {
        }
    }
    

      

    namespace WebApiCORS.Controllers
    {
        public class ChargingController : BaseApiController
        {
            /// <summary>
            /// 得到所有数据
            /// </summary>
            /// <returns>返回数据</returns>
            [HttpGet]
            public string GetAllChargingData()
            {
                return "Success";
            }
    
            /// <summary>
            /// 得到当前Id的所有数据
            /// </summary>
            /// <param name="id">参数Id</param>
            /// <returns>返回数据</returns>
            [HttpGet]
            public string GetAllChargingData(string id)
            {
                return "ChargingData" + id;
            }
      }
    }
    

      解决ajax的问题

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

    (function ($) {
        //1.得到$.ajax的对象
        var _ajax = $.ajax;
        $.ajax = function (options) {
            //2.每次调用发送ajax请求的时候定义默认的error处理方法
            var fn = {
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    toastr.error(XMLHttpRequest.responseText, '错误消息', { closeButton: true, timeOut: 0, positionClass: 'toast-top-full-width' });
                },
                success: function (data, textStatus) { },
                beforeSend: function (XHR) { },
                complete: function (XHR, TS) { }
            }
            //3.扩展原生的$.ajax方法,返回最新的参数
            var _options = $.extend({}, {
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    fn.error(XMLHttpRequest, textStatus, errorThrown);
                },
                success: function (data, textStatus) {
                    fn.success(data, textStatus);
                },
                beforeSend: function (XHR) {
                    XHR.setRequestHeader('Authorization', 'BasicAuth ' + Ticket);
                    fn.beforeSend(XHR);
                },
                complete: function (XHR, TS) {
                    fn.complete(XHR, TS);
                }
            }, options);
            //4.将最新的参数传回ajax对象
            _ajax(_options);
        };
    })(jQuery);
    

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

    public class ChargingController : BaseApiController
        {
            /// <summary>
            /// 得到所有数据
            /// </summary>
            /// <returns>返回数据</returns>
            [HttpGet]
            public string GetAllChargingData()
            {
                return "Success";
            }
    
            /// <summary>
            /// 得到当前Id的所有数据
            /// </summary>
            /// <param name="id">参数Id</param>
            /// <returns>返回数据</returns>
            [HttpGet]
            [AllowAnonymous]
            public string GetAllChargingData(string id)
            {
                return "ChargingData" + id;
            }
      }
    

      

  • 相关阅读:
    第05组 Alpha冲刺(2/4)
    Alpha冲刺(1/4)
    第04组 Beta冲刺(4/4)
    第04组 Beta冲刺(3/4)
    第04组 Beta冲刺(2/4)
    第04组 Beta冲刺(1)
    第04组 Alpha事后诸葛亮
    第04组 Alpha冲刺(4/4)
    第04组 Alpha冲刺(3/4)
    第04组 Alpha冲刺(2/4)
  • 原文地址:https://www.cnblogs.com/xiangxiong/p/6796695.html
Copyright © 2011-2022 走看看