Tôi đang sử dụng WSO2 làm Nhà cung cấp nhận dạng (IDP). Nó đang đặt JWT trong một tiêu đề gọi là "Xác nhận X-JWT".
Để cung cấp điều này vào hệ thống ASP.NET Core, tôi đã thêm một OnMessageReceived
sự kiện. Điều này cho phép tôi đặt token
giá trị được cung cấp trong tiêu đề.
Đây là mã mà tôi phải làm điều đó (phần quan trọng là 3 dòng mã không có khung cuối cùng):
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddJwtBearer(async options =>
{
options.TokenValidationParameters =
await wso2Actions.JwtOperations.GetTokenValidationParameters();
options.Events = new JwtBearerEvents()
{
// WSO2 sends the JWT in a different field than what is expected.
// This allows us to feed it in.
OnMessageReceived = context =>
{
context.Token = context.HttpContext.Request.Headers["X-JWT-Assertion"];
return Task.CompletedTask;
}
}
};
Tất cả điều này hoạt động hoàn hảo ngoại trừ cuộc gọi đầu tiên sau khi dịch vụ khởi động. Để rõ ràng, mọi cuộc gọi, ngoại trừ cuộc gọi đầu tiên hoạt động chính xác như tôi muốn. (Nó đặt mã thông báo vào và cập nhật User
đối tượng như tôi cần.)
Nhưng đối với cuộc gọi đầu tiên, OnMessageReceived
không được nhấn. Và User
đối tượng trong bộ điều khiển của tôi không được thiết lập.
Tôi đã kiểm tra HttpContext
cuộc gọi đầu tiên đó và tiêu đề "X-JWT-Ass Ass" nằm trong Request.Headers
danh sách (có JWT trong đó). Nhưng, vì một số lý do, OnMessageReceived
sự kiện này không được gọi cho nó.
Làm thế nào tôi có OnMessageReceived
thể được gọi cho lần gọi đầu tiên của một hoạt động dịch vụ cho dịch vụ của mình?
LƯU Ý QUAN TRỌNG: Tôi đã tìm ra rằng vấn đề là async
await
trong AddJwtBearer
. (Xem câu trả lời của tôi dưới đây.) Đó là những gì tôi thực sự muốn từ câu hỏi này.
Tuy nhiên, vì tiền thưởng không thể bị hủy bỏ, tôi vẫn sẽ trao tiền thưởng cho bất kỳ ai có thể chỉ ra cách sử dụng AddJwtBearer
với async
await
nơi đang chờ HttpClient
cuộc gọi thực tế . Hoặc hiển thị tài liệu về lý do tại sao async
await
không được sử dụng với AddJwtBearer
.
async
await
không hoạt động tốt với đường ống cuộc gọi.)
AddJwtBearer
(và bên dưới AuthenticationBuilder.AddSchemeHelper
) không mong đợi các cuộc gọi async trong đó - nó chỉ thêm IConfigureOptions vào serices. OnMessageReceived
, mặt khác - đang được chờ đợi trên. Vì vậy, tôi tự hỏi nếu bạn có khả năng có thể làm cho OnMessageReceived
lambda không đồng bộ, chuyển cuộc gọi http của bạn vào OnMessageReceived
cơ thể và bằng cách nào đó kết quả bộ nhớ cache trong đó?