#c# #azure #asp.net-core #active-directory #blazor-server-side
Вопрос:
- Я успешно внедрил проверку подлинности azure ad. Я могу войти в систему и отобразить имя пользователя.
- Теперь мне нужно вызвать api graph, чтобы получить доступ к адресу электронной почты пользователя. У меня есть тип токена, установленный для токенов «ID» на портале azure.
Индекс.Бритва
Code {
private HttpClient _httpClient;
public string Name { get; set; }
public string userDisplayName = "";
//this is what I am using to get the user's name
protected override async Task OnInitializedAsync()
{
var authstate = await Authentication_.GetAuthenticationStateAsync();
var user = authstate.User.Identity.Name;
if (user != null)
{
Name = user;
// 1) this is what I'm trying to use right now.
//The Graph API SDK
var attempt= await GraphServiceClient.Me.Request().GetAsync();
}
else
{
Name = "";
}
/*
// 2)this is what I've tried to use to access the graph api
_httpClient = HttpClientFactory.CreateClient();
// get a token
var token = await TokenAcquisitionService.GetAccessTokenForUserAsync(new string[] { "User.Read" });
// make API call
_httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var dataRequest = await _httpClient.GetAsync("https://graph.microsoft.com/beta/me");
if (dataRequest.IsSuccessStatusCode)
{
var userData = System.Text.Json.JsonDocument.Parse(await dataRequest.Content.ReadAsStreamAsync());
userDisplayName = userData.RootElement.GetProperty("displayName").GetString();
}
}
Startup.cs
var initialScopes = Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
.AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
.AddInMemoryTokenCaches();
services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy
options.FallbackPolicy = options.DefaultPolicy;
});
services.AddRazorPages();
services.AddAuthorization();
services.AddServerSideBlazor()
.AddMicrosoftIdentityConsentHandler();
Appsettings.json
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
"TenantId": "xxxxxxxxxxxxxxxxxxxxxxxxx",
"ClientId": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
"CallbackPath": "/.auth/login/aad/callback",
"ClientSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"DownstreamApi": {
"BaseUrl": "https://graph.microsoft.com/beta",
"Scopes": "user.read"
},
Когда я пытаюсь выполнить запрос с помощью 1-го опробованного метода, упомянутого в файле Index.razor выше (я прокомментировал его цифрой 1) Я получаю сообщение об ошибке: «MSAL.Чистая Ни одна учетная запись или подсказка для входа в систему не была передана на вызов AcquireTokenSilent»
Более подробная информация:
Это изображение моих делегированных разрешений, установленных на портале azure
Наконец: это ссылка на пример, которому я следовал. https://github.com/wmgdev/BlazorGraphApi
Комментарии:
1. Вы уверены, что электронное письмо еще не находится в состоянии проверки подлинности?
2. Просто проверил список претензий и увидел указанный адрес электронной почты. Есть ли конкретный способ получить к нему доступ или мне следует просто взять элемент из списка?
3. Вы можете сделать » authstate.User.Claims. Одиночный(c => c.Тип == «электронная почта»), однако я только что проверил, и у меня есть «имя» и «upn», а не «электронная почта», хотя их значения сформированы как адреса электронной почты.
Ответ №1:
Вы можете добавить необязательное утверждение «электронная почта», если у вас есть контроль над регистрацией приложения Azure AD:
После этого у вас будет претензия «адрес электронной почты» в authstate.User.Claims
Я только что попробовал это в своем приложении Blazor, и оно отлично работает. Я думаю, что, возможно, там не будет свойства электронной почты, поэтому убедитесь, что вы отключили проверку и т. Д.
Ответ №2:
Вы можете использовать @context.User.Claims
для получения имени для входа, в случае, если имя для входа совпадает с адресом электронной почты, как обычно.
< AuthorizeView>
< Authorized>
Hello, @context.User.Claims.First( cl => cl.Type.ToString()=="preferred_username").Value
</Authorized>
<NotAuthorized>
<a href="authentication/login">Log in</a>
</NotAuthorized>
</ AuthorizeView>
Получение имени пользователя для входа в компонент Blazor WASM