2012-06-29 166 views
61

有沒有一種方法可以爲WebApi要求SSL?屬性?在WebApi中需要SSL嗎?

我沒有看到適用的屬性System.Web.Http下,有點像RequireHttps屬性,我們可以對MVC。如果有內置的解決方案,我只是試圖避免滾動我自己的屬性/消息處理程序。

+0

這是關於這個問題的文章,值得一讀:https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/working-with-ssl-in-web-api – Tohid

回答

40

您可以使用WebAPIContrib項目中的RequireHttpsHandler。基本上,它的作用是檢查輸入的請求URI方案:

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

或者,卡洛斯菲蓋拉有another implementation在他的MSDN博客。

+1

謝謝。我想了很多,只是不想重新發明輪子。 – EBarr

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

就像一個參考,這個代碼使用的'ActionFilterAttribute'類在'System.Web.Http.Filters'中。它不是'System.Web.Mvc'中的'ActionFilterAttribute'類。 –

+4

對於那些想知道的問題,在添加這個地方之後,在類/動作上面添加'[RequireHttps]'。文檔:http://www.asp.net/web-api/overview/security/working-with-ssl-in-web-api – CularBytes

+0

我也使用這種方法。我見過很多使用'AuthorizationFilterAttribute'的例子。任何人爲什麼使用這個'ActionFilterAttribute'的原因? – Ollie

19

令人費解的是,ASP.NET Web API中沒有與ASP.NET MVC RequireHttps屬性等效的內容。不過,您可以根據MVC的RequireHttps輕鬆創建一個。

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"; 
    } 
} 

所有有剩下要做的就是爭論有多少冗餘代碼。

2

你可以使用下面的過濾器類來強制你的動作方法使用SSL,這將處理你的請求枯萎其GET方法或任何其他動詞,如果它的get方法將重定向瀏覽器(使用位置標題)到新的URI。 否則會顯示一條消息使用https

下面的代碼顯示您必須在從AuthorizationFilterAttribute繼承後重寫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"); 

      } 
} 
1

您可以使用下面的代碼; (自動重定向到https)在基於http的請求發出時重定向到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 
      var uriBuilder = new UriBuilder(actionContext.Request.RequestUri) 
      { 
       Scheme = Uri.UriSchemeHttps, 
       Port = 44353 // port used in visual studio for this 
      }; 

      actionContext.Response.Headers.Location = uriBuilder.Uri; 
     } 
    } 
} 

使用該註冊方法是這樣

config.Filters.Add(new RequireHttpsAttribute()); 
0

一些研究,我決定在這之後可能是最適當的反應。儘管規範指出Html是推薦的,但它可以被更新爲提供json,text或xml。

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