web-dev-qa-db-fra.com

Rediriger vers HTTPS

Quelle est la méthode recommandée pour rediriger vers HTTPS toutes les demandes entrantes qui ne sont pas sécurisées? Dois-je écrire un composant middleware? Si tel est le cas, je ne saurais pas comment obtenir le nom du serveur.

public class RedirectHttpMiddleware
{
    RequestDelegate _next;

    public RedirectHttpMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.IsSecure)
            await _next(context);
        else
        {
            var server = "";  // How do I get the server name?
            context.Response.Redirect("https://" + server + context.Request.Path);
        }
    }
}
34
William

Vous pouvez utiliser votre propre classe de middleware, mais généralement, je fais quelque chose comme ceci dans ma configuration de démarrage:

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps)
    {
        await next();
    }
    else
    {
        var withHttps = Uri.UriSchemeHttps + Uri.SchemeDelimiter + context.Request.Uri.GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Scheme, UriFormat.SafeUnescaped);
        context.Response.Redirect(withHttps);
    }
});

Cela consiste simplement à saisir l'URL entière, la chaîne de requête et tout, et à utiliser GetComponents pour obtenir tout sauf le schéma de l'URL. Ensuite, le schéma HTTPS est ajouté à l'URL des composants.

Cela fonctionnera avec le .NET Framework complet. Pour ASP.NET Core, vous pouvez faire quelque chose comme ceci:

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps)
    {
        await next();
    }
    else
    {
        var withHttps = "https://" + context.Request.Host + context.Request.Path;
        context.Response.Redirect(withHttps);
    }
});

Cela ajoute l'hôte et le chemin d'accès au schéma HTTPS. Vous voudrez peut-être ajouter d'autres composants tels que la requête et le hachage.

43
vcsjones

Pour .NET Core 2.0 et versions antérieures ( documents officiels pour 2.0 ):

Utilisez l'attribut/filtre [RequireHttps] . Vous pouvez le faire sur vos contrôleurs:

[RequireHttps]
public class AccountController {
}

Ou bien ajoutez ceci dans votre Startup.cs dans la méthode ConfigureServices:

services.Configure<MvcOptions>(options =>
{
    options.Filters.Add(new RequireHttpsAttribute());
}

En outre, je voulais juste ajouter que la réponse de vcsjones est également correcte, mais vous devez vous assurer d'ajouter ce code tôt dans votre configuration, avant tout autre code middleware/code générant des redirections. juste avant d’ajouter le middleware Identity Framework.

16
Josh Mouch

La réponse complète est au numéro 1, mais ne vous arrêtez pas là pour configurer HTTPS, passez à l'étape supplémentaire:

1 - Nous utilisons ensuite la variable RequireHttpsAttribute pour rediriger vers HTTPS et définir le port SSL dans les options MVC. Nous lisons également le port SSL de launchSettings.json mais nous n’avons besoin de cela qu’en mode Développement.

2 - Utilisez AddAntiforgery pour exiger HTTPS sur vos jetons anti-contrefaçon.

3 - Utilisez le package NWebsec.AspNetCore.Middleware NuGet et la méthode UseHsts pour activer la sécurité du transport strict (HSTS) sur le site. N'oubliez pas d'ajouter le préchargement ci-dessous et de soumettre votre site au HSTS Preload site . Plus d'informations ici et ici .

4 - Utilisez le package NWebsec.AspNetCore.Middleware NuGet et la méthode UseHpkp pour activer le repérage de clé publique (HPKP) sur le site. Notez que si vous faites une erreur avec celui-ci, vous faites essentiellement votre site. Plus d'informations ici et ici .

5 - Incluez le schéma https dans toutes les URL utilisées. Politique de sécurité du contenu (CSP) En-tête HTTP et Intégrité de la sous-source (SRI) ne joue pas bien lorsque vous imitez le schéma dans certains navigateurs. Il vaut mieux être explicite à propos de HTTPS. par exemple.

<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js"></script>

6- Utilisez le modèle de projet ASP.NET MVC Boilerplate Visual Studio pour générer un projet avec tout cela et bien plus intégré. Vous pouvez également afficher le code sur GitHub .

Après tout ce qui précède, votre classe Startup devrait ressembler à ceci:

public class Startup
{
    private readonly int? sslPort;

    public Startup(IHostingEnvironment hostingEnvironment)
    {
        if (hostingEnvironment.IsDevelopment())
        {
            var launchConfiguration = new ConfigurationBuilder()
                .SetBasePath(hostingEnvironment.ContentRootPath)
                .AddJsonFile(@"Properties\launchSettings.json")
                .Build();
            // During development we won't be using port 443.
            this.sslPort = launchConfiguration.GetValue<int>("iisSettings:iisExpress:sslPort");
        }
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddAntiforgery(options =>
            {
                options.RequireSsl = true;
            });
            .AddMvc(options =>
            {
                options.Filters.Add(new RequireHttpsAttribute());
                options.SslPort = sslPort;
            });
    }

    public void Configure(IApplicationBuilder application)
    {
        application
            .UseHsts(options => options.MaxAge(days: 18 * 7).IncludeSubdomains().Preload())
            .UseHpkp(options => options
                .Sha256Pins(
                    "Base64 encoded SHA-256 hash of your first certificate e.g. cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=",
                    "Base64 encoded SHA-256 hash of your second backup certificate e.g. M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE=")
                .MaxAge(days: 18 * 7)
                .IncludeSubdomains())
            .UseCsp(options => options
                .UpgradeInsecureRequests(this.sslPort.HasValue ? this.sslPort.Value : 443))
            .UseMvc();
    }
}
12

Si vous souhaitez récupérer le port lorsque vous vous trouvez dans un environnement DEV dans .NET Core, examinez env.IsDevelopment() et récupérez de manière conditionnelle le port SSL à partir de launchSettings.json.

if (env.IsDevelopment())
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile(@"Properties/launchSettings.json", optional: false, reloadOnChange: true);
    var launchConfig = builder.Build();
    sslPort = launchConfig.GetValue<int>("iisSettings:iisExpress:sslPort");
}

