在WebApi中需要SSL?

有没有办法要求WebApi的SSL? 一个属性?

我没有在System.Web.Http下看到一个适用的属性,就像我们对MVC的RequireHttps属性。 我只是试图避免滚动我自己的属性/消息处理程序,如果有一个内置的解决scheme。

您可以使用WebAPIContrib项目中的RequireHttpsHandler 。 基本上,它所做的只是检查传入的请求URIscheme:

 if (request.RequestUri.Scheme != Uri.UriSchemeHttps) { // Forbidden (or do a redirect)... } 

另外,卡洛斯菲盖拉在他的MSDN博客上有另一个实现 。

 public class RequireHttpsAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps) { actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden); } } } 

令人费解的是ASP.NET Web API中没有ASP.NET MVC RequireHttps属性。 不过,您可以根据MVC的RequireHttps轻松创build一个。

 using System; using System.Net.Http; using System.Web.Http.Controllers; using System.Web.Http.Filters; ... public class RequireHttpsAttribute : AuthorizationFilterAttribute { public override void OnAuthorization(HttpActionContext actionContext) { if (actionContext == null) { throw new ArgumentNullException("actionContext"); } if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps) { HandleNonHttpsRequest(actionContext); } else { base.OnAuthorization(actionContext); } } protected virtual void HandleNonHttpsRequest(HttpActionContext actionContext) { actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden); actionContext.Response.ReasonPhrase = "SSL Required"; } } 

所有剩下的事情就是争论有多less冗余的代码。

您可以使用以下filter类来强制您的操作方法使用SSL,这将处理您的请求枯萎其GET方法或任何其他动词,如果其get方法,它将redirect浏览器(使用位置标头)到新的URI。 否则,会显示一条消息使用https

下面的代码显示了你必须在从AuthorizationFilterAttributeinheritance之后重写OnAuthorization方法。

  string _HtmlBody = string.Empty; UriBuilder httpsNewUri; var _Request = actionContext.Request; if (_Request.RequestUri.Scheme != Uri.UriSchemeHttps ) { _HtmlBody = "<p>Https is required</p>"; if (_Request.Method.Method == "GET"){ actionContext.Response = _Request.CreateResponse(HttpStatusCode.Found); actionContext.Response.Content = new StringContent(_HtmlBody, Encoding.UTF8, "text/html"); httpsNewUri = new UriBuilder(_Request.RequestUri); httpsNewUri.Scheme = Uri.UriSchemeHttps; httpsNewUri.Port = 443; //To ask a web browser to load a different web page with the same URI but different scheme and port actionContext.Response.Headers.Location = httpsNewUri.Uri; }else{ actionContext.Response = _Request.CreateResponse(HttpStatusCode.NotFound); actionContext.Response.Content = new StringContent(_HtmlBody, Encoding.UTF8, "text/html"); } } 

你可以使用下面的代码; (自动redirect到https)在基于http的请求发出时redirect到https。

要在visual studio中检查它,你需要在visual studio中启用ssl。 这可以使用启用SSL属性为true来完成。

 public class RequireHttpsAttribute: AuthorizationFilterAttribute { public override void OnAuthorization(HttpActionContext actionContext) { if(actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps){ // constructing the https url UriBuilder uriBuilder = new UriBuilder(actionContext.Request.RequestUri); uriBuilder.Scheme = Uri.UriSchemeHttps; uriBuilder.Port = 44353 // port used in visual studio for this actionContext.Response.Headers.Location = uriBuilder.Uri; } } } 

像这样在Register方法中使用这个

 config.Filter.Add(new RequireHttpsAttribute()); 

经过一番研究,我确定这可能是最恰当的回应。 它可以被更新以提供json,text或xml,尽pipe规范指示Html被推荐。

 public class RequireHttpsAttribute : AuthorizationFilterAttribute { public override void OnAuthorization(HttpActionContext context) { if (context.Request.RequestUri.Scheme != Uri.UriSchemeHttps) { context.Response = new HttpResponseMessage(HttpStatusCode.UpgradeRequired); context.Response.Headers.Add("Upgrade", "TLS/1.1, HTTP/1.1"); context.Response.Headers.Add("Connection", "Upgrade"); context.Response.Headers.Remove("Content-Type"); context.Response.Headers.Add("Content-Type", "text/html"); context.Response.Content = new StringContent("<html><head></head><body><h1>Http protocol is not valid for this service call.</h1><h3>Please use the secure protocol https.</h3></body></html>"); } else base.OnAuthorization(context); } } 

这里是规范: RFC 2817