優點是邏輯簡單明了、設置簡單。
缺點顯而易見,即使是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();
新聞熱點
疑難解答