2012-06-29 18 views
61

WebApiにSSLを要求する方法はありますか?属性?WebApiでSSLが必要ですか?

System.Web.Httpの下に該当する属性がありません。これはMVC用に持っているRequireHttps属性のようなものです。私は、ソリューションが組み込まれている場合は、自分の属性/メッセージハンドラをロールバックしないようにしようとしています。

+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)... 
} 

代わりに、カルロス・フィゲイラは彼のMSDNブログでanother implementationを持っています。

+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

FYIと同様に、このコードが使用する '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でsslを有効にする必要があります。 enable ssl propertyを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

関連する問題