Vì vậy, sau một ngày dài cố gắng giải quyết vấn đề này, cuối cùng tôi đã tìm ra cách Microsoft muốn chúng tôi tạo các trình xử lý xác thực tùy chỉnh cho thiết lập phần mềm trung gian mới của họ trong lõi 2.0.
Sau khi xem qua một số tài liệu về MSDN, tôi đã tìm thấy một lớp được gọi là AuthenticationHandler<TOption>
thực thi IAuthenticationHandler
giao diện.
Từ đó, tôi đã tìm thấy toàn bộ cơ sở mã với các lược đồ xác thực hiện có tại https://github.com/aspnet/Security
Bên trong một trong số này, nó cho thấy cách Microsoft triển khai lược đồ xác thực JwtBearer. ( https://github.com/aspnet/Security/tree/master/src/Microsoft.AspNetCore.Authentication.JwtBearer )
Tôi đã sao chép hầu hết mã đó vào một thư mục mới và xóa tất cả những thứ phải làm JwtBearer
.
Trong JwtBearerHandler
lớp (mở rộng AuthenticationHandler<>
), có một ghi đè choTask<AuthenticateResult> HandleAuthenticateAsync()
Tôi đã thêm vào phần mềm trung gian cũ của chúng tôi để thiết lập xác nhận quyền sở hữu thông qua máy chủ mã thông báo tùy chỉnh và vẫn gặp phải một số vấn đề với quyền, chỉ xuất hiện 200 OK
thay vì 401 Unauthorized
mã khi mã thông báo không hợp lệ và không có xác nhận quyền sở hữu nào được thiết lập.
Tôi nhận ra rằng tôi đã ghi đè Task HandleChallengeAsync(AuthenticationProperties properties)
mà vì bất kỳ lý do gì được sử dụng để đặt quyền qua [Authorize(Roles="")]
bộ điều khiển.
Sau khi loại bỏ ghi đè này, mã đã hoạt động và đã ném thành công 401
khi các quyền không khớp.
Điều rút ra chính là bây giờ bạn không thể sử dụng phần mềm trung gian tùy chỉnh, bạn phải triển khai nó thông qua AuthenticationHandler<>
và bạn phải đặt DefaultAuthenticateScheme
và DefaultChallengeScheme
khi sử dụng services.AddAuthentication(...)
.
Dưới đây là một ví dụ về tất cả những gì điều này sẽ trông như thế nào:
Trong Startup.cs / ConfigureServices () thêm:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "Custom Scheme";
options.DefaultChallengeScheme = "Custom Scheme";
})
.AddCustomAuth(o => { });
Trong Startup.cs / Configure () thêm:
app.UseAuthentication();
Tạo một tệp mới CustomAuthExtensions.cs
public static class CustomAuthExtensions
{
public static AuthenticationBuilder AddCustomAuth(this AuthenticationBuilder builder, Action<CustomAuthOptions> configureOptions)
{
return builder.AddScheme<CustomAuthOptions, CustomAuthHandler>("Custom Scheme", "Custom Auth", configureOptions);
}
}
Tạo một tệp mới CustomAuthOptions.cs
public class CustomAuthOptions: AuthenticationSchemeOptions
{
public CustomAuthOptions()
{
}
}
Tạo một tệp mới CustomAuthHandler.cs
internal class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
{
public CustomAuthHandler(IOptionsMonitor<CustomAuthOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
{
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
return AuthenticateResult.NoResult();
}
}