ASP.NET Core 1.0 Web API中的简单JWT身份validation

我正在寻找最简单的方法来设置一个使用JWTs在ASP.NET Core(又名ASP.NET 5)中进行身份validation的Web API服务器。 这个项目( 博客文章 / github )正是我正在寻找,但它使用ASP.NET 4。

我只是想能够:

  1. 设置一个login路由,可以创build一个JWT令牌并将其返回到头部。 我将这与现有的RESTful服务集成,这将告诉我,如果用户名和密码是有效的。 在ASP.NET 4项目中,我正在看这可以通过以下路线完成https://github.com/stewartm83/Jwt-WebApi/blob/master/src/JwtWebApi/Controllers/AccountController.cs#L24- L54

  2. 拦截传入的请求到需要授权的路由,解密并validation来自头部的JWT令牌,并使JWT令牌的有效载荷中的用户信息可以被路由访问。 例如像这样的: https : //github.com/stewartm83/Jwt-WebApi/blob/master/src/JwtWebApi/App_Start/AuthHandler.cs

我在ASP.NET Core中看到的所有例子都非常复杂,并且依赖于我希望避免的OAuth,IS,OpenIddict和EF中的一些或全部。

任何人都可以指向我如何在ASP.NET Core做到这一点的例子,或帮助我开始呢?

编辑:回答我结束了使用这个答案: https : //stackoverflow.com/a/33217340/373655

注意/更新:

下面的代码是为.NET Core 1.1
由于.NET Core 1是如此非常RTM,authentication从.NET Core 1跳转到2.0(又名[部分修改])。
这就是为什么下面的代码不再适用于.NET Core 2.0的原因。
但它仍然是一个有用的阅读。


Necromancing。
我深入了解智威汤逊。 这是我的发现:

您需要添加Microsoft.AspNetCore.Authentication.JwtBearer

那么你可以设置

app.UseJwtBearerAuthentication(bearerOptions); 

在Startup.cs中=>configuration

bearerOptions由您定义,例如

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

其中CustomBearerEvents是你可以添加标记数据到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 { /// <summary> /// Invoked if exceptions are thrown during request processing. The exceptions will be re-thrown after this event unless suppressed. /// </summary> public Func<AuthenticationFailedContext, Task> OnAuthenticationFailed { get; set; } = context => Task.FromResult(0); /// <summary> /// Invoked when a protocol message is first received. /// </summary> public Func<MessageReceivedContext, Task> OnMessageReceived { get; set; } = context => Task.FromResult(0); /// <summary> /// Invoked after the security token has passed validation and a ClaimsIdentity has been generated. /// </summary> public Func<TokenValidatedContext, Task> OnTokenValidated { get; set; } = context => Task.FromResult(0); /// <summary> /// Invoked before a challenge is sent back to the caller. /// </summary> public Func<JwtBearerChallengeContext, Task> 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); } } 

而tokenValidationParameters是由你定义的,例如

 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, }; 

MyTokenHandler可以自定义,如果你想定制令牌validation,例如

 // 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<System.Security.Claims.Claim> ls = new System.Collections.Generic.List<System.Security.Claims.Claim>(); 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(); } } 

棘手的部分是如何获得AsymmetricSecurityKey,因为你不想传递一个rsaCryptoServiceProvider,因为你需要crypto格式的互操作性。

创造沿着

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

例如从DER证书的BouncyCastle:

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

随后,您可以添加包含JWT载体的自定义Cookie格式:

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

