優點是邏輯簡單明了、設置簡單。
缺點顯而易見,即使是BASE64后也是可見的明文,很容易被破解、非法利用,使用HTTPS是一個解決方案。
還有就是HTTP是無狀態的,同一客戶端每次都需要驗證。
?
實現:
客戶端在用戶輸入用戶名及密碼后,將用戶名及密碼以BASE64加密,加密后的密文將附加于請求信息中,如當用戶名為Parry,密碼為123456時,客戶端將用戶名和密碼用":"合并,并將合并后的字符串用BASE64加密,并于每次請求數據時,將密文附加于請求頭(Request Header)中。
HTTP服務器在每次收到請求包后,根據協議取得客戶端附加的用戶信息(BASE64加密的用戶名和密碼),解開請求包,對用戶名及密碼進行驗證,如果用戶名及密碼正確,則根據客戶端請求,返回客戶端所需要的數據;否則,返回錯誤代碼或重新要求客戶端提供用戶名及密碼。?
自定義屬性HTTPBasicAuthorize?,繼承AuthorizeAttribute,并實現兩個方法:OnAuthorization和HandleUnauthorizedRequest。
public class HTTPBasicAuthorizeAttribute : System.Web.Http.AuthorizeAttribute{public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext){if (actionContext.Request.Headers.Authorization != null){//對客戶端進行BASE64后的字符串再解碼string userInfo = Encoding.Default.GetString(Convert.FromBase64String(actionContext.Request.Headers.Authorization.Parameter));//用戶驗證邏輯if (string.Equals(userInfo, string.Format("{0}:{1}", "Parry", "123456"))){IsAuthorized(actionContext);}else{HandleUnauthorizedRequest(actionContext);}}else{HandleUnauthorizedRequest(actionContext);}} //或不重寫OnAuthorization,對IsAuthorized方法重寫protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext){if (actionContext.Request.Method == HttpMethod.Options)return true;if (actionContext.Request.Headers.Authorization != null && actionContext.Request.Headers.Authorization.Parameter != null) { // System.Web.Security.FormsAuthentication.var userdata= System.Text.Encoding.Default.GetString(Convert.FromBase64String(actionContext.Request.Headers.Authorization.Parameter));if (userdata.Equals(String.Format("{0}:{1}", "tzy", "123"))) {return true;//base.IsAuthorized(actionContext); }}return false;// return base.IsAuthorized(actionContext); }protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext){var challengeMessage = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);challengeMessage.Headers.Add("WWW-Authenticate", "Basic");throw new System.Web.Http.HttpResponseException(challengeMessage);}}
這些代碼值得注意的地方及說明
1.??if?(actionContext.Request.Method ==?HttpMethod.Options)?? 這個判斷是在進行跨域訪問時瀏覽器會發起一個Options請求去試探這個請求,但是他不會帶著data參數和一些header參數,所以認證肯定沒法通過導致無法繼續進行,所以給他直接認證通過。(對非跨域的則沒有影響)
2.對Authorization.Parameter 的解密,這里的解析跟登陸成功之后返回的Token 加密方式相同就行 這里采用的是Basic認證方式(簡單的64位字符串)
3.HandleUnauthorizedRequest方法 這里因為是繼承重寫的AuthorizeAttribute,在IsAuthorized 返回False的時候會執行這個方法
這里是返回一個401的錯誤信息
4.challengeMessage.Headers.Add("WWW-Authenticate","Basic"); ??這句代碼指示瀏覽器 認證方式為Basic 然后瀏覽器自動彈出一個登陸窗口并以basic 的方式 加密后每次通過header 傳輸到服務器進行認證然后得到授權
在需要驗證的Controller的類加上[HTTPBasicAuthorize]屬性,即可對當前控制器下的所有方法實現基本身份認證
?然后我習慣更改一下api的路由? 就改了一下routeTemplate 加入/{action}
public static void Register(HttpConfiguration config){// Web API configuration and services// Web API routes config.MapHttpAttributeRoutes();// config.Filters.Add(new AuthorizeAttribute()); config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{action}/{id}",defaults: new { id = RouteParameter.Optional });}
如果以webapi里面有xml?方式返回,更改formatter 如下
protected void Application_Start(){GlobalConfiguration.Configure(WebApiConfig.Register);GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();}
?
https://www.cnblogs.com/leo_wl/p/3553385.html
Basic Authentication
具體做法:創建一個filter繼承自AuthorizationFilterAttribute,重寫OnAuthorization來實現我們的需求。
原理是:客戶端在發送Http請求的時候在Header部分提供一個基于Base64編碼的用戶名和密碼,形式為“username:password”,消息接收者(服務器)進行驗證,通過后繼續處理請求。
1.從請求Header中獲取校驗數據
2.判斷驗證信息類型為“basic”并包含base64編碼
3.將base64編碼轉化為string,并提取用戶名和密碼
4.校驗提供的驗證信息是否與訪問的資源信息相同(學生的詳細信息只能由他自己訪問)
5.去數據庫校驗用戶名及密碼
6.如果校驗通過,則設置Thread的CurrentPrincipal,使本次接下來的請求都是通過校驗的。
7.校驗沒通過,返回401(Unauthorized)并添加一個WWW-Authenticate響應頭