OnAuthorize(string userName, string userPassword, HttpActionContext actionContext) { if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(userPassword)) return false; ; }
var principal = new GenericPrincipal(identity, null); Thread.CurrentPrincipal = principal; //下面是针对ASP.NET而设置 //if (HttpContext.Current != null) // HttpContext.Current.User = principal;
第三步一切已经就绪,此时在重写方法中进行相应的调用即可,如下:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class BasicAuthenticationFilter : AuthorizationFilterAttribute { OnAuthorization(HttpActionContext actionContext) { var userIdentity = ParseHeader(actionContext); if (userIdentity == null) { Challenge(actionContext); return; } if (!OnAuthorize(userIdentity.Name, userIdentity.Password, actionContext)) { Challenge(actionContext); return; } var principal = new GenericPrincipal(userIdentity, null); Thread.CurrentPrincipal = principal; base.OnAuthorization(actionContext); }
第四步自定义 CustomBasicAuthenticationFilter 并继承于 BasicAuthenticationFilter ,重写其虚方法。
public class CustomBasicAuthenticationFilter : BasicAuthenticationFilter { OnAuthorize(string userName, string userPassword, HttpActionContext actionContext) { && userPassword == ) return true; ; } }
最后一步注册自定义认证特性并进行调用
config.Filters.Add(new CustomBasicAuthenticationFilter()); [CustomBasicAuthenticationFilter] public class ProductController : ApiController {....}
至此对于其认证方式就已经完全实现,接下来我们通过【搜狗浏览器】来验收我们的成果。
看到如下认证其用户名和密码的图片,我们知道我们成功了一半
我们点击取消,观察是否返回401并添加质询头即WWW-Authenticate,如我们所料
我们输入正确的用户名和密码再试试看,结果认证成功,如下:
我们知道HttpMessageHandler是Web API中请求-响应中的消息处理管道的重要角色,但是真正实现管道串联的是DelegatingHandler,若你不懂Web API消息管道,请参考前面系列文章,所以我们可以自定义管道来进行拦截通过继承DelegatingHandler。下面我们一步步来实现基于此管道的认证。
第一步和第一种方法一致不再叙述。
第二步这一步当然是自定义管道进行处理并继承DelegatingHandler,重载在此类中的SendAsync方法,通过获得其请求并处理从而进行响应,若不懂此类中的具体实现,请参看前面系列文章。
public virtual BasicAuthenticationIdentity ParseHeader(HttpRequestMessage requestMessage) { string authParameter = null; var authValue = requestMessage.Headers.Authorization; ) authParameter = authValue.Parameter; if (string.IsNullOrEmpty(authParameter)) return null; authParameter = Encoding.Default.GetString(Convert.FromBase64String(authParameter)); ); if (authToken.Length < 2) return null; return new BasicAuthenticationIdentity(authToken[0], authToken[1]); }
void Challenge(HttpRequestMessage request,HttpResponseMessage response) { var host = request.RequestUri.DnsSafeHost; response.Headers.Add(authenticationHeader, , host)); }