C# 将JWT身份验证实现从.net core 2传输到asp.net web api 2

C# 将JWT身份验证实现从.net core 2传输到asp.net web api 2,c#,authentication,asp.net-web-api2,jwt,owin,C#,Authentication,Asp.net Web Api2,Jwt,Owin,我在.NETCore2应用程序中实现了JWT身份验证,它运行良好 我想在asp.net web api 2应用程序中使用此实现和结构,但出现错误 我的结构: JwtTokenBuilder类: 安全密钥类别: 生成和返回令牌的my token controller方法: 在.net core 2应用程序中,我使用OWIN启动类对所有具有Authorize属性的控制器验证我的令牌 控制器示例: 用于验证JWT令牌的我的owin启动类: using System; using System.IO;

我在.NETCore2应用程序中实现了JWT身份验证,它运行良好

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

我的结构:

JwtTokenBuilder类:

安全密钥类别:

生成和返回令牌的my token controller方法:

在.net core 2应用程序中,我使用OWIN启动类对所有具有Authorize属性的控制器验证我的令牌

控制器示例:

用于验证JWT令牌的我的owin启动类:

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
命名空间来生成和验证Jwt令牌

.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类:

在此类中,更改
签名凭据
参数设置

  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));
    }
  }
}
控制器属性:

我的主要更改是在启动OWIN类中,并将
Microsoft.OWIN.Security.Jwt
包版本从“3.1.0”更改为“3.0.0”,以验证传入请求的Jwt令牌

实施:


您如何获得发行人安全性密钥提供程序?我只有
IssuerSecurityKeyProviders
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;
}
namespace solution.Controllers
{
  public class ExampleController : ApiController
  {
    [HttpPost]
    [Route("api/Example")]
    [Authorize(Policy = "Session")]
    public void Run()
    {
       // do something;
    }
  }  
}
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 =>
      {
      });
    }
  }
}
  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;
    }
  }  
}
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
        );
    }
  }
}