コード例 #1
0
        private static void ServerOptions(OpenIdConnectServerOptions options)
        {
            options.Provider                  = new AuthorizationServerProvider();
            options.AllowInsecureHttp         = true;
            options.AuthorizationEndpointPath = "/account/authorize";
            options.TokenEndpointPath         = "/token";

            options.AccessTokenLifetime  = TimeSpan.FromMinutes(1);
            options.RefreshTokenLifetime = TimeSpan.FromHours(10);
        }
コード例 #2
0
        /// <summary>
        /// Configures the OpenID Connect server to issue JWT access tokens.
        /// </summary>
        /// <param name="options">The options used to configure the OpenID Connect server.</param>
        /// <returns>The options used to configure the OpenID Connect server.</returns>
        public static OpenIdConnectServerOptions UseJwtTokens([NotNull] this OpenIdConnectServerOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            options.AccessTokenHandler = new JwtSecurityTokenHandler();

            return(options);
        }
コード例 #3
0
        private static AuthenticationTicket CreateAuthenticationTicket(
            ClaimsPrincipal principal,
            AuthenticationProperties authenticationProperties,
            OpenIdConnectServerOptions options, BaseContext context)
        {
            var configuration = Configuration(context);
            var ticket        = new AuthenticationTicket(principal,
                                                         authenticationProperties,
                                                         options.AuthenticationScheme);

            ticket.SetResources(configuration.ApiHostName());
            ticket.SetScopes(
                OpenIdConnectConstants.Scopes.OfflineAccess);
            return(ticket);
        }
        /// <summary>
        /// Adds a new OpenID Connect server instance in the OWIN pipeline.
        /// </summary>
        /// <param name="app">The web application builder.</param>
        /// <param name="options">The options controlling the behavior of the OpenID Connect server.</param>
        /// <returns>The application builder.</returns>
        public static IAppBuilder UseOpenIdConnectServer(
            [NotNull] this IAppBuilder app,
            [NotNull] OpenIdConnectServerOptions options)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            return(app.Use <OpenIdConnectServerMiddleware>(app.Properties, options));
        }
コード例 #5
0
        private static void ServerOptions(OpenIdConnectServerOptions options)
        {
            options.Provider          = new AuthorizationServerProvider();
            options.AllowInsecureHttp = true;
            // Enable endpoints.
            options.TokenEndpointPath      = "/connect/token";
            options.RevocationEndpointPath = "/connect/revoke";

            options.AccessTokenLifetime  = TimeSpan.FromMinutes(15);
            options.RefreshTokenLifetime = TimeSpan.FromMinutes(45);

            // Note: see AuthorizationController.cs for more
            // information concerning ApplicationCanDisplayErrors.
            options.ApplicationCanDisplayErrors = true;
            options.AllowInsecureHttp           = true;
        }
        /// <summary>
        /// Adds a new OpenID Connect server instance in the OWIN 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 IAppBuilder UseOpenIdConnectServer(
            [NotNull] this IAppBuilder app,
            [NotNull] Action <OpenIdConnectServerOptions> configuration)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            var options = new OpenIdConnectServerOptions();

            configuration(options);

            return(app.Use <OpenIdConnectServerMiddleware>(app.Properties, options));
        }
        /// <summary>
        /// Configures the OpenID Connect server to enable logging.
        /// </summary>
        /// <param name="options">The options used to configure the OpenID Connect server.</param>
        /// <param name="configuration">The delegate used to configure the logger factory.</param>
        /// <returns>The options used to configure the OpenID Connect server.</returns>
        public static OpenIdConnectServerOptions UseLogging(
            [NotNull] this OpenIdConnectServerOptions options,
            [NotNull] Action <LoggerFactory> configuration)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            var factory = new LoggerFactory();

            configuration(factory);

            options.Logger = factory.CreateLogger <OpenIdConnectServerMiddleware>();

            return(options);
        }
コード例 #8
0
        /// <summary>
        /// A kérések vavlidálását végzi el, csak akkor
        /// megy tovább a valósi tennivalóra, ha a kérés valid.
        /// Mivel nagyon egyszerű workflow-t akarunk legyártani,
        /// ezért a beépített validációt le kell butítanunk,
        /// és kétféle kérést elfogadnunk, a többit pedig nem ellenőrizni.
        /// </summary>
        /// <param name="options"></param>
        public static void UseMyValidateTokenRequest(this OpenIdConnectServerOptions options)
        {
            //Delegate helyett függvénnyel is megadhatjuk a tennivalót:
            //options.Provider.OnValidateTokenRequest = OnValidateTokenRequest;

            options.Provider.OnValidateTokenRequest = context =>
            {
                if (!context.Request.IsPasswordGrantType() &&
                    !context.Request.IsRefreshTokenGrantType())
                {
                    context.Reject(
                        error: OpenIdConnectConstants.Errors.UnsupportedGrantType,
                        description: "Nem megfelelő kérés"
                        );
                    return(Task.FromResult(0));
                }

                //a további validálást kikapcsoljuk
                context.Skip();
                return(Task.FromResult(0));
            };
        }