`

Après avoir saisi le port SSL, vous pouvez l'intégrer à la solution publiée par @vcsjones.

3
long2know

AlwaysHttpsMiddleware.cs, inspiré de Requiert HTTPHttps.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

public class AlwaysHttpsMiddleware
{
    private readonly RequestDelegate _next;

    public AlwaysHttpsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.IsHttps)
        {
            await _next.Invoke(context);
        }
        else
        {
            var request = context.Request;

            // only redirect for GET requests, otherwise the browser might
            // not propagate the verb and request body correctly.

            if (!string.Equals(request.Method, "GET", StringComparison.OrdinalIgnoreCase))
            {
                context.Response.StatusCode = StatusCodes.Status403Forbidden;
                await context.Response.WriteAsync("This site requires HTTPS.");
            }
            else
            {
                var newUrl = string.Concat(
                    "https://",
                    request.Host.ToUriComponent(),
                    request.PathBase.ToUriComponent(),
                    request.Path.ToUriComponent(),
                    request.QueryString.ToUriComponent());

                context.Response.Redirect(newUrl);
            }
        }
    }
}

Startup.cs

public void Configure(IApplicationBuilder app)
{
    if (_env.IsProduction())
    {
        app.UseMiddleware<AlwaysHttpsMiddleware>();
    }
 }
2
Shaun Luttin

Dans ASP.NET Core 2.1, utilisez simplement ceci:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();   // <-- Add this !!!!!
    }

    app.UseHttpsRedirection(); // <-- Add this !!!!!
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseMvc();
}
1
Yanga

Pour que votre application DOTNet Core s'exécute sous HTTPS, vous devez suivre trois étapes:

  1. Naviguez jusqu'au fichier launchSettings.json de votre application et entrez le port https de 44390 à 44399  enter image description here
  2. Editez votre fichier Startup.cs. Entrez le code suivant:

    services.Configure<MvcOptions>(options =>
    {
        options.SslPort = 44390;
        options.Filters.Add(new RequireHttpsAttribute());
    });
    

     enter image description here

  3. Cliquez avec le bouton droit sur votre répertoire racine du projet, à partir de l'explorateur de solutions, puis sélectionnez Propriétés. Cochez Activer SSL, copiez le lien SSL et ajoutez-le à la zone URL de l'application .  enter image description here

    1. Lancer l'application. Il fonctionnera toujours dans le contexte HTTPS.
0
Johnny

Il existe quelques bonnes réponses ici, mais j'avais besoin d'une solution qui fonctionnerait avec ou sans IIS et ne modifierait pas le protocole lors du débogage local. J'ai ajouté ceci juste après avoir ajouté l'authentification AD au pipeline dans la méthode Startup.Configure. Ceci est pour le cadre complet. Les autres solutions présentées ici expliquent comment reconstruire l'URL pour Core.

app.Use(async (context, next) =>
{
    if (context.Request.IsHttps || // Handles https straight to the server 
        context.Request.Headers["X-Forwarded-Proto"] == Uri.UriSchemeHttps || // Handles an IIS or Azure passthrough
        context.Request.Host.ToString().StartsWith("localhost",true, System.Globalization.CultureInfo.InvariantCulture) || // Ignore for localhost
        context.Request.Headers["X-Forwarded-Proto"].Contains( Uri.UriSchemeHttps )) // X-Forwarded-Proto can have multiple values if there are multiple proxies 
    {
        await next();
    }
    else
    {
        var withHttps = Uri.UriSchemeHttps + Uri.SchemeDelimiter + context.Request.Host + context.Request.Path + context.Request.QueryString;
        context.Response.Redirect(withHttps);
    }
});
0
EricksonG

Une technique décrite à l'adresse https://github.com/aspnet/KestrelHttpServer/issues/916 ajoute ceci à votre web.config:

<rewrite>
      <rules>
          <rule name="HTTP/S to HTTPS Redirect" enabled="true" stopProcessing="true">
          <match url="(.*)" />
          <conditions logicalGrouping="MatchAny">
              <add input="{SERVER_PORT_SECURE}" pattern="^0$" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_Host}/{R:1}" redirectType="Permanent" />
          </rule>
      </rules>
</rewrite>
0
SaltySub2