Asp.net core 在多个项目中使用JWT令牌

Asp.net core 在多个项目中使用JWT令牌,asp.net-core,asp.net-web-api,jwt,Asp.net Core,Asp.net Web Api,Jwt,我有3个项目JWT.IDP、JWT.API、JWT.MVC IDP-API项目验证用户并发布JWT令牌 JWT.API-用于我的业务逻辑、CURD等的API项目 MVC-一个用于UI的MVC应用程序 我的意图是使用JWT.IDP中生成的这个令牌,并从JWT.MVC调用JWT.API函数 IDP令牌工作得非常好,我可以生成令牌,我的JWT.MVC登录控制器可以接收它。但是当我试图使用这个令牌访问JWT.API时,它给出了一个500错误(请参阅下面代码中的最后一个函数(GetWeatherData)

我有3个项目JWT.IDP、JWT.API、JWT.MVC

  • IDP-API项目验证用户并发布JWT令牌
  • JWT.API-用于我的业务逻辑、CURD等的API项目
  • MVC-一个用于UI的MVC应用程序
  • 我的意图是使用JWT.IDP中生成的这个令牌,并从JWT.MVC调用JWT.API函数

    IDP令牌工作得非常好,我可以生成令牌,我的JWT.MVC登录控制器可以接收它。但是当我试图使用这个令牌访问JWT.API时,它给出了一个500错误(请参阅下面代码中的最后一个函数(GetWeatherData))

    有人能帮忙吗,我不是一个高级用户,下面写的代码取自几个示例。所以我不确定它是否真的是正确的代码

    namespace JWT.MVC.Controllers
    {
        public class LoginController : Controller
        {
    
            public IActionResult DoLogin()
            {
    
                return View();
            }
    
    
            [HttpPost]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> DoLogin([Bind("EmailOrName,Password")] LoginRequestModel loginRequestModel)
            {
                var apiName = $"https://localhost:44318/api/User/login";
    
                HttpClient httpClient = new HttpClient();
                HttpResponseMessage response = await httpClient.PostAsJsonAsync(apiName, loginRequestModel);
                var jasonString = await response.Content.ReadAsStreamAsync();
    
                var data = await JsonSerializer.DeserializeAsync<IEnumerable<AccessibleDb>>
                        (jasonString, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
    
                foreach (var item in data)
                {
                    item.UserName = loginRequestModel.EmailOrName;
                }
    
                return View("SelectDatabase" , data);
            }
    
          
            public async Task<IActionResult> PostLogin(string db, string user)
            {
                TokenRequestModel tokenRequestModel = new TokenRequestModel() { Database = db, UserName = user };
    
                var apiName = $"https://localhost:44318/api/User/tokenonly";
    
                HttpClient httpClient = new HttpClient();
                HttpResponseMessage response = await httpClient.PostAsJsonAsync(apiName, tokenRequestModel);
                var jasonString = await response.Content.ReadAsStreamAsync();
    
                var data = await JsonSerializer.DeserializeAsync<AuthenticationModel>
                        (jasonString, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
    
                var stream = data.Token;
                var handler = new JwtSecurityTokenHandler();
                var jsonToken = handler.ReadToken(stream);
                var tokenS = jsonToken as JwtSecurityToken;
                var selectedDb = tokenS.Claims.First(claim => claim.Type == "Database").Value;
    
                ViewBag.SelectedDb = selectedDb;
    
                return View(data);
            }
    
            public async Task<IActionResult> GetWeatherData(string token)
            {
    
                var apiName = $"https://localhost:44338/weatherforecast";
    
                HttpClient httpClient = new HttpClient();
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
                HttpResponseMessage response = await httpClient.GetAsync(apiName);
                if (!response.IsSuccessStatusCode)
                {
                    ViewBag.Error = response.StatusCode;
                    return View("Weatherdata");
                }
                var jasonString = await response.Content.ReadAsStreamAsync();
                var data = await JsonSerializer.DeserializeAsync<WeatherForecast>
                        (jasonString, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
    
            
                return View("Weatherdata" , data);
            }
        }
    }
    
    JWT.API的启动类如下

    
     public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllersWithViews();
                services.AddAuthentication("Bearer")
                 .AddJwtBearer("Bearer", options =>
                 {
    
                     options.Audience = "SecureApiUser";
                     options.Authority = "https://localhost:44318";
                     options.TokenValidationParameters = new TokenValidationParameters
                     {
                         ValidateAudience = false
                     };
                 });
    
              
            }
    
    
    
      public void ConfigureServices(IServiceCollection services)
            {
    
                services.AddControllers();
                //Copy from IS4
                services.AddAuthentication("Bearer")
                  .AddJwtBearer("Bearer", options =>
                  {
                      
                      options.Audience = "SecureApiUser";
                      options.Authority = "https://localhost:44318";
                      options.TokenValidationParameters = new TokenValidationParameters
                      {
                          ValidateAudience = false
                      };
                  });
    
              
                //End
                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new OpenApiInfo { Title = "JWT.API", Version = "v1" });
                });
            }
    
      public void ConfigureServices(IServiceCollection services)
            {
    
                services.AddControllers();
    
                //Configuration from AppSettings
                services.Configure<JwtSettings>(Configuration.GetSection("JWT"));
                //User Manager Service
                services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<IdentityDbContext>();
                services.AddScoped<IUserService, UserService>();
                //Adding DB Context with MSSQL
                services.AddDbContext<IdentityDbContext>(options =>
                    options.UseSqlServer(
                        Configuration.GetConnectionString("IdentityDbConnectionString"),
                        b => b.MigrationsAssembly(typeof(IdentityDbContext).Assembly.FullName)));
    
                //Adding Athentication - JWT
                services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                    .AddJwtBearer(o =>
                    {
                        o.RequireHttpsMetadata = false;
                        o.SaveToken = false;
                        o.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidateIssuerSigningKey = true,
                            ValidateIssuer = true,
                            ValidateAudience = true,
                            ValidateLifetime = true,
                            ClockSkew = TimeSpan.FromMinutes(Convert.ToInt32(Configuration["JWT:DurationInMinutes"])),
                            ValidIssuer = Configuration["JWT:Issuer"],
                            ValidAudience = Configuration["JWT:Audience"],
                            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Key"]))
                        };
                    });
    
               
    
                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new OpenApiInfo { Title = "JWT.IDP", Version = "v1" });
                });
            }
    
    
     "JWT": {
        "key": "C1CF4B7DC4C4175B6618DE4F55CA4",
        "Issuer": "http://localhost:44318",
        "Audience": "SecureApiUser",
        "DurationInMinutes": 60
      },
    
    JWT.IDP的启动级别如下

    
     public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllersWithViews();
                services.AddAuthentication("Bearer")
                 .AddJwtBearer("Bearer", options =>
                 {
    
                     options.Audience = "SecureApiUser";
                     options.Authority = "https://localhost:44318";
                     options.TokenValidationParameters = new TokenValidationParameters
                     {
                         ValidateAudience = false
                     };
                 });
    
              
            }
    
    
    
      public void ConfigureServices(IServiceCollection services)
            {
    
                services.AddControllers();
                //Copy from IS4
                services.AddAuthentication("Bearer")
                  .AddJwtBearer("Bearer", options =>
                  {
                      
                      options.Audience = "SecureApiUser";
                      options.Authority = "https://localhost:44318";
                      options.TokenValidationParameters = new TokenValidationParameters
                      {
                          ValidateAudience = false
                      };
                  });
    
              
                //End
                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new OpenApiInfo { Title = "JWT.API", Version = "v1" });
                });
            }
    
      public void ConfigureServices(IServiceCollection services)
            {
    
                services.AddControllers();
    
                //Configuration from AppSettings
                services.Configure<JwtSettings>(Configuration.GetSection("JWT"));
                //User Manager Service
                services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<IdentityDbContext>();
                services.AddScoped<IUserService, UserService>();
                //Adding DB Context with MSSQL
                services.AddDbContext<IdentityDbContext>(options =>
                    options.UseSqlServer(
                        Configuration.GetConnectionString("IdentityDbConnectionString"),
                        b => b.MigrationsAssembly(typeof(IdentityDbContext).Assembly.FullName)));
    
                //Adding Athentication - JWT
                services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                    .AddJwtBearer(o =>
                    {
                        o.RequireHttpsMetadata = false;
                        o.SaveToken = false;
                        o.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidateIssuerSigningKey = true,
                            ValidateIssuer = true,
                            ValidateAudience = true,
                            ValidateLifetime = true,
                            ClockSkew = TimeSpan.FromMinutes(Convert.ToInt32(Configuration["JWT:DurationInMinutes"])),
                            ValidIssuer = Configuration["JWT:Issuer"],
                            ValidAudience = Configuration["JWT:Audience"],
                            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Key"]))
                        };
                    });
    
               
    
                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new OpenApiInfo { Title = "JWT.IDP", Version = "v1" });
                });
            }
    
    
     "JWT": {
        "key": "C1CF4B7DC4C4175B6618DE4F55CA4",
        "Issuer": "http://localhost:44318",
        "Audience": "SecureApiUser",
        "DurationInMinutes": 60
      },
    

    令人惊讶的是,没有人能够识别出这个错误。我做了以下更改,现在它工作得非常好

    MVC和API项目中的ConfigureServices如下所示。对任何其他代码没有其他更改

    
             public void ConfigureServices(IServiceCollection services)
            {
    
                services.AddControllers();
    
                var authenticationProviderKey = "IdentityApiKey";
                var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("C1CF4B7DC4C4175B6618DE4F55CA4"));
                var tokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = signingKey,
                    ValidateIssuer = true,
                    ValidIssuer = "http://localhost:44318",
                    ValidateAudience = true,
                    ValidAudience = "SecureApiUser",
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero,
                    RequireExpirationTime = true,
                };
    
                services.AddAuthentication(o =>
                {
                    o.DefaultAuthenticateScheme = authenticationProviderKey;
                })
                .AddJwtBearer(authenticationProviderKey, x =>
                {
                    x.RequireHttpsMetadata = false;
                    x.TokenValidationParameters = tokenValidationParameters;
                });
    
                //services.AddAuthentication(options =>
                //{
                //    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                //    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    
                //}).AddJwtBearer(options =>
                //{
                //    options.Authority = "https://localhost:44318"; ;
                //    options.RequireHttpsMetadata = false;
                //    options.Audience = "SecureApiUser";
                //});
    
                //End
    
                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new OpenApiInfo { Title = "JWT.API2", Version = "v1" });
                });
            }
    
    

    这看起来和你这里的问题一样。在任何情况下,如果您收到500个错误,您至少需要从生成该错误的服务器发布错误消息/输出。不,Shaun,问题是不同的。在那里,我想知道如何将JWT传递给一个API,我得到了这个API的答案,在将它标记为答案之后,我的下一个挑战出现了。因为那个在那里帮助我的人似乎很有见识,我想在那里发布这个问题,但他没有回应,这就是为什么在这里创建一个新帖子的原因。顺便问一下,你知道解决方案吗,你能帮忙吗?正如我所说的,你真的需要说出导致500错误代码的实际错误是什么。查看服务器的输出或尝试从响应中提取更多信息。仅仅一个500码是不够的。肖恩,我在过去的12个小时里试图找出内部错误的原因。我只能得到一个内部错误。错误在LoginController中,代码HttpResponseMessage response=await httpClient.GetAsync(apiName)上的GetWheatherData;此处响应对象的IsSuccessStatusCode为false,如果在调试模式下评估响应对象,则会显示InternalServerError。您是否可以帮助调试服务器代码,即
    GetWeatherData
    中的API实现。在这种情况下,LoginController是客户端。