1:Home/index.cshtml下面的Html代碼
<div>
<input value="1點擊先登陸" type="button" id="btnLogin"/><br />
<input value="2再點擊授權后調用接口" type="button" id="btnAuthenrazation" /><br />
</div>
2:Home/index 下面的HomeController
[skipLogAttribute] public ActionResult Index() { return View(); }
3: Ajax的模擬代碼,先登錄,后獲取授權,再帶上Ticket,后台過濾器校驗ok雜可以請求對應的接口
<script type="text/javascript">
$(function () {
var ticket = "";
$("#btnLogin").click(function () { //---登陸的操作
$.ajax({
url: "http://localhost:8899/api/values",
data: { "uid": "zrf", "pwd": "123" },
type: "get",
success: function (res) {
if (res.result) {
ticket = res.ticket;
alert("授權成功"+res.ticket);
}
},
dataType:"json"
})
});
//----拿到了Ticket(后台過濾器會判斷是否有過授權,以及授權ok才可以調用對應的接口)
$("#btnAuthenrazation").click(function () {
$.ajax({
url: "http://localhost:8899/api/values",
data: { },
type: "get",
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'BasicAuth ' + ticket);//--請求其他的接口都需要帶上Ticket的
},
success: function (res) {
alert("ok")
}
})
});
})
//帶上Ticket來訪問WebApi接口
$("#btnWithTicket").click(function () {
$.ajax({
url: "http://localhost:8899/api/values",
data: {"id":110},
type: "get",
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'BasicAuth ' + ticket);//--請求其他的接口都需要帶上Ticket的
},
success: function (res) {
if (res.result) {
alert("調用成功" + res.data);
}
}
})
})
4: 創建的一個測試的 WebApiController 如ValuesController:ApiController
namespace WebApplication1.Controllers
{
using System.Web.Security;
using WebApplication1.Filters;
public class ValuesController : ApiController
{
[HttpGet]
[skipLog]
public dynamic Login(string uid, string pwd)
{
dynamic result = null;
if ("zrf".Equals(uid) && pwd.Equals("123"))
{
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "account", DateTime.Now, DateTime.Now.AddSeconds(10), true, $"uid={uid},pwd={pwd}");
result = new { result = true, ticket = FormsAuthentication.Encrypt(ticket) };
}
else {
result = new { result = false, ticket = ""};
}
return result;
}
// GET api/<controller>
[skipLogAttribute]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<controller>/5
[CustomerAuthenrazationFilter]
public dynamic Get(int id)
{
return new { result = true, id = id };
}
}
}
5:授權過濾器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebApplication1.Filters
{
using System.Net.Http.Headers;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Web.Security;
using System.Web.Http;
using System.Net;
public class CustomerAuthenrazationFilterAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
skipLogAttribute skiplogin = actionContext.ActionDescriptor.GetCustomAttributes<skipLogAttribute>().FirstOrDefault();
if (skiplogin!=null)
{
return;
}
AuthenticationHeaderValue headevalue = actionContext.Request.Headers.Authorization;
if (headevalue != null)
{
string Msg = string.Empty;
if (ValidateTicket(headevalue.Parameter,out Msg))
{
return;
}
else
{
this.HandlerUnAuthorization(Msg);
}
}
else {
this.HandlerUnAuthorization("請先獲取登陸授權的Ticket");
}
}
private void HandlerUnAuthorization(string Msg)
{
throw new Exception(Msg);
}
private bool ValidateTicket(string parameter,out string Msg)
{
Msg = string.Empty;
if (!string.IsNullOrWhiteSpace(parameter))
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(parameter);
if (ticket != null)
{
if (ticket.Expired)
{
Msg = "接口時間已經過期,請重新登陸授權!";
return false;
}
if (string.Equals($"uid=zrf,pwd=123", ticket.UserData))// $"uid={accountID},pwd={pwd}"
{
Msg = "授權成功!";
return true;
}
else {
Msg = "授權失敗,請重新登陸授權!";
return false;
}
}
}
return false;
}
}
}
6:自定義的特性,用來跳過權限的驗證
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebApplication1.Filters
{
public class skipLogAttribute:Attribute
{
}
}
7:在WebApiConfig 文件中來注冊一個全局的授權過濾器
namespace WebApplication1.App_Start
{
using System.Web.Mvc;
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服務
// Web API 路由
config.MapHttpAttributeRoutes();
config.Filters.Add(new Filters.CustomerAuthenrazationFilterAttribute());
}
}
}
8:最后上兩張測試的截圖:


最后,這個案例只是起到拋磚引玉的作用,大家還可以做得更加的細致及合理
如下:
我們還可以加上隨機字符串:A;
時間戳:B(時間精確到秒,方便后續判斷,可過期);
唯一的uid C;
pwd D(根據uid來查詢數據庫並獲取到pwd),;
獲取自定義的簽名Sign:(如:uid+A+B+C+D 這4個值再MD5一下,防篡改),這樣就和微信那套機制就差不多了! 嘻嘻!
規則我們自己來定,歡迎大家提出有建議性的回復,謝謝
