How do I get the access token from a blazor (server-side) web app?

六月ゝ 毕业季﹏ 提交于 2020-05-07 04:59:29

问题


After implementing openidconnect, where does blazor store the access token? how to retrieve it?


How to add OpenIdConnect via IdentityServer4 to ASP.NET Core ServerSide Blazor web app?

https://docs.microsoft.com/en-us/aspnet/core/security/blazor/?view=aspnetcore-3.1&tabs=visual-studio#customize-unauthorized-content-with-the-router-component


回答1:


The following code snippets provide a way to retrieve the access token issued when a user is authenticated with IdentityServer4 provider. In order to get the access token you can use the HttpContext object, but since Blazor is SignalR-based, you'll have to do it the only time the HttpContext object is available, when the connection to your application is an HTTP connection, and not a WebSocket connection.

After retrieving the access token, you need to pass it to your Blazor app, and store it in a local storage. My code also provide a way to parse the access token, if necessary.

  • Add a file to the Pages folder and name it _Host.cshtml.cs

  • Add this code to the file:

     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; }
     }
    

Note: I've name the the PageModel class: HostAuthenticationModel You'll need some of these: using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using System; using System.Linq; using System.Threading.Tasks;

  • Next we have to pass the value stored in the AccessToken property to the Blazor App:

In the _Host.cshtml file add the model directive at the top portion of the file:

@model HostAuthenticationModel

Add a new attribute to the component Tag Helper like this:

param-AccessToken="Model.AccessToken"

Final result:

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

The param-AccessToken attribute requires you to define a property named AccessToken in the App component which will get the access token from the page model.

  • Next define the property which will receive the access token
  • And then override the OnAfterRenderAsync method from which we call a method to store the access token in the local storage.

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

Also place the following at the top of the App component:

@inject AccessTokenStorage tokenStorage
  • Next you'll have to create the AccessTokenStorage service like this:

    Create a class named AccessTokenStorage at the root of your app, and add the following code:

    public class AccessTokenStorage { private readonly 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);
        }
    
    
     }
    }
    

I guess no explanation is needed here... Here's some using directives you may need 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;

Add the following to the Startup.ConfigureServices

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

Note: the above code should be used with the code I provide in my answer here



来源:https://stackoverflow.com/questions/59891352/how-do-i-get-the-access-token-from-a-blazor-server-side-web-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!