【发布时间】:2021-08-19 00:45:21
【问题描述】:
我有 3 个项目 JWT.IDP、JWT.API、JWT.MVC。
- JWT.IDP - API 项目验证用户并颁发 JWT 令牌。
- JWT.API - 我的业务逻辑、CURD 等的 API 项目
- JWT.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.MVC 的启动类如下
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
};
});
}
JWT.API 的启动类如下
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" });
});
}
JWT.IDP 的启动类如下
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 设置如下
"JWT": {
"key": "C1CF4B7DC4C4175B6618DE4F55CA4",
"Issuer": "http://localhost:44318",
"Audience": "SecureApiUser",
"DurationInMinutes": 60
},
【问题讨论】:
-
这看起来与您在stackoverflow.com/questions/67662711/… 的问题相同。在任何情况下,如果您收到 500 错误,您至少需要从产生它的服务器发布错误消息/输出。
-
不,肖恩,问题不同。在那里,我想知道如何将 JWT 传递给我得到答案的 API,在将其标记为答案之后,只有我的下一个挑战出现了。因为在那里帮助我的人似乎知识渊博,我想在那里发布问题,但他没有回应这就是为什么它在这里被创建为一个新帖子。对了,你知道解决办法吗,能帮忙吗?
-
正如我所说,您确实需要说明导致 500 错误代码的实际错误是什么。查看服务器的输出或尝试从响应中提取更多信息。仅 500 个代码是不够的。
-
Shaun,我在过去 12 小时内尝试查看内部错误的原因。除了内部错误,我什么也得不到。错误出现在 LoginController 中,GetWheatherData 代码 HttpResponseMessage response = await httpClient.GetAsync(apiName);这里响应对象的 IsSuccessStatusCode 为 false,如果您在调试模式下评估响应对象,它会显示 InternalServerError。你能帮忙吗
-
你需要调试服务端代码——即
GetWeatherData中的API实现。在这种情况下,LoginController 是客户端。
标签: asp.net-core asp.net-web-api jwt