原文:Web APi之认证(Authentication)两种实现方法【二】(十三)
前言
上一节我们详细讲解了认证及其根基信息,这一节我们通过两种差别方法来实现认证,并且分析如何合理的操作这两种方法,文中涉及到的根本常识,请参看上一篇文中,就不再叙述空话。
序言对付所谓的认证说到底就是安适问题,在Web API中有多种方法来实现安适,【accepted】方法来措置惩罚惩罚基于IIS的安适(通过上节提到的WindowsIdentity依赖于HttpContext和IIS认证)或者在Web API里通过使用Web API中的动静措置惩罚惩罚机制,但是如果我们想应用措施运行在IIS之外此时Windows Idenitity这一方法似乎就不太可能了,同时在Web API中自己就未供给如何措置惩罚惩罚认证的直接方法,我们不得不自界说来实现认证成果,同时这也是我们所保举的方法,本身动手,人给家足。
温馨提示:下面实现要领皆基于根本认证,若不熟悉Http协议中的Basic根本认证,请先参看此篇文章【园友海鸟-介绍Basic根本认证和Digest摘要认证】。 无论何种方法,对付我们的应用措施我们都需要在业务层使用基于凭证的用户认证,因为是客户端一方的需求,所以客户端需要明确根本验证,根本认证(Basic)非常简单并且撑持任何Web客户端,但是根本验证的错误谬误是不安适,通过使用SSL则可以进行加密就可以在必然水平上保证了安适,如果是对付一般的应用措施通过根本认证只是进行编码而未加密也可以说是安适的。我们还是看看上一节所给图片通过上述图片的大略信息我们可以看出在请求到Action要领之间要颠末Web API动静措置惩罚惩罚管道,在请求到方针元素之前要颠末HttpMessageHandler和认证过滤器,所以我们可以通过这两者来自界说实现认证。下面我们一一来看。
基于Web API的认证过滤器(AuthorizationFilterAttribute)实现认证 第一步我们自界说一个认证身份(用户名和暗码)的类,那么此类必需也就要担任于 GenericIdentity ,既然是基于根本验证,那么类型固然也就是Basic了。
public class BasicAuthenticationIdentity : GenericIdentity { public string Password { get; set; } public BasicAuthenticationIdentity(string name, string password) : base(name, "Basic") { this.Password = password; } }
第二步我们要自界说一个认证过滤器特性,并担任 AuthorizationFilterAttribute ,此时会酿成如下:
public class BasicAuthenticationFilter : AuthorizationFilterAttribute { public override void OnAuthorization(HttpActionContext actionContext) {} }
那么在这个重写的要领我们应该写什么呢?我们慢慢来分析!请往下看。
解析请求报文头
首先对付客户端发送过来的请求我们必定是需要获得请求报头,然后解析请求报头中的Authorization,若此时其参数为空,我们将返回到客户端,并倡议质询。string authParameter = null; var authValue = actionContext.Request.Headers.Authorization; //actionContext:Action要领请求上下文 if (authValue != null && authValue.Scheme == "Basic") authParameter = authValue.Parameter; //authparameter:获取请求中颠末Base64编码的(用户:暗码) if (string.IsNullOrEmpty(authParameter)) return null;
次之,若此时认证中的参数不为空并开始对其进行解码,并返回一个BasicAuthenticationIdentity东西,若此时东西为空,则同样返回到客户端,并倡议质询authParameter = Encoding.Default.GetString(Convert.FromBase64String(authParameter)); //对编码的参数进行解码 var authToken = authParameter.Split(‘:‘); //解码后的参数格局为(用户名:暗码)将其进行支解 if (authToken.Length < 2) return null; return new BasicAuthenticationIdentity(authToken[0], authToken[1]); //将支解的用户名和暗码通报给此类结构函数进行初始化
最后,我们将上述两者封装为一个ParseHeader要领以便进行挪用public virtual BasicAuthenticationIdentity ParseHeader(HttpActionContext actionContext) { string authParameter = null; var authValue = actionContext.Request.Headers.Authorization; if (authValue != null && authValue.Scheme == "Basic") authParameter = authValue.Parameter; if (string.IsNullOrEmpty(authParameter)) return null; authParameter = Encoding.Default.GetString(Convert.FromBase64String(authParameter)); var authToken = authParameter.Split(‘:‘); if (authToken.Length < 2) return null; return new BasicAuthenticationIdentity(authToken[0], authToken[1]); }
接下来我们将认证未通过而需要倡议认证质询,我们将其封装为一个要领Challenge