Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 17 additions & 11 deletions docs/docs/v4/security/certificate.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Several steps need to happen before certificate authorization policies can be us

1. Bind configuration values into named `CertificateOptions`.
1. Monitor certificate files for changes (to stay up to date when certificates are rotated).
1. Configure certificate forwarding (so that ASP.NET reads the certificate from an HTTP Header).
1. Configure certificate forwarding (so that ASP.NET reads the certificate forwarded by the Cloud Foundry Gorouter).
1. Add authentication services.
1. Add authorization services and policies.
1. Activate middleware.
Expand All @@ -76,27 +76,30 @@ builder.Services
// Register Microsoft authorization services
builder.Services.AddAuthorizationBuilder()
// Register Steeltoe components and policies requiring org and/or space to match between client and server certificates
.AddOrgAndSpacePolicies();
.AddOrgAndSpacePoliciesForMutualTls();
```

> [!TIP]
> Steeltoe configures the certificate forwarding middleware to look for a certificate in the `X-Client-Cert` HTTP header.
> To change the HTTP header name used for authorization, include it when registering the policy. For example: `.AddOrgAndSpacePolicies("X-Custom-Certificate-Header")`.
> `AddOrgAndSpacePoliciesForMutualTls` configures the certificate forwarding middleware to trust only the `X-Forwarded-Client-Cert` HTTP header.
> This requires the Cloud Foundry Gorouter to be configured as the point of TLS termination. When configured correctly, Gorouter terminates the mutual TLS handshake itself and forwards the verified client certificate in the `X-Forwarded-Client-Cert` header, while stripping any instance of that header sent by the original client. This means a request cannot spoof its identity by setting the header directly, because Gorouter overwrites or removes it before the request reaches the app. If TLS termination is not enabled at the router, this header is never set and the configured policies will reject every request.

Steeltoe exposes some of the policy-related components directly if more customized scenarios are required:

```csharp
// AuthorizationPolicyBuilder setup
builder.Services.AddAuthorizationBuilder()
.AddOrgAndSpacePolicies()
.AddOrgAndSpacePoliciesForMutualTls()
.AddDefaultPolicy("sameOrgAndSpace", policy => policy.RequireSameOrg().RequireSameSpace());

// Or the equivalent using different syntax
builder.Services.AddAuthorizationBuilder()
.AddOrgAndSpacePolicies()
.AddOrgAndSpacePoliciesForMutualTls()
.AddPolicy("sameOrgAndSpace", policy => policy.AddRequirements(new SameOrgRequirement(), new SameSpaceRequirement()));
```

> [!NOTE]
> The original `AddOrgAndSpacePolicies` method (and its overload accepting a custom header name) is marked obsolete since Steeltoe 4.3.0: it trusts whatever HTTP header is configured (`X-Client-Cert` by default) without verifying that a reverse proxy set it after a successful mTLS handshake, so any client can set that header itself and spoof its identity. It remains available to support scenarios where client and server applications are upgraded one side at a time.

To activate certificate-based authorization in the request pipeline, use the `UseCertificateAuthorization` extension method on `IApplicationBuilder`:

```csharp
Expand All @@ -115,7 +118,7 @@ app.UseCertificateAuthorization();
> [!NOTE]
> This step is required only for applications that are receiving certificate-authorized requests.

As implied by the name of the extension method `AddOrgAndSpacePolicies` (from the previous section in this topic), Steeltoe provides policies for validating that a request came from an application in the same org and/or the same space. You can secure endpoints using the standard ASP.NET Core `Authorize` attribute with these security policies.
As implied by the name of the extension method `AddOrgAndSpacePoliciesForMutualTls` (from the previous section in this topic), Steeltoe provides policies for validating that a request came from an application in the same org and/or the same space. You can secure endpoints using the standard ASP.NET Core `Authorize` attribute with these security policies.

