diff --git a/.vscode/settings.json b/.vscode/settings.json index a1fff093..4428a17d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,7 @@ "appsettings", "Blazor", "docfx", + "Gorouter", "LastExitCode", "steeltoe", "tanzu" diff --git a/docs/docs/v4/configuration/cloud-foundry-provider.md b/docs/docs/v4/configuration/cloud-foundry-provider.md index d6c3e2e2..1a9208c8 100644 --- a/docs/docs/v4/configuration/cloud-foundry-provider.md +++ b/docs/docs/v4/configuration/cloud-foundry-provider.md @@ -118,3 +118,23 @@ public class HomeController( } } ``` + +### Reverse‑Proxy and Forwarded Headers Support + +Cloud Foundry places applications behind a reverse‑proxy (the **Gorouter**), which forwards client IP, protocol, and other metadata using HTTP headers like `X‑Forwarded‑For` and `X‑Forwarded‑Proto`. + +When an application that uses the Cloud Foundry configuration provider is running on Cloud Foundry, it sets the ASP.NET Core `ASPNETCORE_FORWARDEDHEADERS_ENABLED` switch to `true`, so that ASP.NET Core's Forwarded Headers Middleware is enabled and configured to trust the proxy headers found in Cloud Foundry environments. + +Review the [documentation for configuration ASP.NET Core to work with a reverse proxy](https://learn.microsoft.com/aspnet/core/host-and-deploy/proxy-load-balancer#forward-the-scheme-for-linux-and-non-iis-reverse-proxies) to learn more. + +#### Customizing ForwardedHeadersOptions + +`ForwardedHeadersOptions` is configured using the [Options Pattern](https://learn.microsoft.com/aspnet/core/fundamentals/configuration/options), for example, in `Program.cs`: + +```csharp +builder.Services.Configure(options => +{ + options.ForwardedHeaders |= ForwardedHeaders.XForwardedHost; + options.KnownProxies.Add(IPAddress.Parse("10.0.0.5")); // your internal proxy +}); +``` diff --git a/docs/docs/v4/security/certificate.md b/docs/docs/v4/security/certificate.md index 112887a7..582bdf01 100644 --- a/docs/docs/v4/security/certificate.md +++ b/docs/docs/v4/security/certificate.md @@ -14,6 +14,7 @@ To use this provider, the following steps are required: 1. Add and use the security provider in the application. 1. Secure your endpoints. 1. Attach certificate to requests to secured endpoints. +1. (Optional) Add support for additional intermediate certificate authorities. ### Add NuGet Reference @@ -101,10 +102,14 @@ To activate certificate-based authorization in the request pipeline, use the `Us ```csharp var app = builder.Build(); -// Steeltoe: Use certificate and header forwarding along with ASP.NET Core Authentication and Authorization middleware +// Steeltoe: Use certificate forwarding along with ASP.NET Core Authentication and Authorization middleware app.UseCertificateAuthorization(); ``` +> [!NOTE] +> This feature requires the application to be compatible with reverse-proxy scenarios, such as when running on Cloud Foundry. +> [Reverse-proxy support is automatically configured by the configuration provider for Cloud Foundry](../configuration/cloud-foundry-provider.md#reverseproxy-and-forwarded-headers-support). + ### Securing Endpoints > [!NOTE] @@ -174,3 +179,40 @@ builder.Services.AddHttpClient().AddAppInstanceIdentityCertifi ``` This method has an overload that changes the name of the HTTP header used to pass the certificate. For example: `.AddAppInstanceIdentityCertificate("X-Custom-Certificate-Header")`. + +### Customizing CertificateAuthenticationOptions + +In some scenarios (particularly when running applications across Linux and Windows cells in Cloud Foundry), you may encounter issues where instance identity certificates are not trusted, even though they are properly issued. +This usually happens because the identity certificates are signed by different intermediate certificates, depending on the operating system. + +If the intermediate certificate from one environment is not included in the trust store of the other, authentication can fail with errors, such as: + +```text +Certificate validation failed... NotSignatureValid The signature of the certificate cannot be verified. +``` + +To resolve this, you can manually extract the intermediate certificate from a trusted identity certificate, export it to a .crt file, and then configure `CertificateAuthenticationOptions` to include it. + +1. Extract the identity certificate: + + ```shell + cf ssh your-app-name + cat /etc/cf-instance-credentials/instance.crt + ``` + +1. Copy everything from the second `-----BEGIN CERTIFICATE-----` to the ending `-----END CERTIFICATE-----` and save it all in a separate file (such as `intermediate.crt`) + +1. Now that you have the intermediate certificate as its own .crt file, configure CertificateAuthenticationOptions to include it during the certificate chain validation: + + ```csharp + using System.Security.Cryptography.X509Certificates; + using Microsoft.AspNetCore.Authentication; + + builder.Services + .AddAuthentication() + .AddCertificate(options => + { + X509Certificate2 certificate = new X509Certificate2("intermediate.crt"); + options.AdditionalChainCertificates.Add(certificate); + }); + ``` diff --git a/docs/docs/v4/security/jwt-bearer.md b/docs/docs/v4/security/jwt-bearer.md index 72f0a512..54ad8077 100644 --- a/docs/docs/v4/security/jwt-bearer.md +++ b/docs/docs/v4/security/jwt-bearer.md @@ -112,8 +112,6 @@ Activate authentication and authorization services _after_ routing services, but ```csharp var app = builder.Build(); -app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedHost | ForwardedHeaders.XForwardedProto }); - app.UseRouting(); app.UseAuthentication(); @@ -125,7 +123,8 @@ app.Run(); ``` > [!NOTE] -> In this sample code, `app.UseForwardedHeaders` is used so that any links generated within the application are compatible with reverse-proxy scenarios, such as when running in Cloud Foundry. +> This feature requires the application to be compatible with reverse-proxy scenarios, such as when running in Cloud Foundry. +> [Reverse-proxy support is automatically configured by the configuration provider for Cloud Foundry](../configuration/cloud-foundry-provider.md#reverseproxy-and-forwarded-headers-support). ### Securing Endpoints diff --git a/docs/docs/v4/security/sso-open-id.md b/docs/docs/v4/security/sso-open-id.md index 101b7938..c6448b8c 100644 --- a/docs/docs/v4/security/sso-open-id.md +++ b/docs/docs/v4/security/sso-open-id.md @@ -126,8 +126,6 @@ using Microsoft.AspNetCore.HttpOverrides; var app = builder.Build(); -app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedHost | ForwardedHeaders.XForwardedProto }); - app.UseRouting(); app.UseAuthentication(); @@ -139,7 +137,8 @@ app.Run(); ``` > [!NOTE] -> In the sample code above, `app.UseForwardedHeaders` is used so that any links generated within the application are compatible with reverse-proxy scenarios, such as when running in Cloud Foundry. +> This feature requires the application to be compatible with reverse-proxy scenarios, such as when running on Cloud Foundry. +> [Reverse-proxy support is automatically configured by the configuration provider for Cloud Foundry](../configuration/cloud-foundry-provider.md#reverseproxy-and-forwarded-headers-support). ### Securing Endpoints