Exemple #1
0
        /// <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));
        }
Exemple #2
0
        /// <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
            }
        }
Exemple #3
0
 /// <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));
 }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
        /// <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));
        }
Exemple #6
0
        /// <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)));
            }
        }
Exemple #7
0
        /// <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)));
        }
Exemple #8
0
        /// <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);
        }
Exemple #9
0
        /// <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));
            }
        }
Exemple #10
0
        /// <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);
        }
Exemple #11
0
 /// <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));
 }