> [!TIP]
> For more information about authorization in ASP.NET Core, see the [Microsoft documentation](https://learn.microsoft.com/aspnet/core/security/authorization/introduction).
Expand Down Expand Up @@ -165,8 +168,8 @@ To use app instance identity certificates in a client application, services must
> [!NOTE]
> This step is required only for applications that are sending certificate-authorized requests.

For applications that need to send identity certificates in outgoing requests, Steeltoe provides a smooth experience through an extension method on `IHttpClientBuilder` called `AddAppInstanceIdentityCertificate`.
This method invokes code that handles loading certificates from paths defined in the application's configuration, monitors those file paths and their content for changes, and places the certificate in an HTTP header named `X-Client-Cert` on all outbound requests.
For applications that need to send identity certificates in outgoing requests, Steeltoe provides a smooth experience through an extension method on `IHttpClientBuilder` called `AddAppInstanceIdentityCertificateForMutualTls`.
This method invokes code that handles loading certificates from paths defined in the application's configuration, monitors those file paths and their content for changes, and attaches the certificate to outbound requests using a real mutual TLS handshake.

> [!TIP]
> For more information about `IHttpClientFactory`, see the [Microsoft documentation](https://learn.microsoft.com/aspnet/core/fundamentals/http-requests).
Expand All @@ -175,10 +178,13 @@ This method invokes code that handles loading certificates from paths defined in
using Steeltoe.Security.Authorization.Certificate;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient<ExampleApiClient>().AddAppInstanceIdentityCertificate();
builder.Services.AddHttpClient<ExampleApiClient>().AddAppInstanceIdentityCertificateForMutualTls();
```

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")`.
> [!NOTE]
> mTLS requires `SocketsHttpHandler` as the primary handler for the `HttpClient`. If none was explicitly configured, one is created automatically. If an incompatible primary handler was explicitly configured, an `InvalidOperationException` is thrown on .NET 9 and later; on .NET 8, the handler is silently replaced (logged at Debug level).

To send a certificate to a service that has not yet been upgraded to trust mTLS, use `AddAppInstanceIdentityCertificate()` (or the `certificateName`-based `AddClientCertificate` overloads) instead. These methods inject the certificate into an HTTP header (`X-Client-Cert` by default, or a caller-supplied name) and are obsolete since Steeltoe 4.3.0 for the same reason described above, but remain available to support one-sided upgrade scenarios during a transition. For example: `.AddAppInstanceIdentityCertificate("X-Custom-Certificate-Header")`.

### Customizing CertificateAuthenticationOptions

Expand Down
8 changes: 7 additions & 1 deletion docs/docs/v4/welcome/migrate-quick-steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -1421,7 +1421,7 @@ app.MapGet("/test-auth", async httpContext =>
await httpContext.Response.WriteAsync("You are logged in and carry the required claim.");
}).RequireAuthorization("read");

app.Run();
app.Run();
```

### JWT Bearer
Expand Down Expand Up @@ -1588,6 +1588,9 @@ app.Run();
> The code shown above is provided for compatibility between the versions. The preferred header name is `X-Client-Cert`.
> In Steeltoe 4.0, the default header is `X-Client-Cert`, so the parameter can be omitted if cross-compatibility is not required.

> [!IMPORTANT]
> `AddOrgAndSpacePolicies` is obsolete since Steeltoe 4.3.0. For new applications, use `AddOrgAndSpacePoliciesForMutualTls` instead, which trusts only the `X-Forwarded-Client-Cert` header set by the Cloud Foundry Gorouter after a real mTLS handshake. See [Resource Protection using Mutual TLS](../security/certificate.md) for details.

Program.cs (client-side):

```diff
Expand Down Expand Up @@ -1639,6 +1642,9 @@ public class TestClient(HttpClient httpClient)
> The code shown above is provided for compatibility between the versions. The preferred header name is `X-Client-Cert`.
> In Steeltoe 4.0, the default header is `X-Client-Cert`, so the parameter can be omitted if cross-compatibility is not required.

> [!IMPORTANT]
> `AddAppInstanceIdentityCertificate` is obsolete since Steeltoe 4.3.0. For new applications, use `AddAppInstanceIdentityCertificateForMutualTls` instead, which attaches the certificate using a real mTLS handshake instead of an HTTP header. See [Resource Protection using Mutual TLS](../security/certificate.md) for details.

### DataProtection Key Store using Redis/Valkey

```diff
Expand Down
15 changes: 15 additions & 0 deletions docs/docs/v4/welcome/whats-new.md
Original file line number Diff line number Diff line change
Expand Up @@ -1494,6 +1494,21 @@ For more information, see the updated [Management documentation](../management/i
| `Steeltoe.Security.DataProtection.Redis.RedisDataProtectionBuilderExtensions.PersistKeysToRedis` | Extension method | Steeltoe.Security.DataProtection.Redis | Added | | Takes an optional service binding name |
| `Steeltoe.Security.DataProtection.RedisDataProtectionBuilderExtensions.PersistKeysToRedis` | Extension method | Steeltoe.Security.DataProtection.RedisCore | Moved | `PersistKeysToRedis()` in Steeltoe.Security.DataProtection.Redis package | |

### Breaking API changes after the 4.0 release

The table above reflects the API surface as of the initial Steeltoe 4.0 release. The following breaking changes were introduced in later 4.x releases.

#### Steeltoe.Security changes in 4.3

| Source | Kind | Package | Change | Replacement | Notes |
| --- | --- | --- | --- | --- | --- |
| `Steeltoe.Security.Authorization.Certificate.CertificateAuthorizationBuilderExtensions.AddOrgAndSpacePolicies` | Extension method | Steeltoe.Security.Authorization.Certificate | Obsolete | `AddOrgAndSpacePoliciesForMutualTls()` | Header-based certificate forwarding can be spoofed by any client |
| `Steeltoe.Security.Authorization.Certificate.CertificateAuthorizationBuilderExtensions.AddOrgAndSpacePoliciesForMutualTls` | Extension method | Steeltoe.Security.Authorization.Certificate | Added | | Verify space/org in the incoming client certificate using mTLS forwarded by the Cloud Foundry Gorouter |
| `Steeltoe.Security.Authorization.Certificate.CertificateHttpClientBuilderExtensions.AddAppInstanceIdentityCertificate` | Extension method | Steeltoe.Security.Authorization.Certificate | Obsolete | `AddAppInstanceIdentityCertificateForMutualTls()` | Header-based certificate injection can be spoofed by any client |
| `Steeltoe.Security.Authorization.Certificate.CertificateHttpClientBuilderExtensions.AddAppInstanceIdentityCertificateForMutualTls` | Extension method | Steeltoe.Security.Authorization.Certificate | Added | | Send app-identity certificate with outgoing HTTP requests using mTLS |
| `Steeltoe.Security.Authorization.Certificate.CertificateHttpClientBuilderExtensions.AddClientCertificate` | Extension method | Steeltoe.Security.Authorization.Certificate | Obsolete | `AddClientCertificateForMutualTls(string)` | Header-based certificate injection can be spoofed by any client |
| `Steeltoe.Security.Authorization.Certificate.CertificateHttpClientBuilderExtensions.AddClientCertificateForMutualTls` | Extension method | Steeltoe.Security.Authorization.Certificate | Added | | Send custom certificate with outgoing HTTP requests using mTLS |

### Notable PRs

- https://github.com/SteeltoeOSS/Steeltoe/pull/1525
Expand Down
Loading