Я использую MSAL, чтобы получить токен идентификатора, который затем используется для доступа к приложению веб-API. У меня есть пара вопросов, и мне было интересно, может ли кто-нибудь помочь мне понять, что происходит.
Позвольте мне начать с процесса аутентификации на стороне клиента. В этом случае я создаю приложение Windows Forms, которое использует следующий код для аутентификации текущего пользователя (т. Е. Для получения идентификатора токена, который будет использоваться для проверки пользователя, когда он пытается получить доступ к Интернету). Приложение API):
//constructor code
_clientApp = new PublicClientApplication(ClientId,
Authority, //which url here?
TokenCacheHelper.GetUserCache());
_scopes = new []{ "user.read" }; //what to put here?
//inside a helper method
try {
return await _clientApp.AcquireTokenSilentAsync(_scopes, _clientApp.Users.FirstOrDefault());
}
catch (MsalUiRequiredException ex) {
try {
return await _clientApp.AcquireTokenAsync(_scopes);
}
catch (MsalException ex) {
return null;
}
}
Первое, что я хотел бы очистить, - это значение, которое следует использовать для параметра полномочий. В этом случае я использую URL-адрес в форме:
https://login.microsoftonline.com/{Tenant}/oauth2/v2.0/token
Тем не менее, у меня сложилось впечатление, что мне также могло сойти с рук что-то вроде этого:
https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration
Кажется, что одна конечная точка специфична для моего Azure AD, а другая выглядит как общий (охватывающий все) URL ... Где я могу найти дополнительную информацию об этих конечных точках и о назначении каждой ...
Еще одна вещь, которую я не совсем понял, - это прицел. Я не заинтересован в запросах MS Graph (или любой другой службы, связанной с Azure). В предыдущих версиях библиотеки MSAL можно было ссылаться на одну из областей действия по умолчанию. Однако похоже, что это больше невозможно (по крайней мере, я попытался и получил исключение, в котором говорилось, что я не должен передавать области по умолчанию ...).
Передача пустой коллекции (например: new List<string>()
) или null
также приведет к ошибке. Итак, в этом случае я закончил передачу области user.read
(которая, если я не ошибаюсь, используется MS Graph API. Это явно не обязательно, но это был единственный способ получить аутентификацию. процесс работает.Любые подсказки о том, как выполнить вызов, когда вам просто нужно получить идентификатор идентификатора? Должен ли я вызывать другой метод?
Переходя на сторону сервера, у меня есть приложение веб-API, доступ к которому ограничен вызовами, которые передают токен идентификатора в заголовке аутентификации (носитель). Согласно этому образцу, я должен использовать что-то вроде этого:
private void ConfigureAuth(IAppBuilder app) {
var authority = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
app.UseOAuthBearerAuthentication(
new OAuthBearerAuthenticationOptions {
AccessTokenFormat = new JwtFormat(GetTokenValidationParameters(),
new OpenIdConnectCachingSecurityTokenProvider(authority)),
Provider = new OAuthBearerAuthenticationProvider {
OnValidateIdentity = ValidateIdentity
}
});
}
Теперь это работает, и он вернет 401 для всех запросов, у которых нет действительного идентификатора токена. Однако есть один вопрос: есть ли способ указать утверждение из идентификатора билета, которое должно использоваться для идентификации имени пользователя (User.Identity.Name
контроллера)? В этом случае я закончил обработку OnValidateIdentity
, чтобы сделать это с помощью кода, который выглядит следующим образом:
private Task ValidateIdentity(OAuthValidateIdentityContext arg) {
//username not getting correctly filled
//so, i'm handling this event in order to set it up
//from the preferred_username claim
if (!arg.HasError && arg.IsValidated) {
var identity = arg.Ticket.Identity;
var username = identity.Claims.FirstOrDefault(c => c.Type == "preferred_username")?.Value ?? "";
if (!string.IsNullOrEmpty(username)) {
identity.AddClaim(new Claim(ClaimTypes.Name, username));
}
}
return Task.CompletedTask;
}
Как вы можете видеть, я ищу утверждение primary_username из идентификатора токена (который был получен клиентом) и использую его значение для настройки утверждения Name. Есть ли какой-нибудь вариант, который позволил бы мне сделать это автоматически? Мне что-то не хватает в конфигурации OAuthBearerAuthenticationMiddleware
?