在WebApi中需要SSL?


Answers:


46

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

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

另外,Carlos Figueira在他的MSDN博客上还有另一个实现


2
谢谢。我想尽可能多的,只是不想重新发明轮子,如果它是内置的。
EBarr

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

12
与FYI一样,ActionFilterAttribute此代码使用的类也位于中System.Web.Http.Filters。这不是中ActionFilterAttributeSystem.Web.Mvc
贾斯汀·赫尔格森2013年

5
对于那些想知道的人,将其添加到某处之后,添加[RequireHttps]到您的类/动作上方。文件:asp.net/web-api/overview/security/working-with-ssl-in-web-api
CularBytes

我也使用这种方法。我已经看到了许多使用“ AuthorizationFilterAttribute”的示例。人们为什么要在“ ActionFilterAttribute”上使用它?
奥利

3
这应该使用AuthorizationFilterAttribute,而不是ActionFilterAttribute。授权发生在管道中的较早位置,到您到达此处时,其他操作过滤器可能已经运行。参见CularBytes的链接
Mark Sowul '16

20

令人困惑的是,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

经过一些研究,我确定这可能是最适当的应对措施。尽管指定了建议使用Html,但可以将其更新为提供json,文本或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


1

您可以使用以下代码;(自动重定向到https)在发出基于http的请求时重定向到https。

要在Visual Studio中进行检查,您需要在Visual Studio中启用ssl。这可以通过将enable 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;
        }
    }
}

像这样在Register方法中使用

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

如果我将其部署在实时服务器上,那么提及端口号将无法使其正常工作;如果我忽略该端口号,它将在其中放置默认端口号。
Jamshaid K.

嗨,@ JamshaidKamran,您是否找到了此问题的解决方案,我也面临此问题
Simba,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.