Autenticazione JWT semplice in API Web ASP.NET Core 1.0

Sto cercando il modo più semplice per configurare un server API Web che utilizza JWT per l’autenticazione in ASP.NET Core (noto anche come ASP.NET 5). Questo progetto ( post di blog / github ) fa esattamente quello che sto cercando ma utilizza ASP.NET 4.

Voglio solo essere in grado di:

  1. configurare un percorso di accesso che può creare un token JWT e restituirlo nell’intestazione. Sto integrando questo con un servizio RESTful esistente che mi dirà se il nome utente e la password sono validi. Nel progetto ASP.NET 4 sto guardando questo potrebbe essere fatto con il seguente percorso https://github.com/stewartm83/Jwt-WebApi/blob/master/src/JwtWebApi/Controllers/AccountController.cs#L24- L54

  2. Intercetta le richieste in entrata alle rotte che richiedono l’authorization, decrittografano e convalidano il token JWT che entra nell’intestazione e rendono le informazioni dell’utente nel payload del token JWT accessibile per la rotta. per esempio qualcosa del genere: https://github.com/stewartm83/Jwt-WebApi/blob/master/src/JwtWebApi/App_Start/AuthHandler.cs

Tutti gli esempi che ho visto in ASP.NET Core sono molto complessi e si basano su alcuni o tutti su OAuth, IS, OpenIddict e EF che vorrei evitare.

Qualcuno può indicarmi un esempio su come farlo in ASP.NET Core o aiutarmi a iniziare con questo?

EDIT: risposta Ho finito per utilizzare questa risposta: https://stackoverflow.com/a/33217340/373655

Nota / Aggiornamento:

Il codice seguente era per .NET Core 1.1
Poiché .NET Core 1 era così molto RTM, l’autenticazione è cambiata con il salto da .NET Core 1 a 2.0 (alias anche [parzialmente?] Risolti con interruzioni delle modifiche).
Ecco perché il codice qui sotto NON funziona più con .NET Core 2.0.
Ma sarà comunque una lettura utile.

Aggiornamento 2018

Nel frattempo, puoi trovare un esempio funzionante di ASP.NET Core 2.0 JWT-Cookie-Authentication sul mio repository di test github . Viene completato con un’implementazione della class astratta MS-RSA e MS-ECDSA con BouncyCastle e un generatore di chiavi per RSA ed ECDSA.


Necromancing.
Ho scavato più a fondo nel JWT. Ecco i miei risultati:

È necessario aggiungere Microsoft.AspNetCore.Authentication.JwtBearer

allora puoi impostare

app.UseJwtBearerAuthentication(bearerOptions); 

in Startup.cs => Configura

dove bearerOptions è definito da te, ad esempio come

 var bearerOptions = new JwtBearerOptions() { AutomaticAuthenticate = true, AutomaticChallenge = true, TokenValidationParameters = tokenValidationParameters, Events = new CustomBearerEvents() }; // Optional // bearerOptions.SecurityTokenValidators.Clear(); // bearerOptions.SecurityTokenValidators.Add(new MyTokenHandler()); 

dove CustomBearerEvents è il luogo in cui è ansible aggiungere dati token a httpContext / Route

 // https://github.com/aspnet/Security/blob/master/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/JwtBearerEvents.cs public class CustomBearerEvents : Microsoft.AspNetCore.Authentication.JwtBearer.IJwtBearerEvents { ///  /// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed. ///  public Func OnAuthenticationFailed { get; set; } = context => Task.FromResult(0); ///  /// Invoked when a protocol message is first received. ///  public Func OnMessageReceived { get; set; } = context => Task.FromResult(0); ///  /// Invoked after the security token has passed validation and a ClaimsIdentity has been generated. ///  public Func OnTokenValidated { get; set; } = context => Task.FromResult(0); ///  /// Invoked before a challenge is sent back to the caller. ///  public Func OnChallenge { get; set; } = context => Task.FromResult(0); Task IJwtBearerEvents.AuthenticationFailed(AuthenticationFailedContext context) { return OnAuthenticationFailed(context); } Task IJwtBearerEvents.Challenge(JwtBearerChallengeContext context) { return OnChallenge(context); } Task IJwtBearerEvents.MessageReceived(MessageReceivedContext context) { return OnMessageReceived(context); } Task IJwtBearerEvents.TokenValidated(TokenValidatedContext context) { return OnTokenValidated(context); } } 

