Наконец-то я это сделал .. Прежде всего, я понял, что важно понять связь между ApiResource -> Scopes
, Clients -> AllowedScopes
. Я предлагаю вам прочитать части о них в документах и здесь
Когда клиент зарегистрирован на identityserver, а затем выбрать конечные точки API ( например: организация, сотрудник, календарь ) они должны быть зарегистрированы как разрешенные. Области клиента ( они живут в таблице ClientScopes ), я делал это правильно. То, что я делал неправильно, я предполагаю, что все эти области являются ApiResources ( для моего случая, потому что все мои apis живут на том же хосте, который я называю CommonServiceApi, только одно приложение веб-API ). Я переопределил свои ApiResources и его области следующим образом:
new ApiResource("commonserviceapi", "Common Service API")
{
Scopes = {
new Scope("calender_api", "Calender Api"),
new Scope("employee_api", "Employee Api"),
new Scope("organization_api", "Organization Api"),
}
}
На стороне API конечные точки должны быть авторизованы с помощью политик, как указано здесь . В маркере доступа разрешенные области запрашивающего клиента передаются в приложение API, поэтому API предоставляет доступ в соответствии с этими значениями.
Итак, Api Запуск
services.AddAuthentication("Bearer").AddJwtBearer(opt =>
{
opt.Authority = "http://localhost:5000";
opt.Audience = "commonserviceapi";
opt.RequireHttpsMetadata = false;
});
services.AddAuthorization(options =>
{
options.AddPolicy("ApiEmployee", builder =>
{
builder.RequireScope("employee_api");
});
options.AddPolicy("ApiOrganization", builder =>
{
builder.RequireScope("organization_api");
});
});
И Api Контроллеры
[Authorize(Policy = "ApiEmployee")]
[Route("api/[controller]")]
[ApiController]
public class EmployeeController : BaseController
{
...
RequireScope
- это, кстати, метод расширения пакета IdentityServer4.AccessTokenValidation
. Вы должны включить этот пакет в свой проект API.
И, наконец, это меня смутило;при запросе токена доступа с сервера параметр области должен быть пустым , так как identityserver берет его из значений allowdScopes клиента. Почти все образцы заполняли это поле, поэтому можно подумать, что оно должно быть заполнено.