Требовать SSL в WebApi?

Есть ли способ потребовать SSL для WebApi? Атрибут?

Я не вижу применимого атрибута в System.Web.Http, что-то вроде атрибута RequireHttps, который у нас есть для MVC. Я просто пытаюсь избежать перетаскивания собственного обработчика атрибута/сообщения, если есть встроенное решение.

Ответ 1

Вы можете использовать RequireHttpsHandler из проекта WebAPIContrib. В основном, все, что он делает, это проверить схему URI входящего запроса:

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

В качестве альтернативы, Карлос Фигейра другой реализации в своем блоге MSDN.

Ответ 2

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

Ответ 3

Непонятно, что нет эквивалента атрибуту ASP.NET MVC RequireHttps в ASP.NET Web API. Однако вы можете легко создать его на основе RequireHttps из MVC.

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

Все, что осталось сделать, - это аргументировать, сколько избыточного кода существует.

Ответ 4

вы можете использовать следующий класс фильтра, чтобы заставить ваш метод действий использовать SSL, это будет обрабатывать ваш запрос wither его метод GET или любой другой глагол, если его метод get перенаправляет браузер (используя заголовок местоположения) к новому URI. В противном случае будет показано сообщение с использованием https

Ниже код показывает, что вы должны переопределить метод OnAuthorization после наследования из AuthorizationFilterAttribute.

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

            }
}

Ответ 5

Вы можете использовать следующий код; (автоматически перенаправлять на https) перенаправлять на https, когда делается запрос на основе http.

Чтобы проверить это в visual studio, вам нужно включить ssl в visual studio. Это можно сделать, используя свойство 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());

Ответ 6

После некоторых исследований я определил, что это, вероятно, самый подходящий ответ. Он может быть обновлен, чтобы обеспечить json, text или xml, несмотря на то, что спецификация указывает, что рекомендуется 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