好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

ASP.NET开发WEBAPI项目的安全验证解决方案源码

1、搭好WEBAPI框架,建立一个验证特性类、产品实体类与登录验证返回实体类

1.1、首先定好验证规则(账号+密码用&分隔),创建一个特性过滤器,以Attribute结尾并继承“AuthorizeAttribute”,类中要引用“System.Web.Http”与“System.Web.Security”命名空间,类的名称用“RequestAuthorizeAttribute(请求授权属性)”

 C#源码如下:

    //创建一个特性 以Attribute结尾的都是特性

    //什么是特性,特性是可以直接加到类或方法的上边 ,加入方法如:[RequestAuthorizeAttribute]

    //特性加在类上,对类影响,加在方法上对方法影响

    //特性类继承AuthorizeAttribute(身份验证的授权管理器)

    //也叫过滤器

    public class RequestAuthorizeAttribute:AuthorizeAttribute

    {

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

        public override void OnAuthorization(HttpActionContext actionContext)

        {

            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);

                }

            }

            else

            {

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

                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);

            strUser = strTicket.Split('&')[0];

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

            strPwd = strTicket.Split('&')[1];

            if(strUser.Equals("admin") && strPwd.Equals("123"))

            {

                return true;

            }

            else

            {

                return false;

            }

        }

    }

1.2、建立一个产品列表的实体类,源码如下:

    public class Product

    {

        public int Pid { get; set; }

        public string PName { get; set; }

    }

1.3、建立一个用户登录结果返回的实体类,源码如下:

    public class HdhCmsUserResult

    {

        public string UName { get; set; }

        public string UPwd { get; set; }

        public bool HdhCmsRequest { get; set; } //是否登录成功!

        public string Ticket { get; set; } //身份验证的票据

    }


2、用户登录向服务器提交请求,服务器验证成功要生成Ticket,然后把Ticket返回给客户端,如果登录成功则加上Ticket参数跳转到产品的列表页,如果失败则提示登录失败

2.1、服务器WEBAPI控制HdhCmsLogin的验证及返回源码

        public object GetHdhCmsUserPwd(string UName,string UPwd)

        {

            if(UName.Equals("admin")&& UPwd.Equals("123"))

            {

                //生成票据

                FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(0, UName, DateTime.Now

                    ,DateTime.Now.AddHours(1), true, string.Format("{0}&{1}", UName, UPwd)

                    ,FormsAuthentication.FormsCookiePath);

                HdhCmsUserResult user = new  HdhCmsUserResult{ HdhCmsRequest = true, UName = UName, UPwd = UPwd, Ticket = FormsAuthentication.Encrypt(ticket) };

                return user;

            }

            else

            {

                return new { HdhCmsRequest = false };

            }

        }


2.2、客户端登录界面及请求源码:

@{

    Layout = null;

}

<!DOCTYPE html>

<html>

<head>

    <meta name="viewport" content="width=device-width" />

    <title>Index</title>

    <script src="~/Scripts/jquery-3.4.1.min.js"></script>

    <script>

        function HdhCmsLogin() {

            var UName = $("#UName").val();

            var UPwd = $("#UPwd").val();

            $.ajax({

                url: "/api/HdhCmsLogin",

                type: "get",

                data: { UName: UName, UPwd: UPwd },

                success: function (result) {

                    if (result.BRes == true) {

                        alert("登录成功!" + result.Ticket);

                        location.href = "/home/HdhCmsMain?ticket=" + result.Ticket;

                    } else {

                        alert("登录失败!");

                    }

                }

            })

        }

    </script>

</head>

<body>

    <div>

        帐号:<input type="text" id="UName" /><br />

        密码:<input type="password" id="UPwd" /><br />

        <input type="button" value="登录" onclick="HdhCmsLogin()" />

    </div>

</body>

</html>

3、在产品列表页向产品列表的WEBAPI控制器请求获取产品数据,在发送请求之前在要请求的头部设置“Authorization”参数,值用Ticket,用于在获取数据之前根据创建的特性类对权限进行验证,如果验证通过则返回产品列表,如果不通过则不返回。

3.1、产品列表(MVC控制器为Home,Action为HdhCmsMain),控制器中ACTION源码为:

        public ActionResult HdhCmsMain(string ticket)

        {

            ViewBag.ticket = ticket;

            return View();

        }

3.2、产品列表(MVC控制器为Home,Action为HdhCmsMain),控制器中视图源码为:

  

@{

    Layout = null;

}

<!DOCTYPE html>

<html>

<head>

    <meta name="viewport" content="width=device-width" />

    <title>Main</title>

    <script src="~/Scripts/jquery-3.4.1.min.js"></script>

    <script>

        var ticket = "@ViewBag.ticket";

        $.ajax({

            url: "/api/HdhCmsProduct",

            type: "get",

            beforeSend: function (XHR) {

                //发送ajax请求之前向http的head里面加入验证信息,记住BasicAuth右边一定要留一个空格,否则特性类在验证时“authorization.Parameter”将取不到参数,验证永远不成功

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

            },

            success: function (result) {

                alert(result.length);

                for (var i = 0; i < result.length; i++) {

                    $("<tr><td>" + result[i].PName + "</td></tr>").appendTo($("#tablePro"));

                }

            }

        })

    </script>

</head>

<body>

    <div>

        <div id="divMain"><table id="tablePro"><tr><th>产品名</th></tr></table></div>

    </div>

</body>

</html>

3.3、产品列表的WebApi控制器(文件名为:HdhCmsProductController.cs)源码为:

using System.Collections.Generic;

using System.Web.Http;

using HdhCmsWebApiAttributeTest.Models;


namespace HdhCmsWebApiAttributeTest.Controllers

{

    [RequestAuthorizeAttribute]

    public class ProductController : ApiController

    {

        //创建实体类的泛型集合,模拟集合数据

        List<Product> lstHdhCms = new List<Product>

        {

            new Product{ Pid=1,PName="花生"},

            new Product{ Pid=2,PName="瓜子"}

        };

        //GET请求返回数据

        public IEnumerable<Product> GetHdhCmsProduct()

        {

            return lstHdhCms;

        }

    }

}



查看更多关于ASP.NET开发WEBAPI项目的安全验证解决方案源码的详细内容...

  阅读:56次