The .NET ecosystem is famous for its batteries-included philosophy, with many of the tools necessary to build solutions available in the SDK. It’s genuinely great. As a developer, many options are one namespace, assembly, or NuGet package away. It lets you focus on developing applications rather than spending precious time and energy finding the perfect dependencies. It’s something we can take for granted, but the benefits become clear when dabbling in other ecosystems. We love it.
While .NET offers many options, there are occasions when a solution gap exists. In fact, that’s why a company like Duende Software can exist. We are a security solutions provider in a space that’s difficult, challenging, and necessary for many customers. Necessity breeds innovation, and at Duende, we aim to innovate.
As many of our customers look to migrate their solutions to .NET 10, here are a few security features missing in .NET 10, why they’re essential, and how Duende can provide an industry-leading solution. Let’s get started.
Token Management and Refresh Token Support
For developers, retrieving and managing tokens from an identity provider, like Duende IdentityServer, is only half the battle. As soon as a provider issues a token, the countdown clock starts. It's only a matter of time until the token expires. What should developers do? There’s no built-in solution in the .NET SDK.
You can rely on our Duende.AccessTokenManagement and Duende.AccessTokenManagement.OpenIdConnect packages. Both packages are free and open-source (FOSS), licensed under the Apache 2 license.
These packages inarguably improve the .NET development experience. Let’s see how.
The Duende.AccessTokenManagement library provides automatic access token management features for .NET worker and ASP.NET Core web applications:
- Automatic acquisition and lifetime management of client credentials-based access tokens for machine-to-machine communication
- Automatic access token lifetime management using a refresh token for API calls on behalf of the currently logged-in user
- Revocation of access tokens
Whether you’re building a solution that relies on console applications, service workers, or web applications, these packages can make token management a generally frustrating experience painless.
We recommend checking out our documentation on this topic to learn more about access token management.
DPoP Support
Demonstrating Proof of Possession (DPoP) is a recommended best current practice for building secure applications. DPoP binds an asymmetric key, stored in a JSON Web Key (JWK), to an access token. This process enhances security by making the access token unusable without the corresponding private key, even if the token is compromised. The “demonstrating” part requires participation from the server and client components of a security solution.
Luckily for Duende IdentityServer Enterprise customers, server-side DPoP support is included with their license. DPoP can be initiated dynamically from a client with just a few lines of code. After installing the Duende.AccessTokenManagement package requires developers to set the DPoPJsonWebKey property to enable the feature.
builder.Services.AddClientCredentialsTokenManagement()
.AddClient("demo_dpop_client", client =>
{
client.TokenEndpoint = "https://demo.duendesoftware.com/connect/token";
client.DPoPJsonWebKey = "...";
// ...
});
Adding DPoP to your security layer ensures you apply the latest, most effective security practices to all outgoing requests.
Read more about DPoP in our documentation.
We have support for DPoP across multiple development scenarios. Developers working with secured APIs will be pleased to hear that DPoP support is also available for JWT Bearer tokens via Duende’s latest NuGet package, Duende.AspNetCore.Authentication.JwtBearer. Let’s give it a try.
After adding the package to an existing project, ensure that the authentication registration registers a JWT Bearer option, as shown in the following code block.
// this API will accept any access token from the authority
builder.Services.AddAuthentication("token")
.AddJwtBearer("token", options =>
{
options.Authority = "https://localhost:5001";
options.TokenValidationParameters.ValidateAudience = false;
options.MapInboundClaims = false;
options.TokenValidationParameters.ValidTypes = ["at+jwt"];
});
Then use the packages' helpful extension method to configure the DPoP options for a specific authentication scheme.
// layers DPoP onto the "token" scheme above
builder.Services.ConfigureDPoPTokensForScheme("token", opt =>
{
opt.ValidationMode = ExpirationValidationMode.IssuedAt;
});
Now, your token authentication supports DPoP. You can see a complete set of DPoP samples in our GitHub repository.
Blazor Support for OIDC and OAuth
When .NET developers talk about Blazor, they typically need to clarify which variant of Blazor they’re using. Is it Wasm, Interactive Server, or Server Side? For many Blazor developers, once they get past the demo phase, they quickly realize they need a security model for their business applications. Regardless of which Blazor variant you’ve chosen, Duende has you covered.
Blazor Interactive Server and Server Side developers can rely on production-hardened Duende IdentityServer and the open-source packages provided to implement OIDC as part of their solution. Follow our guides to secure an existing Blazor application quickly.
For developers building Blazor WebAssembly solutions, we offer our Backend for Frontend Security Framework, which enables safe management of OAuth tokens and keeps them out of the browser. Check out our detailed quick-start guide on integrating BFF into your security model.
OAuth 2.0 Token Introspection
Standards committees evolve specifications to make developers' lives more productive. The following specification is a lifesaver for some. The Duende.AspNetCore.Authentication.OAuth2Introspection library implements an ASP.NET Core authentication handler for OAuth 2.0 token introspection, as defined in RFC 7662, “OAuth 2.0 Token Introspection”.
This library enables ASP.NET Core applications to validate access tokens and retrieve associated metadata from an authorization server. By using this, applications can employ opaque tokens that don't contain user or scope information, instead relying on the authorization server for those details. Essential features of this library include:
- OAuth 2.0 token introspection protocol
- Supports both opaque and JWT access token introspection
- Caching of introspection results to reduce load on the authorization server
- Provides a customizable authentication handler for ASP.NET Core
- Integrates seamlessly with ASP.NET Core’s authentication middleware
Adding this feature to your existing authentication handler requires an additional method call during the authentication registration process.
using Duende.AspNetCore.Authentication.OAuth2Introspection;
builder.Services.AddAuthentication(OAuth2IntrospectionDefaults.AuthenticationScheme)
.AddOAuth2Introspection(options =>
{
// Replace with your authorization server's URL
options.Authority = "https://demo.duendesoftware.com";
options.ClientId = "client_id_for_introspection_endpoint";
options.ClientSecret = "client_secret_for_introspection_endpoint";
});
Learn more about the OAuth 2.0 Introspection feature in our documentation.
Knowledge and Experience
Here at Duende, we have decades of experience integrating with security solutions within and outside of the .NET ecosystem. While we strive to codify that experience into an SDK, sometimes knowledge is better conveyed through other mediums. We’ve leveraged our expertise to develop community-leading workshops, documentation, and support, helping developers worldwide across all industries.
Conclusion
We’re excited about the .NET 10 release, and we encourage everyone who can upgrade to do so. During your upgrade, please consider Duende product offerings. Don’t reinvent the wheel when .NET itself does not cover something. Instead, leverage Duende’s expertise to develop the best security model for your applications, stakeholders, and users.
Know that we’re here to help you deliver security. Join our community over on GitHub discussions, and please leave a comment below. We’d love to hear from you.