コード例 #9
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 <OpenIdConnectServerOptions> configuration)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            var options = new OpenIdConnectServerOptions();

            // By default, enable AllowInsecureHttp in development/testing environments.
            var environment = app.ApplicationServices.GetRequiredService <IHostingEnvironment>();

            options.AllowInsecureHttp = environment.IsDevelopment() || environment.IsEnvironment("Testing");

            configuration(options);
            return(app.UseOpenIdConnectServer(options));
        }
コード例 #10
0
        /// <summary>
        /// Adds a new OpenID Connect server instance in the OWIN pipeline.
        /// </summary>
        /// <param name="app">The web application builder.</param>
        /// <param name="options">The options controlling the behavior of the OpenID Connect server.</param>
        /// <returns>The application builder.</returns>
        public static IAppBuilder UseOpenIdConnectServer(
            [NotNull] this IAppBuilder app,
            [NotNull] OpenIdConnectServerOptions options)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            // If no key has been explicitly added, use the fallback mode.
            if (options.EncryptingCredentials.Count == 0 ||
                options.SigningCredentials.Count == 0)
            {
                var directory = OpenIdConnectServerHelpers.GetDefaultKeyStorageDirectory();

                // Ensure the directory exists.
                if (!directory.Exists)
                {
                    directory.Create();
                    directory.Refresh();
                }

                // Get a data protector from the services provider.
                var protector = app.CreateDataProtector(
                    typeof(OpenIdConnectServerMiddleware).Namespace,
                    options.AuthenticationType, "Keys", "v1");

                // Initialize a default logger if none has been explicitly registered.
                var logger = options.Logger ?? new LoggerFactory().CreateLogger <OpenIdConnectServerMiddleware>();

                foreach (var file in directory.EnumerateFiles("*.key"))
                {
                    using (var buffer = new MemoryStream())
                        using (var stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) {
                            // 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.
                            string usage;
                            var    parameters = OpenIdConnectServerHelpers.DecryptKey(protector, buffer.ToArray(), out usage);
                            if (parameters == null)
                            {
                                logger.LogDebug("An invalid/incompatible key was ignored: {Key}.", file.FullName);

                                continue;
                            }

                            if (string.Equals(usage, "Encryption", StringComparison.OrdinalIgnoreCase))
                            {
                                // Only add the encryption key if none has been explictly added.
                                if (options.EncryptingCredentials.Count != 0)
                                {
                                    continue;
                                }

                                var algorithm = RSA.Create();
                                algorithm.ImportParameters(parameters.Value);

                                // Add the key to the encryption credentials list.
                                options.EncryptingCredentials.AddKey(new RsaSecurityKey(algorithm));

                                logger.LogInformation("An existing key was automatically added to the " +
                                                      "encryption credentials list: {Key}.", file.FullName);
                            }

                            else if (string.Equals(usage, "Signing", StringComparison.OrdinalIgnoreCase))
                            {
                                // Only add the signing key if none has been explictly added.
                                if (options.SigningCredentials.Count != 0)
                                {
                                    continue;
                                }

                                var algorithm = RSA.Create();
                                algorithm.ImportParameters(parameters.Value);

                                // Add the key to the signing credentials list.
                                options.SigningCredentials.AddKey(new RsaSecurityKey(algorithm));

                                logger.LogInformation("An existing key was automatically added to the " +
                                                      "signing credentials list: {Key}.", file.FullName);
                            }
                        }
                }

                // If no encryption key has been found, generate and persist a new RSA key.
                if (options.EncryptingCredentials.Count == 0)
                {
                    // Generate a new RSA key and export its public/private parameters.
                    var algorithm  = OpenIdConnectServerHelpers.GenerateKey(size: 2048);
                    var parameters = algorithm.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 = OpenIdConnectServerHelpers.EncryptKey(protector, parameters, usage: "Encryption");

                        // Write the encrypted key to the file stream.
                        stream.Write(bytes, 0, bytes.Length);
                    }

                    options.EncryptingCredentials.AddKey(new RsaSecurityKey(algorithm));

                    logger.LogInformation("A new RSA key was automatically generated, added to the " +
                                          "encryption credentials list and persisted on the disk: {Path}.", path);
                }

                // If no signing key has been found, generate and persist a new RSA key.
                if (options.SigningCredentials.Count == 0)
                {
                    // Generate a new RSA key and export its public/private parameters.
                    var algorithm  = OpenIdConnectServerHelpers.GenerateKey(size: 2048);
                    var parameters = algorithm.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 = OpenIdConnectServerHelpers.EncryptKey(protector, parameters, usage: "Signing");

                        // Write the encrypted key to the file stream.
                        stream.Write(bytes, 0, bytes.Length);
                    }

                    options.SigningCredentials.AddKey(new RsaSecurityKey(algorithm));

                    logger.LogInformation("A new RSA key was automatically generated, added to the " +
                                          "signing credentials list and persisted on the disk: {Path}.", path);
                }
            }

            return(app.Use(typeof(OpenIdConnectServerMiddleware), app, options));
        }
