【问题标题】:Retrieve Azure AD token on Blazor Server在 Blazor 服务器上检索 Azure AD 令牌
【发布时间】:2022-01-04 15:23:24
【问题描述】:

我有一个 Blazor Server 应用程序,我设法通过 Azure AD 进行身份验证,但我无法检索 Azure AD 令牌。我有以下内容:

_Host.cshtml:

@{
Layout = null;


var tokens = new InitialApplicationState
{
    AccessToken = await HttpContext.GetTokenAsync("access_token"),
    RefreshToken = await HttpContext.GetTokenAsync("refresh_token")
};
}

<component type="typeof(App)" param-InitialState="tokens" render-mode="ServerPrerendered" />

Startup.cs:

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
    options.ResponseType = OpenIdConnectResponseType.Code;
    options.SaveTokens = true;

    options.Scope.Add("User.Read");
});
services.AddControllersWithViews()
    .AddMicrosoftIdentityUI();
services.AddAuthorization(options =>
{
    options.FallbackPolicy = options.DefaultPolicy;
});
services.AddScoped<TokenProvider>();

TokenProvider.cs:

public class TokenProvider
{
    public string AccessToken { get; set; }
    public string RefreshToken { get; set; }
}

InitialApplicationState.cs:

public class InitialApplicationState
{
    public string AccessToken { get; set; }
    public string RefreshToken { get; set; }
}

GradingApiService.cs:

public class GradingApiService : IGradingApiService
    {
        private readonly HttpClient _httpClient;
        private readonly IConfiguration _configuration;
        private readonly TokenProvider _tokenProvider;

    public GradingApiService(HttpClient httpClient, IConfiguration configuration, TokenProvider tokenProvider)
    {
        _httpClient = httpClient;
        _configuration = configuration;
        _tokenProvider = tokenProvider;
    }

    public async Task<Gradings> GetRiskAppetiteGradingByQuoteID()
    {
        try
        {
            var token = _tokenProvider.AccessToken;
            var request = new HttpRequestMessage(HttpMethod.Get,
                "https://grading-api-func-uks-tst.azurewebsites.net/api/Gradings/a0999a23-b275-4993-a959-6185cd769c0a");
            request.Headers.Add("Authorization", $"Bearer {token}");
            var response = await _httpClient.SendAsync(request);
            response.EnsureSuccessStatusCode();

            return await response.Content.ReadAsAsync<Gradings>();
        }
        catch
        {
            return new Gradings();
        }
    }
}

所以每当我检索令牌时,我都会获得一个空值。你能帮我理解这有什么问题吗?

非常感谢。

【问题讨论】:

  • 如果我的回答对您有帮助,您可以接受它作为答案(单击答案旁边的复选标记将其从灰色切换为已填充)。这对其他社区成员可能是有益的。谢谢

标签: azure azure-active-directory blazor token blazor-server-side


【解决方案1】:

请检查引用是否可以解决,并检查您是否遗漏了任何配置:

确保您选中标记访问令牌和 id 令牌

如果您调用 api,请尝试添加客户端密码(仅在需要时)

如果可以在 app.razor 页面初始化组件

在 app.razor 组件中

@using BlazorserverDemoApp.Data
@inject TokenProvider TokensProvider 


<CascadingAuthenticationState>
…
</CascadingAuthenticationState>

@code{
    [Parameter]
 public InitialApplicationState InitialState { get; set; }

    protected override Task OnInitializedAsync()
    {
        TokensProvider.AccessToken = InitialState.AccessToken;
        TokensProvider.RefreshToken = InitialState.RefreshToken;

        return base.OnInitializedAsync();
    }
}

请包含 services.AddRazorPages();如果在 services.AddScoped(); 之前使用它;

添加您的 api 的范围usually User.Read is the graph endpoint,因此请在此处为您的 api 提供门户中提供的范围。并添加endpoints.MapControllers();

 public void ConfigureServices(IServiceCollection services)
    {
    
            services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
                .AddAzureAD(options => Configuration.Bind("AzureAd", options));

            services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
            {
                options.ResponseType = "code";
                options.SaveTokens = true;

                options.Scope.Add("offline_access");
                options.Scope.Add("<<scope>>");      //add the scope of your api 
                options.Resource = "<<resource>>";
            });

            services.AddHttpClient();                   //add this
            services.AddScoped<TokenProvider>();

            services.AddControllersWithViews(options =>
            {
                var policy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            }).AddMicrosoftIdentityUI();;

            services.AddRazorPages();
            services.AddServerSideBlazor();             //this is important
                    .AddMicrosoftIdentityConsentHandler();   
            services.AddTransient<WeatherForecastService>();
    
  
    }

在startup.cs的configure方法中

  app.UseEndpoints(endpoints =>
        {
           // endpoints.MapRazorPages();
                    endpoints.MapControllers(); //add this
                    endpoints.MapBlazorHub();
                    endpoints.MapFallbackToPage("/_Host");
                });

请查看是否缺少标签

     <app>
        <component type="typeof(App)" param-InitialState="tokens" render-mode="ServerPrerendered" />
     </app>

在 api service side api 或 fetch.razor 中,希望你已经使用了IhttpClientFactory

       private readonly IConfiguration _configuration;
        private readonly TokenProvider _tokenProvider;

    public GradingApiService(IhttpClientFactory httpClient, IConfiguration configuration, TokenProvider tokenProvider)
    {
        _httpClient = httpClient.CreateClient();
        _configuration = configuration;
        _tokenProvider = tokenProvider;
    }

public HttpClient _httpClient { get; }

public async Task<Gradings> GetRiskAppetiteGradingByQuoteID()
    {

        Try
          { 
           var token = _tokenProvider.AccessToken;
            
           var request = new HttpRequestMessage(HttpMethod.Get, "your/api"); 

               request.Headers. Authorization=new 
             System.Net.Http.Headers.AuthenticationHeaderValue(“Bearer”, token);
            var response = await _httpClient.SendAsync(request);
            response.EnsureSuccessStatusCode();

             return await response.Content.ReadAsAsync<Gradings>();

               }
             Catch
                  {
                   //code..
                 }
         }
        

参考资料:

  1. Quickstart| Microsoft Docs
  2. blazor-server-aad-sample(github.com)
  3. how-do-i-get-the-access-token | stack overflow

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-01
    • 1970-01-01
    • 2020-08-12
    • 2017-01-12
    • 2020-05-23
    • 2021-02-09
    • 1970-01-01
    • 2022-06-30
    相关资源
    最近更新 更多