Blazor azure AD извлекает электронную почту из API graph

#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