コード例 #11
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="options">The options controlling the behavior of the OpenID Connect server.</param>
        /// <returns>The application builder.</returns>
        public static IApplicationBuilder UseOpenIdConnectServer(
            this IApplicationBuilder app,
            OpenIdConnectServerOptions options)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            // If no key has been explicitly added, use the fallback mode.
            if (options.SigningCredentials.Count == 0)
            {
                // Resolve a logger instance from the services provider.
                var logger = app.ApplicationServices.GetRequiredService <ILoggerFactory>()
                             .CreateLogger <OpenIdConnectServerMiddleware>();

                // Resolve the hosting environment from the services container.
                var environment = app.ApplicationServices.GetRequiredService <IHostingEnvironment>();
                if (environment.IsProduction())
                {
                    logger.LogWarning("No explicit signing credentials have been registered. " +
                                      "Using a X.509 certificate stored in the machine store " +
                                      "is recommended for production environments.");
                }

                var directory = OpenIdConnectServerHelpers.GetDefaultKeyStorageDirectory();

                // Ensure the directory exists.
                if (!directory.Exists)
                {
                    directory.Create();
                    directory.Refresh();
                }

                // Get a data protector from the services provider.
                var protector = app.ApplicationServices.GetDataProtector(
                    typeof(OpenIdConnectServerMiddleware).Namespace,
                    options.AuthenticationScheme, "Keys", "v1");

                foreach (var file in directory.EnumerateFiles("*.key"))
                {
                    using (var buffer = new MemoryStream())
                        using (var stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) {
                            // 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.
                            string usage;
                            var    parameters = OpenIdConnectServerHelpers.DecryptKey(protector, buffer.ToArray(), out usage);
                            if (parameters == null)
                            {
                                logger.LogVerbose("An invalid/incompatible key was ignored: {Key}.", file.FullName);

                                continue;
                            }

                            // Only add the key if it corresponds to the intended usage.
                            if (!string.Equals(usage, "Signing", StringComparison.OrdinalIgnoreCase))
                            {
                                continue;
                            }

                            logger.LogInformation("An existing key was automatically added to the " +
                                                  "signing credentials list: {Key}.", file.FullName);

                            // Add the key to the signing credentials list.
                            options.SigningCredentials.AddKey(new RsaSecurityKey(parameters.Value));
                        }
                }

                // If no signing key has been found, generate and persist a new RSA key.
                if (options.SigningCredentials.Count == 0)
                {
                    // Generate a new 2048 bit RSA key and export its public/private parameters.
                    var provider   = OpenIdConnectServerHelpers.GenerateKey(app.ApplicationServices.GetRequiredService <IRuntimeEnvironment>());
                    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 = OpenIdConnectServerHelpers.EncryptKey(protector, parameters, usage: "Signing");

                        // Write the encrypted key to the file stream.
                        stream.Write(bytes, 0, bytes.Length);
                    }

                    logger.LogInformation("A new RSA key was automatically generated, added to the " +
                                          "signing credentials list and persisted on the disk: {Key}.", path);

                    options.SigningCredentials.AddKey(new RsaSecurityKey(parameters));
                }
            }

            return(app.UseMiddleware <OpenIdConnectServerMiddleware>(options));
        }
コード例 #12
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="options">The options used to configure the OpenID Connect server.</param>
        /// <returns>The options used to configure the OpenID Connect server.</returns>
        public static OpenIdConnectServerOptions UseOpaqueTokens(this OpenIdConnectServerOptions options)
        {
            options.AccessTokenHandler = null;

            return(options);
        }
