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项目的安全验证解决方案源码的详细内容...