无论是MVC或者是WebAPI安全验证一般都踩用过滤器,这里我们采用一个自定义过滤器来实现WebAPI调用前的安全验证;
示例如下:
实体类-
1.产品类:
namespace WebSecurityDemo.Models
{
public class Product
{
public int PId { get; set; }
public string PName { get; set; }
}
}
2.用户信息类:
namespace WebSecurityDemo.Models
{
public class UserInfo
{
/// <summary>
/// 用户名
/// </summary>
public string UName { get; set; }
/// <summary>
/// 密码
/// </summary>
public string UPwd { get; set; }
/// <summary>
/// 验证结果
/// </summary>
public bool BRes { get; set; }
/// <summary>
/// 票据=由用户名和密码经过加密生成的字符串
/// </summary>
public string Ticket { get; set; }
}
}
3.验证信息类
using System.Linq;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Security;
namespace WebSecurityDemo.Models
{
public class RequestAuthorizeAttribute:AuthorizeAttribute
{
//重写基类的验证方式,加入我们自定义的Ticket验证
public override void OnAuthorization(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);
}
}
else //如果获取不到身份验证信息,并且不允许匿名访问,则返回未验证401
{
var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
bool isAnoymouse = attributes.Any(a => a is AllowAnonymousAttribute);
if (isAnoymouse) 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 == "123")
{
return true;
}
else
{ return false; }
}
}
}
控制器
1.MVC控制器
using System.Web.Mvc;
namespace WebSecurityDemo.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Title = "Home Page";
return View();
}
public ActionResult Main(string ticket)
{
ViewBag.ticket = ticket;
return View();
}
}
}
2.WebAPI控制器
using System;
using System.Web.Http;
using System.Web.Security;
using WebSecurityDemo.Models;
namespace WebSecurityDemo.Controllers
{
public class UserInfoController : ApiController
{
public object GetLogin(string UName, string Pwd)
{
if (UName == "admin" && Pwd == "123")
{
//根据用户名和密码生成票据信息
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(0, UName, DateTime.Now, DateTime.Now.AddHours(1), true, string.Format("{0}&{1}", UName, Pwd),FormsAuthentication.FormsCookiePath);
UserInfo user = new UserInfo { BRes = true, UName = UName, UPwd = Pwd, Ticket = FormsAuthentication.Encrypt(ticket) };
return user;
}
else
{
return new { BRes = false };
}
}
}
}
using System.Collections.Generic;
using System.Web.Http;
using WebSecurityDemo.Models;
namespace WebSecurityDemo.Controllers
{
[RequestAuthorizeAttribute]
public class ProductController : ApiController
{
List<Product> lst = new List<Product> {
new Product{PId=1,PName="钢笔"},
new Product{ PId=2,PName="篮球"},
new Product{ PId=3,PName="足球"}
};
public IEnumerable<Product> GetProduct()
{
return lst;
}
}
}
视图:
@{
ViewBag.Title = "Index";
}
@section Scripts{
<script>
$(document).ready(function () {
});
function Login() {
$.ajax({
type: "get",
url: "/api/UserInfo",
data: { UName: $("#UName").val(), Pwd:$("#Pwd").val() },
success: function (obj) {
if (obj.BRes == true) {
alert("登录成功!");
location.href = "/Home/Main?ticket=" + obj.Ticket;
} else {
alert("登录失败!");
}
}
});
}
</script>
}
@section Body{
<div class="panel panel-group">
<div class="panel panel-heading">
<label class="label label-info">登录认证</label>
</div>
<div class="panel panel-body">
<table class="table table-condensed">
<tr>
<td>用户名:</td>
<td><input id="UName" type="text" /></td>
</tr>
<tr>
<td>密码:</td>
<td><input id="Pwd" type="password" /></td>
</tr>
<tr>
<td colspan="2"><button id="Login" onclick="Login()" class="btn btn-xs btn-primary">登录</button></td>
</tr>
</table>
</div>
</div>
}
@{
ViewBag.Title = "Main";
}
@section Scripts{
<script>
var ticket ='@ViewBag.ticket';
$.ajax({
type: "get",
url: "/api/Product",
beforeSend: function (XHR) {
//发送ajax请求之前向http的head里面加入验证信息
XHR.setRequestHeader("Authorization", "BasicAuth " + ticket);
},
success: function (obj) {
for (var i = 0; i < obj.length; i++) {
$("<tr><td>"+(i+1)+"</td><td>" + obj[i].PName + "</td></tr>").appendTo("#tabPro");
}
// alert(JSON.stringify(obj));
},
error: function (e) {
$("#devMain").html("Error");
}
});
</script>
}
@section Body{
<div id="divMain">
<table id="tabPro" class="table table-striped table-condensed" >
<tr>
<td>编号</td><td>产品名</td>
</tr>
</table>
</div>
}