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); }
/// <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); }
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)); }
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); }
/// <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)); }; }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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); }
//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; }; }
/// <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); }