/// <summary> /// Adds a new OpenID Connect server instance in the ASP.NET pipeline. /// </summary> /// <param name="app">The web application builder.</param> /// <param name="configuration">A delegate allowing to modify the options controlling the behavior of the OpenID Connect server.</param> /// <returns>The application builder.</returns> public static IApplicationBuilder UseOpenIdConnectServer( [NotNull] this IApplicationBuilder app, [NotNull] Action <OpenIdConnectServerConfiguration> configuration) { var options = new OpenIdConnectServerConfiguration(app); // By default, enable AllowInsecureHttp in development/testing environments. var environment = app.ApplicationServices.GetRequiredService <IHostingEnvironment>(); options.Options.AllowInsecureHttp = environment.IsDevelopment() || environment.IsEnvironment("Testing"); configuration(options); // If no key has been explicitly added, use the fallback mode. if (options.Options.SigningCredentials.Count == 0) { var directory = GetDefaultKeyStorageDirectory(); // Ensure the directory exists. if (!directory.Exists) { directory.Create(); directory.Refresh(); } options.UseKeys(directory); } return(app.UseMiddleware <OpenIdConnectServerMiddleware>(options.Options)); }
/// <summary> /// Uses a specific <see cref="X509Certificate2"/> retrieved from the /// given X509 store to sign tokens issued by the OpenID Connect server. /// </summary> /// <param name="configuration">The options used to configure the OpenID Connect server.</param> /// <param name="thumbprint">The thumbprint of the certificate used to identify it in the X509 store.</param> /// <param name="name">The name of the X509 store.</param> /// <param name="location">The location of the X509 store.</param> /// <returns>The options used to configure the OpenID Connect server.</returns> public static OpenIdConnectServerConfiguration UseCertificate( [NotNull] this OpenIdConnectServerConfiguration configuration, [NotNull] string thumbprint, StoreName name, StoreLocation location) { var store = new X509Store(name, location); try { store.Open(OpenFlags.ReadOnly); var certificates = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, validOnly: false); var certificate = certificates.OfType <X509Certificate2>().SingleOrDefault(); if (certificate == null) { throw new InvalidOperationException("The certificate corresponding to the given thumbprint was not found."); } return(configuration.UseCertificate(certificate)); } finally { #if DNXCORE50 store.Dispose(); #else store.Close(); #endif } }
/// <summary> /// Uses a specific <see cref="X509Certificate2"/> contained in /// a stream to sign tokens issued by the OpenID Connect server. /// </summary> /// <param name="configuration">The options used to configure the OpenID Connect server.</param> /// <param name="stream">The stream containing the certificate.</param> /// <param name="password">The password used to open the certificate.</param> /// <returns>The options used to configure the OpenID Connect server.</returns> public static OpenIdConnectServerConfiguration UseCertificate( [NotNull] this OpenIdConnectServerConfiguration configuration, [NotNull] Stream stream, [NotNull] string password) { return(configuration.UseCertificate(stream, password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet)); }
/// <summary> /// Uses a specific <see cref="SecurityKey"/> to sign tokens issued by the OpenID Connect server. /// </summary> /// <param name="configuration">The options used to configure the OpenID Connect server.</param> /// <param name="key">The key used to sign security tokens issued by the server.</param> /// <returns>The options used to configure the OpenID Connect server.</returns> public static OpenIdConnectServerConfiguration UseKey( [NotNull] this OpenIdConnectServerConfiguration configuration, [NotNull] SecurityKey key) { configuration.Options.SigningCredentials.Add(new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest)); return(configuration); }
/// <summary> /// Uses the <see cref="RsaSecurityKey"/>s stored in the given directory. /// Note: this extension will automatically ignore incompatible keys and /// create a new RSA key if none has been previously added. /// </summary> /// <param name="configuration">The options used to configure the OpenID Connect server.</param> /// <param name="directory">The directory containing the encrypted keys.</param> /// <returns>The options used to configure the OpenID Connect server.</returns> public static OpenIdConnectServerConfiguration UseKeys( [NotNull] this OpenIdConnectServerConfiguration configuration, [NotNull] DirectoryInfo directory) { // Gets a data protector from the services provider. var protector = configuration.Builder.ApplicationServices.GetDataProtector( typeof(OpenIdConnectServerMiddleware).Namespace, configuration.Options.AuthenticationScheme, "Signing_Credentials", "v1"); return(configuration.UseKeys(directory, protector)); }
/// <summary> /// Uses a specific <see cref="X509Certificate2"/> contained in /// a stream to sign tokens issued by the OpenID Connect server. /// </summary> /// <param name="configuration">The options used to configure the OpenID Connect server.</param> /// <param name="stream">The stream containing the certificate.</param> /// <param name="password">The password used to open the certificate.</param> /// <param name="flags">An enumeration of flags indicating how and where to store the private key of the certificate.</param> /// <returns>The options used to configure the OpenID Connect server.</returns> public static OpenIdConnectServerConfiguration UseCertificate( [NotNull] this OpenIdConnectServerConfiguration configuration, [NotNull] Stream stream, [NotNull] string password, X509KeyStorageFlags flags) { using (var buffer = new MemoryStream()) { stream.CopyTo(buffer); return(configuration.UseCertificate(new X509Certificate2(buffer.ToArray(), password, flags))); } }
/// <summary> /// Uses a specific <see cref="X509Certificate2"/> to sign tokens issued by the OpenID Connect server. /// </summary> /// <param name="configuration">The options used to configure the OpenID Connect server.</param> /// <param name="certificate">The certificate used to sign security tokens issued by the server.</param> /// <returns>The options used to configure the OpenID Connect server.</returns> public static OpenIdConnectServerConfiguration UseCertificate( [NotNull] this OpenIdConnectServerConfiguration configuration, [NotNull] X509Certificate2 certificate) { if (!certificate.HasPrivateKey) { throw new InvalidOperationException("The certificate doesn't contain the required private key."); } return(configuration.UseKey(new X509SecurityKey(certificate))); }
/// <summary> /// Uses the <see cref="RsaSecurityKey"/>s stored in the given directory. /// Note: this extension will automatically ignore incompatible keys and /// create a new RSA key if none has been previously added. /// </summary> /// <param name="configuration">The options used to configure the OpenID Connect server.</param> /// <param name="directory">The directory containing the encrypted keys.</param> /// <param name="protector">The data protector used to decrypt the key.</param> /// <returns>The options used to configure the OpenID Connect server.</returns> public static OpenIdConnectServerConfiguration UseKeys( [NotNull] this OpenIdConnectServerConfiguration configuration, [NotNull] DirectoryInfo directory, [NotNull] IDataProtector protector) { if (!directory.Exists) { throw new InvalidOperationException("The directory does not exist"); } foreach (var file in directory.EnumerateFiles("*.key")) { using (var buffer = new MemoryStream()) using (var stream = file.Open(FileMode.Open)) { // Copy the key content to the buffer. stream.CopyTo(buffer); // Extract the key material using the data protector. // Ignore the key if the decryption process failed. var parameters = protector.DecryptKey(buffer.ToArray()); if (parameters == null) { continue; } configuration.UseKey(new RsaSecurityKey(parameters.Value)); } } // If no signing key has been found, // generate and persist a new RSA key. if (configuration.Options.SigningCredentials.Count == 0) { // Generate a new 2048 bit RSA key and export its public/private parameters. var provider = new RSACryptoServiceProvider(2048); var parameters = provider.ExportParameters(includePrivateParameters: true); // Generate a new file name for the key and determine its absolute path. var path = Path.Combine(directory.FullName, Guid.NewGuid().ToString() + ".key"); using (var stream = new FileStream(path, FileMode.CreateNew, FileAccess.Write)) { // Encrypt the key using the data protector. var bytes = protector.EncryptKey(parameters); // Write the encrypted key to the file stream. stream.Write(bytes, 0, bytes.Length); } configuration.UseKey(new RsaSecurityKey(parameters)); } return(configuration); }
/// <summary> /// Uses a specific <see cref="X509Certificate2"/> retrieved from an /// embedded resource to sign tokens issued by the OpenID Connect server. /// </summary> /// <param name="configuration">The options used to configure the OpenID Connect server.</param> /// <param name="assembly">The assembly containing the certificate.</param> /// <param name="resource">The name of the embedded resource.</param> /// <param name="password">The password used to open the certificate.</param> /// <returns>The options used to configure the OpenID Connect server.</returns> public static OpenIdConnectServerConfiguration UseCertificate( [NotNull] this OpenIdConnectServerConfiguration configuration, [NotNull] Assembly assembly, [NotNull] string resource, [NotNull] string password) { using (var stream = assembly.GetManifestResourceStream(resource)) { if (stream == null) { throw new InvalidOperationException("The certificate was not found in the given assembly."); } return(configuration.UseCertificate(stream, password)); } }
/// <summary> /// Configures the OpenID Connect server to issue opaque access tokens produced by the data protection block. /// Opaque tokens cannot be read by client applications or resource servers if they don't share identical keys. /// Note: you can use the validation endpoint to validate opaque tokens directly on the authorization server. /// </summary> /// <param name="configuration">The options used to configure the OpenID Connect server.</param> /// <returns>The options used to configure the OpenID Connect server.</returns> public static OpenIdConnectServerConfiguration UseOpaqueTokens([NotNull] this OpenIdConnectServerConfiguration configuration) { configuration.Options.AccessTokenHandler = null; return(configuration); }
/// <summary> /// Uses a specific <see cref="X509Certificate2"/> retrieved from the /// X509 machine store to sign tokens issued by the OpenID Connect server. /// </summary> /// <param name="configuration">The options used to configure the OpenID Connect server.</param> /// <param name="thumbprint">The thumbprint of the certificate used to identify it in the X509 store.</param> /// <returns>The options used to configure the OpenID Connect server.</returns> public static OpenIdConnectServerConfiguration UseCertificate( [NotNull] this OpenIdConnectServerConfiguration configuration, [NotNull] string thumbprint) { return(configuration.UseCertificate(thumbprint, StoreName.My, StoreLocation.LocalMachine)); }