コード例 #13
0
        //Delegate nélkül így lehetne definiálni ezt
        ////////////////////////////////////////////
        //private static Task OnValidateTokenRequest(ValidateTokenRequestContext context)
        //{
        //    if (!context.Request.IsPasswordGrantType()
        //        && !context.Request.IsRefreshTokenGrantType())
        //    {
        //        context.Reject(
        //            error: OpenIdConnectConstants.Errors.UnsupportedGrantType,
        //            description: "Nem megfelelő kérés"
        //            );
        //        return Task.FromResult(0);
        //    }

        //    //a további validálást kikapcsoljuk
        //    context.Skip();
        //    return Task.FromResult(0);
        //}



        public static void UseMyHandleTokenRequest(this OpenIdConnectServerOptions options)
        {
            options.Provider.OnHandleTokenRequest = async context => //async, mert az identity async felületet ad
            {
                if (context.Request.IsPasswordGrantType())
                {
                    //csak ezt kell implementálni, a token refresh-t megoldja a szerver
                    //beépített működése

                    //Ellenőriznünk kell, hogy a felhasználó neve és jelszava rendben van-e?

                    //Ehhez szükségünk van a UserManager-re
                    //figyelem: ne mi hozzunk létre példányt hanem
                    //bízzuk rá az ASP.NET Core Dependency Service-ére!!!
                    var manager = context.HttpContext
                                  .RequestServices
                                  .GetRequiredService <UserManager <ApplicationUser> >();

                    //1. lépés: ellenőrizzük a felhasználót
                    var user = await manager.FindByNameAsync(context.Request.Username);

                    if (user == null)
                    {
                        context.Reject(
                            error: OpenIdConnectConstants.Errors.InvalidGrant,
                            description: "nem megfelelő bejelentkezési adatok"
                            );
                        return;
                    }

                    //2. ellenőrizzük a jelszavát, ehhez a bejelentkezési szolgáltatás kell.
                    var signInManager = context.HttpContext
                                        .RequestServices
                                        .GetRequiredService <SignInManager <ApplicationUser> >();

                    //először is ellenőrizzük, hogy nincs-e letilva
                    var canSignIn = await signInManager.CanSignInAsync(user);

                    if (!canSignIn)
                    {
                        context.Reject(
                            error: OpenIdConnectConstants.Errors.InvalidGrant,
                            description: "a felhasználó le van tiltva"
                            );
                        return;
                    }

                    //ide jön még egy csomó minden

                    //2 faktoros authentikáció
                    //túl sok próbálkozás miatti kitiltás kezelése
                    //stb.

                    //végül ellenőrizzük, hogy a név és jelszó megfelelő-e?
                    var isPasswordOk = await manager.CheckPasswordAsync(user, context.Request.Password);

                    if (!isPasswordOk)
                    {
                        context.Reject(
                            error: OpenIdConnectConstants.Errors.InvalidGrant,
                            description: "nem megfelelő bejelentkezési adatok"
                            );
                        return;
                    }

                    var identity = new System.Security.Claims.ClaimsIdentity(context.Options.AuthenticationScheme);
                    identity.AddClaim(OpenIdConnectConstants.Claims.Subject, user.UrlCode);
                    identity.AddClaim("username", context.Request.Username,
                                      OpenIdConnectConstants.Destinations.AccessToken
                                      , OpenIdConnectConstants.Destinations.IdentityToken); //ha a jwt-ben ezt szeretnénk látni

                    //tegyük rá a tokenre a felhasználó csoporttagságát is:
                    var roles = await manager.GetRolesAsync(user);

                    foreach (var role in roles)
                    {
                        identity.AddClaim("role", role,
                                          OpenIdConnectConstants.Destinations.AccessToken
                                          , OpenIdConnectConstants.Destinations.IdentityToken); //ha a jwt-ben ezt szeretnénk látni
                    }

                    var ticket = new Microsoft.AspNetCore.Authentication.AuthenticationTicket(
                        new System.Security.Claims.ClaimsPrincipal(identity)
                        , new Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties()
                        , context.Options.AuthenticationScheme);

                    ticket.SetScopes(
                        OpenIdConnectConstants.Scopes.OpenId          //ha openId jwt tokent is akarunk gyártani
                        , OpenIdConnectConstants.Scopes.OfflineAccess //a refresh token készítéshez ezt be kell állítani
                        );



                    context.Validate(ticket);
                }

                return;
            };
        }
コード例 #14
0
        /// <summary>
        /// Configures the OpenID Connect server to issue JWT access tokens.
        /// </summary>
        /// <param name="options">The options used to configure the OpenID Connect server.</param>
        /// <returns>The options used to configure the OpenID Connect server.</returns>
        public static OpenIdConnectServerOptions UseJwtTokens([NotNull] this OpenIdConnectServerOptions options)
        {
            options.AccessTokenHandler = new JwtSecurityTokenHandler();

            return(options);
        }