HTTPS Redirection

Force HTTP traffic to upgrade to HTTPS with a configurable redirect status code and optional explicit HTTPS port.

The middleware issues a redirect (default 307) when a client hits an HTTP listener while a secure listener is also configured.

Aspect Default Notes
Status Code 307 Temporary Redirect Can be set to 301 / 302 / 308; use 301/308 only once confident (permanent caching)
HTTPS Port Inferred (443) Specify when running on a custom dev port (e.g. 5443)
Certificate Not created automatically Use New-KrSelfSignedCertificate for local dev or import a real cert

Permanent (301/308) redirects are cacheable by browsers and intermediaries—during development prefer 307/302.

Full source

File: pwsh/tutorial/examples/10.3-Https-Redirection.ps1

<#
    Create a self-signed development certificate and start HTTPS listener.
    FileName: 10.3-Https-Redirection.ps1
#>
param(
    [int]$Port = 5000,
    [IPAddress]$IPAddress = [IPAddress]::Loopback
)

# Initialize Kestrun root directory
Initialize-KrRoot -Path $PSScriptRoot

# Configure default logging
New-KrLogger |
    Set-KrLoggerLevel -Value Debug |
    Add-KrSinkConsole |
    Register-KrLogger -Name 'myLogger' -SetAsDefault

# Create a self-signed cert for localhost (RSA 2048 by default)
$cert = New-KrSelfSignedCertificate -DnsNames localhost, 127.0.0.1 -Exportable -ValidDays 30


# Configure HTTPS listener with the certificate
New-KrServer -Name "HTTPS Redirection Demo"
Add-KrEndpoint -Port ($Port) -IPAddress $IPAddress
Add-KrEndpoint -Port ($Port + 443) -IPAddress $IPAddress -X509Certificate $cert

Add-KrHttpsRedirection -RedirectStatusCode 301 -HttpsPort ($Port + 443)

# Enable Kestrun configuration
Enable-KrConfiguration

# Minimal route to verify HTTPS redirect works
Add-KrMapRoute -Verbs Get -Pattern "/" -ScriptBlock { Write-KrTextResponse "hello https" }

Start-KrServer

# Clean up and close all the loggers when the server stops
Close-KrLogger

Step-by-step

  1. Two endpoints are registered: an HTTP listener (e.g. http://localhost:5000) and an HTTPS listener (e.g. https://localhost:5443).
  2. Add-KrHttpsRedirection wires ASP.NET Core’s HTTPS policy middleware.
  3. Incoming HTTP requests receive a redirect response with the configured status code and target HTTPS URL.
  4. Normal route handling proceeds only on the HTTPS endpoint.

Configuration Examples

Minimal (accept default 307 + inferred HTTPS port):

Add-KrHttpsRedirection

Explicit permanent redirect to custom port:

Add-KrHttpsRedirection -RedirectStatusCode 308 -HttpsPort 5443

Using an options object (advanced):

$options = [Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionOptions]::new()
$options.RedirectStatusCode = 301
$options.HttpsPort = 5001
Add-KrHttpsRedirection -Options $options

Try it

Run the sample (spawns both listeners):

pwsh .\docs\_includes\examples\pwsh\10.3-Https-Redirection.ps1 -Port 5000

Test redirect behavior (PowerShell):

# Expect 301/302/307/308 with Location header pointing to HTTPS
try {
  Invoke-WebRequest -Uri 'http://localhost:5000/' -UseBasicParsing -MaximumRedirection 0 -ErrorAction Stop
} catch {
  $_.Exception.Response.StatusCode.value__    # redirect status
  $_.Exception.Response.Headers['Location']   # target URL
}

# Follow redirect automatically
Invoke-RestMethod -Uri 'http://localhost:5000/' -SkipCertificateCheck

Curl variant:

curl -I http://localhost:5000/

Security Notes

Concern Guidance
Mixed Content Always redirect early before body writes to prevent mixed HTTP/HTTPS usage.
Status Code Choice 307/302 preserve method; 301/308 may be cached long-term.
HSTS (Strict Transport Security) Not enabled automatically. Consider adding a response header once stable: Strict-Transport-Security: max-age=31536000; includeSubDomains
Self-Signed Dev Certs Accept locally with -SkipCertificateCheck during development only.

Troubleshooting

Symptom Cause Fix
Redirect loops Incorrect port mapping or proxy rewriting scheme Ensure HTTPS listener is reachable and reverse proxy sets X-Forwarded-Proto correctly
Not redirecting Middleware not added or only HTTPS endpoint defined Add both HTTP and HTTPS endpoints before Add-KrHttpsRedirection
Wrong port in Location Missing -HttpsPort when using a non-standard HTTPS port Supply -HttpsPort (e.g. 5443)
Browser warning Self-signed cert in dev Import trust locally or ignore for dev only

References


Previous / Next

Previous: Response Compression Next: Rate Limiting (planned)