如何从blazor(服务器端)Web应用程序获取访问令牌?

时间:2020-01-24 06:25:27

标签: c# asp.net blazor blazor-server-side

2 个答案:

答案 0 :(得分:8)

以下代码段提供了一种方法,该方法可以检索在使用IdentityServer4提供程序对用户进行身份验证时发出的访问令牌。为了得到 访问令牌可以使用HttpContext对象,但是由于Blazor是基于SignalR的,因此与应用程序的连接是HTTP连接而不是WebSocket连接时,只有在HttpContext对象可用时,您才必须这样做。

检索访问令牌后,您需要将其传递给Blazor应用程序,并将其存储在本地存储中。我的代码还提供了一种在必要时解析访问令牌的方法。

  • 将文件添加到Pages文件夹并将其命名为_Host.cshtml.cs

  • 将此代码添加到文件:

     public class HostAuthenticationModel : PageModel
     {
         public async Task<IActionResult> OnGet()
         {
             if (User.Identity.IsAuthenticated)
             {
                var token = await HttpContext.GetTokenAsync("access_token");
                AccessToken = token;
    
             }
        return Page();
     }
    
     public string AccessToken { get; set; }
     }
    

注意:我已将PageModel类命名为:HostAuthenticationModel 您将需要其中一些: using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using System; using System.Linq; using System.Threading.Tasks;

  • 接下来,我们必须将AccessToken属性中存储的值传递给Blazor App:

在_Host.cshtml文件中,在文件的顶部添加模型指令:

@model HostAuthenticationModel

像这样向组件Tag Helper添加新属性:

param-AccessToken="Model.AccessToken"

最终结果:

 <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" 
                 param-AccessToken="Model.AccessToken"/>
 </app>

param-AccessToken属性要求您在 App组件中定义一个名为 AccessToken 的属性,该属性将从页面模型获取访问令牌。

  • 接下来定义将接收访问令牌的属性
  • ,然后重写OnAfterRenderAsync方法,从中调用方法 将访问令牌存储在本地存储中。

    @code{
       [Parameter]
       public string AccessToken { get; set; }
    
       protected override async Task OnAfterRenderAsync(bool firstRender)
       {
           if (firstRender)
            {
                await tokenStorage.SetTokenAsync(AccessToken);
            }
       }
     }
    

还将以下内容放在App组件的顶部:

@inject AccessTokenStorage tokenStorage
  • 接下来,您必须像这样创建AccessTokenStorage服务:

    在应用的根目录中创建一个名为 AccessTokenStorage 的类,然后添加 以下代码:

    公共类AccessTokenStorage { 私有只读IJSRuntime _jsRuntime;

    public AccessTokenStorage(IJSRuntime jsRuntime)
    {
        _jsRuntime = jsRuntime;
    }
    
    public async Task<string> GetTokenAsync()
        => await _jsRuntime.InvokeAsync<string>("localStorage.getItem", "accessToken");
    
    public async Task SetTokenAsync(string token)
    {
        if (token == null)
        {
            await _jsRuntime.InvokeAsync<object>("localStorage.removeItem", 
                                                            "accessToken");
        }
        else
        {
            await _jsRuntime.InvokeAsync<object>("localStorage.setItem", 
                                                   "accessToken", token);
        }
    
    
     }
    }
    

我想这里不需要解释...这是您可能需要的一些使用指令 using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Security.Claims; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.JSInterop;

将以下内容添加到Startup.ConfigureServices

services.AddHttpClient(); services.AddScoped<AccessTokenStorage>();

注意:以上代码应与我提供的代码in my answer here

一起使用

答案 1 :(得分:1)

我通过添加以下链接中列出的代码解决了这个问题。

https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/webapi/quick-start-blazor-server-app#make-a-call-to-the-web-api

注意:上面链接中列出的步骤可以正常工作,但是,我做了一些小的修改,这些修改对我来说更有意义。我还修改了对我来说更有意义的顺序。

步骤:

1。创建TokenProvider类

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

2。使用以下命令更新_Host.cshtml文件:

@using Microsoft.AspNetCore.Authentication

@{
   
    var accessToken = await HttpContext.GetTokenAsync("access_token");
}

<body>
    <app>
        <component type="typeof(App)" param-AccessToken="accessToken" render-mode="ServerPrerendered" />
    </app>

3。使用DI更新StartUp.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();

        services.AddScoped<TokenProvider>();

4。使用以下命令更新App.razor:

@inject TokenProvider TokenProvider

@code
{
    
    [Parameter]
    public string AccessToken { get; set; }

    protected override void OnInitialized()
    {
        //Accept the parameter from _Host.cshtml and move into the Token Provider 
        TokenProvider.AccessToken = AccessToken;
        base.OnInitialized();
    }
}

5。必要时,获取AccessToken

注意: _tokenProvider是使用构造函数DI创建的

            var accessToken = _tokenProvider.AccessToken;

            if (accessToken != null)
            {
                _httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
            }

希望上述步骤对其他人有帮助。