Доступ на основе ролей с использованием сервера идентификации 4 и типа предоставления учетных данных клиента
Я только начинаю работать с Identity Server 4.
Я пытаюсь защитить API с помощью типа предоставления учетных данных клиента.
У меня есть настройка API в IS4:
public static IEnumerable<ApiResource> Apis =>
new List<ApiResource>
{
new ApiResource("myapi", "Test API")
{
ApiSecrets = { new Secret("secret".Sha256() )}
}
};
У меня также есть следующая настройка клиента:
public static IEnumerable<Client> Clients =>
new List<Client>
{
new Client
{
ClientId = "testc",
ClientName= "Test Client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
{
new Secret("m2msecret".Sha256())
},
AllowedScopes = new List<string>
{
"myapi"
}
},
};
У меня есть контроллер в API, который я хотел бы защитить:
[Authorize]
public class TestController : ControllerBase {}
Если я затем создам запрос токена следующим образом:
var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "testc",
ClientSecret = "m2msecret",
Scope = "myapi",
});
Это позволяет мне вызывать API и получать доступ к ресурсу. Отлично!
Но я бы хотел защитить контроллер ролью, например
[Authorize(Roles = "admin")]
public class TestController : ControllerBase {}
Итак, мои 2 вопроса:
1. Как настроить авторизацию на основе ролей с использованием учетных данных клиента?
2: Поскольку учетные данные клиента не связаны с пользователем, как я могу вести контрольный журнал изменений записей, например, поставщик X был обновлен с помощью userId 5 и т. Д.
Благодарность
2 ответа
Я понимаю что ты имеешь ввиду. Но клиенты не являются пользователями, поэтому вы не можете назначать роли клиенту.
Сделаем шаг назад. Ресурс - это то, что вы хотите защитить. В IdentityServer вы можете дать ресурсу логическое имя, логическое, потому что у вас может быть несколько API, которые являются частью одного ресурса. И, что менее очевидно, у ресурса есть как минимум одна область видимости. В примерах ресурс имеет имя Api1 и область действия Api1.
Клиент может получить доступ к ресурсу только в том случае, если для него настроена хотя бы одна разрешенная область. Потому что это имя api, которое используется для доступа к ресурсу.
Чтобы ограничить доступ на основе областей, вам необходимо протестировать области, включенные в токен. И это ключевой момент: вместо использования ролей вы должны использовать политики, соответствующие области действия. В вашем стартапе:
services.AddAuthorization(option =>
{
option.AddPolicy("testing", p => p.RequireScope("myapp.test"));
});
И в контроллере:
[Authorize("testing")]
public class TestController : ControllerBase {}
Обратите внимание: части, которые не защищены политиками, подобными приведенным выше, будут разрешены всем клиентам, у которых есть хотя бы одна область действия ресурса, независимо от ее области.
Я предлагаю вам разделить ваш ресурс на логические части (области) и настроить клиентов, чтобы определить, какой клиент может получить доступ к какой области (части ресурса).
Тип клиента не имеет значения. Это работает для типа предоставления учетных данных клиента, но также и с интерактивными клиентами. Хотя в этом случае доступ может быть ограничен авторизацией пользователя.
Что касается отслеживания пользователей. Для интерактивных клиентов пользователь доступен в дополнительном требовании. С авторизацией пользователя вы можете использовать роли.
Для потока учетных данных клиента такая информация должна быть частью запроса (данных).
Для вашего дизайна вы можете использовать отдельные контроллеры для разных типов клиентов и авторизации пользователей, которые могут вызывать одни и те же службы.
1. Как настроить авторизацию на основе ролей с использованием учетных данных клиента? 2: Поскольку учетные данные клиента не связаны с пользователем, как я могу вести контрольный журнал изменений записей, например, поставщик X был обновлен с помощью userId 5 и т. Д.
В частности, существует разница между авторизацией пользователя и учетными данными клиента. Авторизация пользователя - это то, что будет проверять ваш API. Учетные данные клиента используются для доступа к другой службе. Вы бы не использовали свои собственные учетные данные клиента для доступа к собственной службе.
Для вашей конкретной реализации вам может потребоваться создать множество политик, соответствующих вашим конкретным ситуациям с разрешениями:
services.AddAuthorization(option =>
{
option.AddPolicy("PoliyExample", p => p.Require(...));
});
Однако это не всегда лучший вариант. В общем, лучше передать токен идентификации пользователя вашему серверу авторизации для явной обработки этой проверки. Таким образом, вы можете избежать необходимости в clientId и secret. Поскольку ваши пользователи уже прошли проверку подлинности, все, что осталось, - это вызвать микросервис авторизации, который выполняет проверку. (Например, с IdentityServer вы можете использовать что-то вроде PolicyServer или Authress.