Ответ 1
Я боролся с той же проблемой в течение нескольких дней, прежде чем приступить к решению. Отвечая на ваш вопрос: да, вы должны иметь возможность вернуть адрес электронной почты в свои заявки до тех пор, пока вы:
- Включите область
profile
илиemail
в свой запрос и - Настройте приложение в разделе Active Directory Azure Portal, чтобы включить вход и просмотр профиля пользователя в разделе "Разрешенные разрешения".
Обратите внимание, что адрес электронной почты не может быть возвращен в претензии email
: в моем случае (после того, как я получил его работу) он возвращается в заявку name
.
Однако не получить адрес электронной почты вообще может быть вызвана одной из следующих проблем:
Отсутствует адрес электронной почты, связанный с учетной записью Azure AD
В соответствии с этим руководством по Области, разрешения и согласие в конечной точке Azure Active Directory v2.0, даже если вы включили email
область действия, на которую вы не сможете получить адрес электронной почты:
Заявка
Если вы снова получите другие претензии, связанные с профилем (например, given_name
и family_name
), это может быть проблемой.
Претензии, отбрасываемые промежуточным программным обеспечением
Это было причиной для меня. Я не получал никаких претензий, связанных с профилем (имя, фамилия, имя пользователя, адрес электронной почты и т.д.).
В моем случае стек обработки идентичности выглядит следующим образом:
- IdentityServer3
- IdentityServer3.AspNetIdentity
- Пользовательский поставщик хранилища Couchbase на основе couchbase-aspnet-identity
Проблема была в классе IdentityServer3.AspNetIdentity AspNetIdentityUserService
: метод InstantiateNewUserFromExternalProviderAsync()
выглядит следующим образом:
protected virtual Task<TUser> InstantiateNewUserFromExternalProviderAsync(
string provider,
string providerId,
IEnumerable<Claim> claims)
{
var user = new TUser() { UserName = Guid.NewGuid().ToString("N") };
return Task.FromResult(user);
}
Обратите внимание, что он проходит в коллекции претензий, затем игнорирует его. Моим решением было создать класс, полученный из этого, и переопределить метод примерно так:
protected override Task<TUser> InstantiateNewUserFromExternalProviderAsync(
string provider,
string providerId,
IEnumerable<Claim> claims)
{
var user = new TUser
{
UserName = Guid.NewGuid().ToString("N"),
Claims = claims
};
return Task.FromResult(user);
}
Я не знаю точно, какие компоненты промежуточного программного обеспечения вы используете, но легко увидеть исходные претензии, возвращенные вашим внешним поставщиком; что, по крайней мере, скажут вам, что они вернутся в норму и что проблема находится где-то в вашем промежуточном программном обеспечении. Просто добавьте свойство Notifications
к вашему объекту OpenIdConnectAuthenticationOptions
, например:
// Configure Azure AD as a provider
var azureAdOptions = new OpenIdConnectAuthenticationOptions
{
AuthenticationType = Constants.Azure.AuthenticationType,
Caption = Resources.AzureSignInCaption,
Scope = Constants.Azure.Scopes,
ClientId = Config.Azure.ClientId,
Authority = Constants.Azure.AuthenticationRootUri,
PostLogoutRedirectUri = Config.Identity.RedirectUri,
RedirectUri = Config.Azure.PostSignInRedirectUri,
AuthenticationMode = AuthenticationMode.Passive,
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = context =>
{
// Log all the claims returned by Azure AD
var claims = context.AuthenticationTicket.Identity.Claims;
foreach (var claim in claims)
{
Log.Debug("{0} = {1}", claim.Type, claim.Value);
}
return null;
}
},
SignInAsAuthenticationType = signInAsType // this MUST come after TokenValidationParameters
};
app.UseOpenIdConnectAuthentication(azureAdOptions);
См. также
- В этой статье Скотта Брэди содержится раздел о Преобразовании Претензий, который может быть полезен, если ни одно из указанных выше не исправляет его.
- Это обсуждение учетной записи IdentityServer3 GitHub стало для меня огромной помощью, особенно этот ответ.