其中CustomJwtDataFormat是沿着

 public class CustomJwtDataFormat : ISecureDataFormat<AuthenticationTicket> { 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<AuthenticationTicket>.Protect(AuthenticationTicket data) { return MyProtect(data, null); } string ISecureDataFormat<AuthenticationTicket>.Protect(AuthenticationTicket data, string purpose) { return MyProtect(data, purpose); } AuthenticationTicket ISecureDataFormat<AuthenticationTicket>.Unprotect(string protectedText) { return MyUnprotect(protectedText, null); } AuthenticationTicket ISecureDataFormat<AuthenticationTicket>.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<System.Security.Claims.Claim> ls = new System.Collections.Generic.List<System.Security.Claims.Claim>(); 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"); } } 

您也可以使用Microsoft.IdentityModel.Token创buildJWT令牌:

 // 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<Claim>() { 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 //(<Base64UrlEncoded header>.<Base64UrlEncoded body>.<signature>) JwtSecurityToken parsedJwt = tokenHandler.ReadToken(jwtToken) as JwtSecurityToken; TokenValidationParameters validationParams = new TokenValidationParameters() { RequireExpirationTime = true, ValidAudience = SecurityConstants.TokenAudience, ValidIssuers = new List<string>() { SecurityConstants.TokenIssuer }, ValidateIssuerSigningKey = true, ValidateLifetime = true, IssuerSigningKey = sSKey, }; SecurityToken secT; return tokenHandler.ValidateToken("token", validationParams, out secT); } private static SecurityTokenDescriptor makeSecurityTokenDescriptor(SecurityKey sSKey, List<Claim> 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) }; } } 

请注意,因为您可以为Cookie中的其他用户提供http-headers(承载)或您指定的任何其他身份validation方法,所以您实际上可以拥有超过1个用户!


看看这个:
https://stormpath.com/blog/token-authentication-asp-net-core

它应该是你正在寻找的。

还有这两个:

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/

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

而JWT-Bearer来源https://github.com/aspnet/Security/tree/master/src/Microsoft.AspNetCore.Authentication.JwtBearer


如果您需要超高安全性,则应通过每次请求更新票证来防止重播攻击,并且在某个超时之后以及用户注销后(不仅在有效期满后)使旧票无效。


对于那些最终从这里通过谷歌,你可以实现cookie身份validationTicketDataFormat当你想使用自己的JWT版本。

我不得不考虑JWT的工作,因为我们需要确保我们的应用程序。
因为我仍然需要使用.NET 2.0,所以我必须编写自己的库。

我已经把这个结果移植到了.NET Core上。 你可以在这里find它: https : //github.com/ststeiger/Jwt_Net20/tree/master/CoreJWT

它不使用任何数据库,这不是JWT库的工作。
获取和设置数据库数据是您的工作。
该库允许在.NET Core中使用IANA JOSE任务中列出的JWT RFC中指定的所有algorithm进行JWT授权和validation。
至于为pipe道添加授权并为路由添加值 – 这两件事情应该分开进行,我认为你最好自己做。

您可以在ASP.NET Core中使用自定义身份validation。
查看docs.asp.net文档的“安全”类别。

或者,您可以查看没有ASP.NET身份的Cookie中间件或自定义的基于策略的授权 。

您也可以在github的auth研讨会或社交login部分或此频道9video教程中了解更多信息。
如果一切都失败了,asp.net安全的源代码在github上 。


.NET 3.5的原始项目,这是我的图书馆从哪里来的,在这里:
https://github.com/jwt-dotnet/jwt
我删除了所有对LINQ +扩展方法的引用,因为它们在.NET 2.0中不受支持。 如果您在源代码中包含LINQ或ExtensionAttribute,那么您不能只更改.NET运行时而不会收到警告; 这就是为什么我完全删除它们。
另外,我添加了RSA + ECSD JWS方法,因此CoreJWT项目依赖于BouncyCastle。
如果将自己限制为HMAC-SHA256 + HMAC-SHA384 + HMAC-SHA512,则可以删除BouncyCastle。

JWE尚未(尚)支持。

用法就像jwt-dotnet / jwt, 除了将命名空间JWT更改为CoreJWT
我还添加了PetaJSON的内部副本作为序列化程序,因此不会干扰其他人的项目依赖关系。

创build一个JWT令牌:

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

validationJWT令牌:

 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!"); } 

对于RSA和ECSA,您必须传递(BouncyCastle)RSA / ECSD私钥而不是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; } } } 

有关如何使用BouncyCastle生成/导出/导入RSA / ECSD密钥,请参阅同一个存储库中名为“BouncyCastleTests”的项目。 我把它留给你安全地存储和检索你自己的RSA / ECSD私钥。

我已经使用JWT.iovalidation了我的图书馆对HMAC-ShaXXX和RSA-XXX的结果 – 看起来他们没问题。
ECSD也可以,但是我没有对任何东西进行testing。
仅供参考,我没有进行广泛的testing。

到目前为止我发现的最简单的选项是OpenIddict 。 你说你想避免entity framework和OpenIddict – 那么你将自己做很多编码,有效地重写OpenIddict和ASOS (OpenIddict使用的)的一部分来完成他们正在做的事情。

如果你可以使用OpenIddict,这几乎是你所需要的所有configuration,下面。 这很简单。

如果你不想使用EF,那么使用OpenIddict就可以。 我不知道如何,但这是你必须弄清楚的。

ConfigureServices:

 services.AddIdentity<ApplicationUser, ApplicationRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders() .AddOpenIddictCore<Application>(config => config.UseEntityFramework()); // this line is for OpenIddict 

configuration

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

有一两个其他的小事情,比如你的DbContext需要从OpenIddictContext<ApplicationUser, Application, ApplicationRole, string>派生。

你可以在这个博客文章中看到一个完整的解释(包括github回购的链接): http : //capesean.co.za/blog/asp-net-5-jwt-tokens/

如果您只需要对外部OAuth / OpenID提供者(如Google,GitHub,Facebook,Microsoft帐户等)进行身份validation,则不需要任何第三方工具。

最常用的OAuth和OpenID提供程序的身份validation提供程序已经在Microsoft.AspNetCore.Authorization.*包中提供了ASP.NET Core。 查看“ 安全 ”存储库的GitHub存储库上提供的示例

如果您需要创build自己的JWT令牌,那么您需要一个OAuth / OpenID服务器。 OpenIddict是一个易于设置的授权服务器。 为此,您需要某种forms的数据库,因为将使用外部提供程序来validation此人,但是您还需要他们在授权服务器上拥有一个帐户。

如果你需要更多的自定义和更多的stream程控制,你必须使用ASOS或者IdentityServer4(目前只有在ASP.NET Core或者Mono下才支持ASP.NET Core),就我所知,Core运行时还不被支持。

还有一个用于OpenIddict的Gitter聊天室,位于https://gitter.im/openiddict/core和https://gitter.im/aspnet-contrib/AspNet.Security.OpenIdConnect.Server用于ASOS。;

有一个ASP.NET Core + JWT Auth + SQL Server + Swagger的完整示例: https : //github.com/wilsonwu/netcoreauth

希望这可以帮到你。