E tokenValidationParameters è definito dall’utente, ad es

 var tokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { // The signing key must match! ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, // Validate the JWT Issuer (iss) claim ValidateIssuer = true, ValidIssuer = "ExampleIssuer", // Validate the JWT Audience (aud) claim ValidateAudience = true, ValidAudience = "ExampleAudience", // Validate the token expiry ValidateLifetime = true, // If you want to allow a certain amount of clock drift, set that here: ClockSkew = TimeSpan.Zero, }; 

E MyTokenHandler è facoltativamente definito dall’utente, se si desidera personalizzare la convalida del token, ad es

 // https://gist.github.com/pmhsfelix/4151369 public class MyTokenHandler : Microsoft.IdentityModel.Tokens.ISecurityTokenValidator { private int m_MaximumTokenByteSize; public MyTokenHandler() { } bool ISecurityTokenValidator.CanValidateToken { get { // throw new NotImplementedException(); return true; } } int ISecurityTokenValidator.MaximumTokenSizeInBytes { get { return this.m_MaximumTokenByteSize; } set { this.m_MaximumTokenByteSize = value; } } bool ISecurityTokenValidator.CanReadToken(string securityToken) { System.Console.WriteLine(securityToken); return true; } ClaimsPrincipal ISecurityTokenValidator.ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken) { JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); // validatedToken = new JwtSecurityToken(securityToken); try { tokenHandler.ValidateToken(securityToken, validationParameters, out validatedToken); validatedToken = new JwtSecurityToken("jwtEncodedString"); } catch (Exception ex) { System.Console.WriteLine(ex.Message); throw; } ClaimsPrincipal principal = null; // SecurityToken validToken = null; validatedToken = null; System.Collections.Generic.List ls = new System.Collections.Generic.List(); ls.Add( new System.Security.Claims.Claim( System.Security.Claims.ClaimTypes.Name, "IcanHazUsr_éèêëïàáâäåãæóòôöõõúùûüñçø_ÉÈÊËÏÀÁÂÄÅÃÆÓÒÔÖÕÕÚÙÛÜÑÇØ 你好,世界 Привет\tмир" , System.Security.Claims.ClaimValueTypes.String ) ); // System.Security.Claims.ClaimsIdentity id = new System.Security.Claims.ClaimsIdentity("authenticationType"); id.AddClaims(ls); principal = new System.Security.Claims.ClaimsPrincipal(id); return principal; throw new NotImplementedException(); } } 

La parte difficile è come ottenere AsymmetricSecurityKey, perché non si vuole passare un rsaCryptoServiceProvider, perché è necessario l’interoperabilità in formato crittografico.

La creazione segue le linee di

 // System.Security.Cryptography.X509Certificates.X509Certificate2 cert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(byte[] rawData); System.Security.Cryptography.X509Certificates.X509Certificate2 cert2 = DotNetUtilities.CreateX509Cert2("mycert"); Microsoft.IdentityModel.Tokens.SecurityKey secKey = new X509SecurityKey(cert2); 

ad es. con BouncyCastle da un certificato DER:

  // http://stackoverflow.com/questions/36942094/how-can-i-generate-a-self-signed-cert-without-using-obsolete-bouncycastle-1-7-0 public static System.Security.Cryptography.X509Certificates.X509Certificate2 CreateX509Cert2(string certName) { var keypairgen = new Org.BouncyCastle.Crypto.Generators.RsaKeyPairGenerator(); keypairgen.Init(new Org.BouncyCastle.Crypto.KeyGenerationParameters( new Org.BouncyCastle.Security.SecureRandom( new Org.BouncyCastle.Crypto.Prng.CryptoApiRandomGenerator() ) , 1024 ) ); Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keypair = keypairgen.GenerateKeyPair(); // --- Until here we generate a keypair var random = new Org.BouncyCastle.Security.SecureRandom( new Org.BouncyCastle.Crypto.Prng.CryptoApiRandomGenerator() ); // SHA1WITHRSA // SHA256WITHRSA // SHA384WITHRSA // SHA512WITHRSA // SHA1WITHECDSA // SHA224WITHECDSA // SHA256WITHECDSA // SHA384WITHECDSA // SHA512WITHECDSA Org.BouncyCastle.Crypto.ISignatureFactory signatureFactory = new Org.BouncyCastle.Crypto.Operators.Asn1SignatureFactory("SHA512WITHRSA", keypair.Private, random) ; var gen = new Org.BouncyCastle.X509.X509V3CertificateGenerator(); var CN = new Org.BouncyCastle.Asn1.X509.X509Name("CN=" + certName); var SN = Org.BouncyCastle.Math.BigInteger.ProbablePrime(120, new Random()); gen.SetSerialNumber(SN); gen.SetSubjectDN(CN); gen.SetIssuerDN(CN); gen.SetNotAfter(DateTime.Now.AddYears(1)); gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0))); gen.SetPublicKey(keypair.Public); // -- Are these necessary ? // public static readonly DerObjectIdentifier AuthorityKeyIdentifier = new DerObjectIdentifier("2.5.29.35"); // OID value: 2.5.29.35 // OID description: id-ce-authorityKeyIdentifier // This extension may be used either as a certificate or CRL extension. // It identifies the public key to be used to verify the signature on this certificate or CRL. // It enables distinct keys used by the same CA to be distinguished (eg, as key updating occurs). // http://stackoverflow.com/questions/14930381/generating-x509-certificate-using-bouncy-castle-java gen.AddExtension( Org.BouncyCastle.Asn1.X509.X509Extensions.AuthorityKeyIdentifier.Id, false, new Org.BouncyCastle.Asn1.X509.AuthorityKeyIdentifier( Org.BouncyCastle.X509.SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keypair.Public), new Org.BouncyCastle.Asn1.X509.GeneralNames(new Org.BouncyCastle.Asn1.X509.GeneralName(CN)), SN )); // OID value: 1.3.6.1.5.5.7.3.1 // OID description: Indicates that a certificate can be used as an SSL server certificate. gen.AddExtension( Org.BouncyCastle.Asn1.X509.X509Extensions.ExtendedKeyUsage.Id, false, new Org.BouncyCastle.Asn1.X509.ExtendedKeyUsage(new ArrayList() { new Org.BouncyCastle.Asn1.DerObjectIdentifier("1.3.6.1.5.5.7.3.1") })); // -- End are these necessary ? Org.BouncyCastle.X509.X509Certificate bouncyCert = gen.Generate(signatureFactory); byte[] ba = bouncyCert.GetEncoded(); System.Security.Cryptography.X509Certificates.X509Certificate2 msCert = new System.Security.Cryptography.X509Certificates.X509Certificate2(ba); return msCert; } 

Successivamente, puoi aggiungere un formato cookie personalizzato che contiene il portatore di JWT:

 app.UseCookieAuthentication(new CookieAuthenticationOptions() { AuthenticationScheme = "MyCookieMiddlewareInstance", CookieName = "SecurityByObscurityDoesntWork", ExpireTimeSpan = new System.TimeSpan(15, 0, 0), LoginPath = new Microsoft.AspNetCore.Http.PathString("/Account/Unauthorized/"), AccessDeniedPath = new Microsoft.AspNetCore.Http.PathString("/Account/Forbidden/"), AutomaticAuthenticate = true, AutomaticChallenge = true, CookieSecure = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest, CookieHttpOnly = false, TicketDataFormat = new CustomJwtDataFormat("foo", tokenValidationParameters) // DataProtectionProvider = null, // DataProtectionProvider = new DataProtectionProvider(new System.IO.DirectoryInfo(@"c:\shared-auth-ticket-keys\"), //delegate (DataProtectionConfiguration options) //{ // var op = new Microsoft.AspNet.DataProtection.AuthenticatedEncryption.AuthenticatedEncryptionOptions(); // op.EncryptionAlgorithm = Microsoft.AspNet.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm.AES_256_GCM: // options.UseCryptographicAlgorithms(op); //} //), }); 

Dove CustomJwtDataFormat è qualcosa sulla falsariga di

 public class CustomJwtDataFormat : ISecureDataFormat { private readonly string algorithm; private readonly TokenValidationParameters validationParameters; public CustomJwtDataFormat(string algorithm, TokenValidationParameters validationParameters) { this.algorithm = algorithm; this.validationParameters = validationParameters; } // This ISecureDataFormat implementation is decode-only string ISecureDataFormat.Protect(AuthenticationTicket data) { return MyProtect(data, null); } string ISecureDataFormat.Protect(AuthenticationTicket data, string purpose) { return MyProtect(data, purpose); } AuthenticationTicket ISecureDataFormat.Unprotect(string protectedText) { return MyUnprotect(protectedText, null); } AuthenticationTicket ISecureDataFormat.Unprotect(string protectedText, string purpose) { return MyUnprotect(protectedText, purpose); } private string MyProtect(AuthenticationTicket data, string purpose) { return "wadehadedudada"; throw new System.NotImplementedException(); } // http://blogs.microsoft.co.il/sasha/2012/01/20/aggressive-inlining-in-the-clr-45-jit/ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] private AuthenticationTicket MyUnprotect(string protectedText, string purpose) { JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); ClaimsPrincipal principal = null; SecurityToken validToken = null; System.Collections.Generic.List ls = new System.Collections.Generic.List(); ls.Add( new System.Security.Claims.Claim( System.Security.Claims.ClaimTypes.Name, "IcanHazUsr_éèêëïàáâäåãæóòôöõõúùûüñçø_ÉÈÊËÏÀÁÂÄÅÃÆÓÒÔÖÕÕÚÙÛÜÑÇØ 你好,世界 Привет\tмир" , System.Security.Claims.ClaimValueTypes.String ) ); // System.Security.Claims.ClaimsIdentity id = new System.Security.Claims.ClaimsIdentity("authenticationType"); id.AddClaims(ls); principal = new System.Security.Claims.ClaimsPrincipal(id); return new AuthenticationTicket(principal, new AuthenticationProperties(), "MyCookieMiddlewareInstance"); try { principal = handler.ValidateToken(protectedText, this.validationParameters, out validToken); JwtSecurityToken validJwt = validToken as JwtSecurityToken; if (validJwt == null) { throw new System.ArgumentException("Invalid JWT"); } if (!validJwt.Header.Alg.Equals(algorithm, System.StringComparison.Ordinal)) { throw new System.ArgumentException($"Algorithm must be '{algorithm}'"); } // Additional custom validation of JWT claims here (if any) } catch (SecurityTokenValidationException) { return null; } catch (System.ArgumentException) { return null; } // Validation passed. Return a valid AuthenticationTicket: return new AuthenticationTicket(principal, new AuthenticationProperties(), "MyCookieMiddlewareInstance"); } } 

E puoi anche creare il token JWT con Microsoft.IdentityModel.Token:

 // https://github.com/aspnet/Security/blob/master/src/Microsoft.AspNetCore.Authentication.JwtBearer/Events/IJwtBearerEvents.cs // http://codereview.stackexchange.com/questions/45974/web-api-2-authentication-with-jwt public class TokenMaker { class SecurityConstants { public static string TokenIssuer; public static string TokenAudience; public static int TokenLifetimeMinutes; } public static string IssueToken() { SecurityKey sSKey = null; var claimList = new List() { new Claim(ClaimTypes.Name, "userName"), new Claim(ClaimTypes.Role, "role") //Not sure what this is for }; JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); SecurityTokenDescriptor desc = makeSecurityTokenDescriptor(sSKey, claimList); // JwtSecurityToken tok = tokenHandler.CreateJwtSecurityToken(desc); return tokenHandler.CreateEncodedJwt(desc); } public static ClaimsPrincipal ValidateJwtToken(string jwtToken) { SecurityKey sSKey = null; var tokenHandler = new JwtSecurityTokenHandler(); // Parse JWT from the Base64UrlEncoded wire form //(..) JwtSecurityToken parsedJwt = tokenHandler.ReadToken(jwtToken) as JwtSecurityToken; TokenValidationParameters validationParams = new TokenValidationParameters() { RequireExpirationTime = true, ValidAudience = SecurityConstants.TokenAudience, ValidIssuers = new List() { SecurityConstants.TokenIssuer }, ValidateIssuerSigningKey = true, ValidateLifetime = true, IssuerSigningKey = sSKey, }; SecurityToken secT; return tokenHandler.ValidateToken("token", validationParams, out secT); } private static SecurityTokenDescriptor makeSecurityTokenDescriptor(SecurityKey sSKey, List claimList) { var now = DateTime.UtcNow; Claim[] claims = claimList.ToArray(); return new Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Issuer = SecurityConstants.TokenIssuer, Audience = SecurityConstants.TokenAudience, IssuedAt = System.DateTime.UtcNow, Expires = System.DateTime.UtcNow.AddMinutes(SecurityConstants.TokenLifetimeMinutes), NotBefore = System.DateTime.UtcNow.AddTicks(-1), SigningCredentials = new SigningCredentials(sSKey, Microsoft.IdentityModel.Tokens.SecurityAlgorithms.EcdsaSha512Signature) }; } } 

Tieni presente che poiché puoi dare un utente diverso nel cookie rispetto a http-headers (Bearer) o qualsiasi altro metodo di autenticazione che hai specificato, puoi effettivamente avere più di 1 utente!


Guarda questo:
https://stormpath.com/blog/token-authentication-asp-net-core

dovrebbe essere esattamente quello che stai cercando.

Ci sono anche questi due:

https://goblincoding.com/2016/07/03/issuing-and-authenticating-jwt-tokens-in-asp-net-core-webapi-part-i/

https://goblincoding.com/2016/07/07/issuing-and-authenticating-jwt-tokens-in-asp-net-core-webapi-part-ii/

e questo
http://blog.novanet.no/hooking-up-asp-net-core-1-rc1-web-api-with-auth0-bearer-tokens/

E i sorgenti di JWT-Bearer: https://github.com/aspnet/Security/tree/master/src/Microsoft.AspNetCore.Authentication.JwtBearer


Se hai bisogno di una sicurezza elevatissima, devi proteggerti dagli attacchi di riproduzione rinnovando il ticket su ogni richiesta e invalida i vecchi ticket dopo un determinato timeout e dopo il logout dell’utente (non solo dopo la scadenza della validità).


Per quelli di voi che finiscono da qui tramite google, è ansible implementare un TicketDataFormat in autenticazione-cookie quando si desidera utilizzare la propria versione di JWT.

Ho dovuto esaminare il JWT per lavoro, perché avevamo bisogno di proteggere la nostra applicazione.
Poiché dovevo ancora utilizzare .NET 2.0, dovevo scrivere la mia libreria.

Questo weekend ho portato il risultato su .NET Core. Lo trovate qui: https://github.com/ststeiger/Jwt_Net20/tree/master/CoreJWT

Non usa alcun database, non è il lavoro di una libreria JWT.
Ottenere e impostare i dati DB è il tuo lavoro.
La libreria consente l’authorization e la verifica JWT in .NET Core con tutti gli algoritmi specificati nel RFC JWT elencati nell’assegnazione JOSE IANA .
Per quanto riguarda l’aggiunta dell’authorization alla pipeline e l’aggiunta di valori alla rotta, queste sono due cose che dovrebbero essere fatte separatamente, e penso che sia meglio farlo da soli.

È ansible utilizzare l’autenticazione personalizzata in ASP.NET Core.
Cerca nella categoria “Sicurezza” dei documenti su docs.asp.net.

Oppure puoi guardare nel middleware dei cookie senza identity framework ASP.NET o in un’authorization basata su criteri personalizzati .

Puoi anche saperne di più nel workshop di auth su github o nella sezione social login o in questo video tutorial di canale 9 .
Se tutto il resto fallisce, il codice sorgente della sicurezza asp.net è in github .


Il progetto originale per .NET 3.5, da cui deriva la mia libreria, è qui:
https://github.com/jwt-dotnet/jwt
Ho rimosso tutti i riferimenti ai metodi di estensione LINQ +, perché non sono supportati in .NET 2.0. Se includi LINQ o ExtensionAttribute nel codice sorgente, non puoi semplicemente modificare il runtime .NET senza ricevere avvisi; è per questo che li ho completamente rimossi.
Inoltre, ho aggiunto i metodi RSA + ECSD JWS, per questo motivo il progetto CoreJWT dipende da BouncyCastle.
Se ti limiti a HMAC-SHA256 + HMAC-SHA384 + HMAC-SHA512, puoi rimuovere BouncyCastle.

JWE non è (ancora) supportato.

L’utilizzo è simile a jwt-dotnet / jwt, tranne che ho cambiato lo spazio dei nomi JWT in CoreJWT .
Ho anche aggiunto una copia interna di PetaJSON come serializzatore, quindi non c’è alcuna interferenza con le dipendenze del progetto di altre persone.

Creare un token JWT:

 var payload = new Dictionary() { { "claim1", 0 }, { "claim2", "claim2-value" } }; var secretKey = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk"; string token = JWT.JsonWebToken.Encode(payload, secretKey, JWT.JwtHashAlgorithm.HS256); Console.WriteLine(token); 

Verifica un token JWT:

 var token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjbGFpbTEiOjAsImNsYWltMiI6ImNsYWltMi12YWx1ZSJ9.8pwBI_HtXqI3UgQHQ_rDRnSQRxFL1SR8fbQoS-5kM5s"; var secretKey = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk"; try { string jsonPayload = JWT.JsonWebToken.Decode(token, secretKey); Console.WriteLine(jsonPayload); } catch (JWT.SignatureVerificationException) { Console.WriteLine("Invalid token!"); } 

Per RSA ed ECSA, dovrai passare la chiave privata RSA / ECSD (BouncyCastle) invece di secretKey.

 namespace BouncyJWT { public class JwtKey { public byte[] MacKeyBytes; public Org.BouncyCastle.Crypto.AsymmetricKeyParameter RsaPrivateKey; public Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters EcPrivateKey; public string MacKey { get { return System.Text.Encoding.UTF8.GetString(this.MacKeyBytes); } set { this.MacKeyBytes = System.Text.Encoding.UTF8.GetBytes(value); } } public JwtKey() { } public JwtKey(string macKey) { this.MacKey = macKey; } public JwtKey(byte[] macKey) { this.MacKeyBytes = macKey; } public JwtKey(Org.BouncyCastle.Crypto.AsymmetricKeyParameter rsaPrivateKey) { this.RsaPrivateKey = rsaPrivateKey; } public JwtKey(Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters ecPrivateKey) { this.EcPrivateKey = ecPrivateKey; } } } 

Per come generare / esportare / importare chiavi RSA / ECSD con BouncyCastle, vedere il progetto chiamato “BouncyCastleTests” nello stesso repository. Lascio a te per archiviare e recuperare in modo sicuro le tue chiavi private RSA / ECSD.

Ho verificato i risultati della mia biblioteca per HMAC-ShaXXX e RSA-XXX con JWT.io – sembra che siano OK.
Anche l’ECSD dovrebbe essere OK, ma non l’ho provato contro nulla.
Comunque, non ho eseguito test approfonditi, FYI.

L’opzione più semplice che ho trovato finora è OpenIddict . Dici di voler evitare Entity Framework e OpenIddict – quindi dovrai fare molto codice, riscrivere efficacemente parti di OpenIddict e ASOS (che OpenIddict usa) per fare quello che stanno facendo comunque.

Se stai bene usando OpenIddict, questa è praticamente tutta la configurazione di cui avrai bisogno, di seguito. È molto semplice.

Se non vuoi usare EF, è ansible con OpenIddict. Non sono sicuro di come ma questo è il pezzo che dovrai capire.

ConfigureServices:

 services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders() .AddOpenIddictCore(config => config.UseEntityFramework()); // this line is for OpenIddict 

Configurazione

 app.UseOpenIddictCore(builder => { // tell openiddict you're wanting to use jwt tokens builder.Options.UseJwtTokens(); // NOTE: for dev consumption only! for live, this is not encouraged! builder.Options.AllowInsecureHttp = true; builder.Options.ApplicationCanDisplayErrors = true; }); // use jwt bearer authentication app.UseJwtBearerAuthentication(options => { options.AutomaticAuthenticate = true; options.AutomaticChallenge = true; options.RequireHttpsMetadata = false; // these urls must match the value sent in the payload posted from the client side during login options.Audience = "http://localhost:58292/"; options.Authority = "http://localhost:58292/"; }); 

Ci sono una o due altre cose minori, come ad esempio il tuo DbContext deve derivare da OpenIddictContext .

Puoi vedere una spiegazione completa (inclusi i link al repository github) su questo post del blog: http://capesean.co.za/blog/asp-net-5-jwt-tokens/

Se tutto ciò di cui hai bisogno è l’autenticazione con un provider OAuth / OpenID esterno (come Google, GitHub, Facebook, Account Microsoft ecc.), Allora non hai bisogno di strumenti di terze parti.

I provider di autenticazione per i provider OAuth e OpenID più comunemente utilizzati sono già forniti con ASP.NET Core nei pacchetti Microsoft.AspNetCore.Authorization.* . Controlla gli esempi forniti sul repository GitHub del repository ” Security ”

Se è necessario creare i propri token JWT, è necessario un server OAuth / OpenID. OpenIddict è un server di authorization facile da configurare. Per questo è necessaria una qualche forma di database, poiché i provider esterni verranno utilizzati per autenticare la persona, ma è anche necessario che abbiano un account sul server delle autorizzazioni.

Se hai bisogno di più personalizzazione e più controllo del stream, devi utilizzare ASOS o IdentityServer4 (attualmente supportato solo su ASP.NET Core quando si lavora con .NET Framework o Mono. Core runtime non è ancora supportato per quanto ne so .

C’è anche una Gitter Chatroom per OpenIddict su https://gitter.im/openiddict/core e https://gitter.im/aspnet-contrib/AspNet.Security.OpenIdConnect.Server per ASOS.

C’è un esempio completo per ASP.NET Core + JWT Auth + SQL Server + Swagger: https://github.com/wilsonwu/netcoreauth

Spero che questo possa aiutarti.

Protezione dell’API Web ASP.NET Core 2.0 con autenticazione basata su Token del portatore JWT standard

https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login

& applica il filtro di authorization come segue

  [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]