将.net core 2的JWT Authentication实现转移到asp.net web api 2

我在.net core 2应用程序中实现了JWT身份validation ,它工作正常。

我想在asp.net web api 2应用程序中使用此实现和结构但我收到错误

我的结构:

JwtTokenBuilder类:

using System; using System.Collections.Generic; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Linq; namespace solution.Authentication { public sealed class JwtTokenBuilder { private SecurityKey securityKey = null; private string subject = ""; private string issuer = ""; private string audience = ""; private Dictionary claims = new Dictionary(); private DateTime expireTime = DateTime.UtcNow.AddMinutes(30); public JwtTokenBuilder AddSecurityKey(SecurityKey securityKey) { this.securityKey = securityKey; return this; } public JwtTokenBuilder AddSubject(string subject) { this.subject = subject; return this; } public JwtTokenBuilder AddIssuer(string issuer) { this.issuer = issuer; return this; } public JwtTokenBuilder AddAudience(string audience) { this.audience = audience; return this; } public JwtTokenBuilder AddClaim(string type, string value) { this.claims.Add(type, value); return this; } public JwtTokenBuilder AddClaims(Dictionary claims) { this.claims.Union(claims); return this; } public JwtTokenBuilder AddExpiry(DateTime expireTime) { this.expireTime = expireTime; return this; } public JwtToken Build() { EnsureArguments(); var claims = new List { new Claim(JwtRegisteredClaimNames.Sub, this.subject), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) } .Union(this.claims.Select(item => new Claim(item.Key, item.Value))); var token = new JwtSecurityToken( issuer: this.issuer, audience: this.audience, claims: claims, expires: this.expireTime, signingCredentials: new SigningCredentials( this.securityKey, SecurityAlgorithms.HmacSha256)); return new JwtToken(token); } #region " private " private void EnsureArguments() { if (this.securityKey == null) throw new ArgumentNullException("Security Key"); if (string.IsNullOrEmpty(this.subject)) throw new ArgumentNullException("Subject"); if (string.IsNullOrEmpty(this.issuer)) throw new ArgumentNullException("Issuer"); if (string.IsNullOrEmpty(this.audience)) throw new ArgumentNullException("Audience"); } #endregion } } 

令牌对象:

 using System; using System.IdentityModel.Tokens.Jwt; namespace solution.Authentication { public sealed class JwtToken { private JwtSecurityToken token; internal JwtToken(JwtSecurityToken token) { this.token = token; } public DateTime ValidTo => token.ValidTo; public string access_token => new JwtSecurityTokenHandler().WriteToken(this.token); } } 

安全密钥类:

 using Microsoft.IdentityModel.Tokens; using System.Text; namespace solution.Authentication { public static class JwtSecurityKey { public static SymmetricSecurityKey Create(string secret) { return new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret)); } } } 

我的令牌控制器用于生成和返回令牌的方法

 private JwtToken getToken(User user) { DateTime startTime = DateTime.Now; DateTime expireTime = DateTime.Now.AddMinutes(60); var token = new JwtTokenBuilder() .AddSecurityKey(JwtSecurityKey.Create("SecurityKey")) .AddSubject("Subject") .AddIssuer("Issuer") .AddAudience("Audience") .AddClaim("Username", user.UserName) .AddExpiry(expireTime) .Build(); return token; } 

在.net core 2应用程序中,我使用OWIN Startup类来validation具有Authorize属性的所有控制器的令牌

控制器示例:

 namespace solution.Controllers { public class ExampleController : ApiController { [HttpPost] [Route("api/Example")] [Authorize(Policy = "Session")] public void Run() { // do something; } } } 

我的owin启动类用于validationJWT令牌:

 using System; using System.IO; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Threading.Tasks; namespace solution { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = "Issuer", ValidAudience = "Audience", IssuerSigningKey = JwtSecurityKey.Create("SecurityKey") }; options.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { return Task.CompletedTask; }, OnTokenValidated = context => { return Task.CompletedTask; } }; }); services.AddAuthorization(options => { options.AddPolicy("Session", policy => policy.RequireClaim("SessionId")); }); services.AddSignalR(); services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder .AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); }); services.AddMvc(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Use(async (context, next) => { await next(); if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value) && !context.Request.Path.Value.StartsWith("/api/", StringComparison.OrdinalIgnoreCase)) { context.Request.Path = "/index.html"; await next(); } }); app.UseDeveloperExceptionPage(); app.UseAuthentication(); app.UseMvcWithDefaultRoute(); app.UseDefaultFiles(); app.UseStaticFiles(); app.UseCors(policyName: "CorsPolicy"); app.UseSignalR(routes => { }); } } } 

我想在asp.net web api中使用这个结构只改变owin类,这可能吗? 请帮我改变

结构更改将我的实现从.net core 2转移到asp.net web api 2

我使用System.IdentityModel.Tokens.Jwt命名空间来生成和validationJWT令牌。

.net core 2与System.IdentityModel.Tokens.Jwt version="5.1.4"兼容,但asp.net web api 2与System.IdentityModel.Tokens.Jwt version="4.0.2"兼容

包版本中的相同更改对代码进行了更改,也是代码的一部分,我使用System.IdentityModel.Tokens命名空间而不是Microsoft.IdentityModel.Tokens因为更改了包版本。

代码更改:

JwtTokenBuilder类:

在此类中更改SigningCredentials参数设置

  var token = new JwtSecurityToken( issuer: this.issuer, audience: this.audience, claims: claims, expires: this.expireTime, signingCredentials: new System.IdentityModel.Tokens.SigningCredentials( this.securityKey, Microsoft.IdentityModel.Tokens.SecurityAlgorithms.HmacSha256Signature , Microsoft.IdentityModel.Tokens.SecurityAlgorithms.HmacSha256Signature)); 

安全密钥类:

更改安全密钥生成方法

 using System.IdentityModel.Tokens; using System.Text; namespace solution.Authentication { public static class JwtSecurityKey { public static SymmetricSecurityKey Create(string secret) { return new InMemorySymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)); } } } 

控制器属性:

 namespace solution.Controllers { public class ExampleController : ApiController { [HttpPost] [Route("api/Example")] [System.Web.Http.Authorize] public void Run() { // do something; } } } 

我的主要更改是在Startup OWIN类中,并将Microsoft.Owin.Security.Jwt包版本从“3.1.0”更改为“3.0.0”,以validation传入请求的JWT令牌。

执行:

 using Microsoft.Owin; using Owin; using System.Web.Http; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Jwt; [assembly: OwinStartup(typeof(solution.Startup))] namespace solution { public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); HttpConfiguration config = new HttpConfiguration(); config.MapHttpAttributeRoutes(); ConfigureOAuth(app); app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); app.UseWebApi(config); } public void ConfigureOAuth(IAppBuilder app) { var issuer = "issuer"; var audience = "audience"; var secret = JwtSecurityKey.Create("SecurityKey").GetSymmetricKey(); // Api controllers with an [Authorize] attribute will be validated with JWT var option = new JwtBearerAuthenticationOptions { AuthenticationMode = AuthenticationMode.Active, AllowedAudiences = new[] { audience }, IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[] { new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret) } }; app.UseJwtBearerAuthentication( option ); } } }