mirror of
https://github.com/DuendeSoftware/products
synced 2026-05-24 09:28:24 +00:00
* Initial import of SAML code * Added missing SAML-relevant tests * Fixed compilation errors after rebasing XUnit V3 changes * Fixed subtle issues introduced in initial code import * Reworked test to use Kestrel based test hosts to allow cross-server communication * Eliminated odd value types to remain more consistent with code base * Do not enable SAML by default, but provide mechnism to opt-in * Base SAML test client * Add directions for configuring cert for SAML sample * Include encrypting assertions in SAML sample * Apply CT alias to SAML code * Dotnet format * Updated necessary SAML code after rebasing cooperative cancellation support * Updated SAML code to participate in cooperative cancellation * Fix name of SAML sign in state cookie
136 lines
5.9 KiB
C#
136 lines
5.9 KiB
C#
// Copyright (c) Duende Software. All rights reserved.
|
|
// See LICENSE in the project root for license information.
|
|
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using Duende.IdentityModel;
|
|
using Duende.IdentityServer;
|
|
using Duende.IdentityServer.Configuration;
|
|
using Duende.IdentityServer.Configuration.RequestProcessing;
|
|
using Duende.IdentityServer.Hosts.Shared.Configuration;
|
|
using Duende.IdentityServer.Hosts.Shared.Customization;
|
|
using Microsoft.AspNetCore.Authentication.Certificate;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
|
|
namespace IdentityServerHost;
|
|
|
|
internal static class IdentityServerExtensions
|
|
{
|
|
internal static WebApplicationBuilder ConfigureIdentityServer(this WebApplicationBuilder builder)
|
|
{
|
|
var identityServer = builder.Services.AddIdentityServer(options =>
|
|
{
|
|
options.Events.RaiseSuccessEvents = true;
|
|
options.Events.RaiseFailureEvents = true;
|
|
options.Events.RaiseErrorEvents = true;
|
|
options.Events.RaiseInformationEvents = true;
|
|
|
|
options.EmitScopesAsSpaceDelimitedStringInJwt = true;
|
|
options.Endpoints.EnableJwtRequestUri = true;
|
|
|
|
options.ServerSideSessions.UserDisplayNameClaimType = JwtClaimTypes.Name;
|
|
|
|
options.UserInteraction.CreateAccountUrl = "/Account/Create";
|
|
|
|
options.Endpoints.EnablePushedAuthorizationEndpoint = true;
|
|
options.PushedAuthorization.AllowUnregisteredPushedRedirectUris = true;
|
|
|
|
options.KeyManagement.SigningAlgorithms.Add(new SigningAlgorithmOptions
|
|
{
|
|
Name = "RS256",
|
|
UseX509Certificate = true
|
|
});
|
|
|
|
// In load-balanced environments, synchronization delay is important.
|
|
// In development, we're never load balanced and can skip it to start up faster.
|
|
if (builder.Environment.IsDevelopment())
|
|
{
|
|
options.KeyManagement.InitializationSynchronizationDelay = TimeSpan.Zero;
|
|
}
|
|
|
|
options.MutualTls.Enabled = true;
|
|
|
|
options.Diagnostics.ChunkSize = 1024 * 1000 - 32; // 1 MB minus some formatting space;
|
|
})
|
|
.AddServerSideSessions()
|
|
.AddInMemoryClients(TestClients.Get())
|
|
.AddInMemoryIdentityResources(TestResources.IdentityResources)
|
|
.AddInMemoryApiResources(TestResources.ApiResources)
|
|
.AddInMemoryApiScopes(TestResources.ApiScopes)
|
|
//.AddStaticSigningCredential()
|
|
.AddExtensionGrantValidator<ExtensionGrantValidator>()
|
|
.AddExtensionGrantValidator<NoSubjectExtensionGrantValidator>()
|
|
.AddJwtBearerClientAuthentication()
|
|
.AddAppAuthRedirectUriValidator()
|
|
.AddTestUsers(TestUsers.Users)
|
|
.AddProfileService<HostProfileService>()
|
|
.AddCustomTokenRequestValidator<ParameterizedScopeTokenRequestValidator>()
|
|
.AddScopeParser<ParameterizedScopeParser>()
|
|
.AddMutualTlsSecretValidators()
|
|
.AddInMemoryOidcProviders(
|
|
[
|
|
new Duende.IdentityServer.Models.OidcProvider
|
|
{
|
|
Scheme = "dynamicprovider-idsvr",
|
|
DisplayName = "IdentityServer (via Dynamic Providers)",
|
|
Authority = "https://demo.duendesoftware.com",
|
|
ClientId = "login",
|
|
ResponseType = "id_token",
|
|
Scope = "openid profile"
|
|
}
|
|
])
|
|
.AddLicenseSummary()
|
|
.AddSaml()
|
|
.AddInMemorySamlServiceProviders(SamlServiceProviders.Get());
|
|
|
|
builder.Services.AddIdentityServerConfiguration(opt => { })
|
|
.AddInMemoryClientConfigurationStore();
|
|
builder.Services.AddTransient<IDynamicClientRegistrationRequestProcessor, CustomClientRegistrationProcessor>();
|
|
|
|
builder.Services.AddDistributedMemoryCache();
|
|
|
|
builder.Services.AddAuthentication().AddCertificate(certificateOptions =>
|
|
{
|
|
// We must allow self-signed certificates for the "ephemeral" case
|
|
certificateOptions.AllowedCertificateTypes = CertificateTypes.Chained | CertificateTypes.SelfSigned;
|
|
certificateOptions.RevocationMode = X509RevocationMode.NoCheck;
|
|
});
|
|
|
|
return builder;
|
|
}
|
|
|
|
// To use static signing credentials, create keys and add it to the certificate store.
|
|
// This shows how to create both rsa and ec keys, in case you had clients that were configured to use different algorithms
|
|
// You can create keys for dev use with the mkcert util:
|
|
// mkcert -pkcs12 identityserver.test.rsa
|
|
// mkcert -pkcs12 -ecdsa identityserver.test.ecdsa
|
|
// Then import the keys into the certificate manager. This code expect keys in the personal store of the current user.
|
|
private static IIdentityServerBuilder AddStaticSigningCredential(this IIdentityServerBuilder builder)
|
|
{
|
|
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
|
|
try
|
|
{
|
|
store.Open(OpenFlags.ReadOnly);
|
|
|
|
var rsaCert = store.Certificates
|
|
.Find(X509FindType.FindBySubjectName, "identityserver.test.rsa", true)
|
|
.Single();
|
|
builder.AddSigningCredential(rsaCert, "RS256");
|
|
builder.AddSigningCredential(rsaCert, "PS256");
|
|
|
|
var ecCert = store.Certificates
|
|
.Find(X509FindType.FindBySubjectName, "identityserver.test.ecdsa", true)
|
|
.Single();
|
|
var key = new ECDsaSecurityKey(ecCert.GetECDsaPrivateKey())
|
|
{
|
|
KeyId = CryptoRandom.CreateUniqueId(16, CryptoRandom.OutputFormat.Hex)
|
|
};
|
|
builder.AddSigningCredential(key, IdentityServerConstants.ECDsaSigningAlgorithm.ES256);
|
|
}
|
|
finally
|
|
{
|
|
store.Close();
|
|
}
|
|
|
|
return builder;
|
|
}
|
|
}
|