WebApi常见的实现方式有:FORM身份验证、集成WINDOWS验证、Basic基础认证、Digest摘要认证
个人偏好Basic基础认证,而且支持跨域,下面详解这种方式。
1.定义一个自定义属性类(BasicAuthorizeAttribute)继承自AuthorizationFilterAttribute:
public class BasicAuthorizeAttribute : AuthorizationFilterAttribute { public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext) { //如果用户使用了forms authentication,就不必在做basic authentication了 if (Thread.CurrentPrincipal.Identity.IsAuthenticated) { return; } var url = actionContext.Request.RequestUri.AbsoluteUri; //var secretkey = actionContext.Request.RequestUri; var secretUrl = url.Split(new string[] { "key=" }, StringSplitOptions.RemoveEmptyEntries)[0].TrimEnd('&'); if (url.Contains('?')) { var queryValue = url.Split('?')[1]; if (!string.IsNullOrEmpty(queryValue) && !string.IsNullOrEmpty(secretUrl)) { var key = ""; var values = queryValue.Split('&'); foreach (var item in values) { var keyValue = item.Split('='); if (keyValue[0] == "key") { key = keyValue[1]; break; } } if (!string.IsNullOrEmpty(key) && key == EncryptHelper.GetEncryptKey(secretUrl)) { return; } } } HandleUnauthorizedRequest(actionContext); } private void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext) { actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "访问未经授权!", "application/json"); } }
2.在需要认证授权后才能访问的Controller中类或ACTION方法上添加上述定义的类BasicAuthorizeAttribute,也可在global文件中将该类添加到全局过滤器中,即可
3.配置配置Basic基础认证
public static class WebApiConfig { public static void Register(HttpConfiguration config) { //// Web API 配置和服务 //// 将 Web API 配置为仅使用不记名令牌身份验证。 //config.SuppressDefaultHostAuthentication(); //config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); //配置Unity依赖注入容器 config.DependencyResolver = new UnityResolver(UnityConfig.GetConfiguredContainer()); //配置Basic基础认证 config.Filters.Add(new BasicAuthorizeAttribute()); // Web API 路由 config.MapHttpAttributeRoutes(); //1.默认路由 config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional }, constraints: new { id = @"d*" } //约束,这个表示匹配0个或多个数字 //constraints: new { id = @"d+" } //正则d+表示匹配一个或多个数字 ); } }