简体   繁体   中英

Blazor Server with Signalr - Authenticating user via third-party OAuth

I am working on a Blazor Server app that authenticates through a third-party OAuth via Spotify.

services.AddAuthentication()
    .AddSpotify(options =>
    {
        options.ClientId = config.Spotify.ClientId;
        options.ClientSecret = config.Spotify.ClientSecret;

The user is able to login and create an account correctly. I have it configured to save the spotify access_token for later use so I can query the spotify API for this user.

ExternalLogin.cshtml.cs

await _signInManager.UpdateExternalAuthenticationTokensAsync(info);

Now, In addition to using SignalR via the Blazor Server functionality, I'm also using a SignalR client to connect to my server on the "front end" page for the current user.

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapBlazorHub();
    endpoints.MapFallbackToPage("/_Host");
    endpoints.MapHub<HostHub>("/hubs/host");
});

So when the user navigates to the page that needs the server in Hub.razor :

@inject HubConnectionProvider HubProvider

    public async Task StartHub()
    {
        try
        {
            Hub = HubProvider.GetHostHub();
            Hub.On<TrackStatus>(nameof(ISpotiFollowerContract.SetTrack), SetTrack);
            await Hub.StartAsync();

            await JoinGroupAsync();
...

//HubConnectionProvider.cs
    public HubConnection GetHostHub()
    {
        string baseUrl = _navMan.BaseUri;
        var hubUrl = baseUrl.TrimEnd('/') + "/hubs/host";
        return new HubConnectionBuilder()
            .WithUrl(hubUrl, options =>
            {
                //my question lies here
                options.AccessTokenProvider = () => Task.FromResult(_currentUserService.GetAccessToken());
            })
            .Build();
    }

The problem I'm having is that even though the user is authenticated for the Blazor app, I can't the authentication to get the user in my HostHub.cs :

        public async Task JoinGroup(string userId)
        {
            //Name comes through as null, Identity has no claims, etc.
            var name = Context.User.Identity.Name;

I've tried providing the HubConnectionBuilder > options.AccessTokenProvider a value, but I'm not sure which access code I should be providing. Since I'm authenticating my user through a third-party token, should I be providing the Spotify access_token I store for the user, or should I be generating a token for MY app that I send to authenticate my user for the HostHub I'm connecting to?

I've tried sending the Spotify access token, and still get no claims on my user. Is there something I need to do to allow my app to authenticate based on this token? I've tried generating an access token for my application for the already-logged-in user, but haven't found a way to do so. If that's what I need to do, how can I generate this token?

I use this with a hub that Authenticates against Identity Server 4 or AzureAD.

hubConnection = new HubConnectionBuilder()
    .WithUrl(uri, options => {
        options.AccessTokenProvider = async () => {
            var accessTokenResult = await accessTokenProvider.RequestAccessToken();
            accessTokenResult.TryGetToken(out var accessToken);
            var token = accessToken.Value;
            return token;
        };                    
    })
    .WithAutomaticReconnect()
    .Build();

services.AddAuthentication()
    .AddMicrosoftAccount(options =>
    {
        options.ClientId = microsoftAccount.ClientId;
        options.ClientSecret = microsoftAccount.ClientSecret;
        options.SignInScheme = microsoftAccount.SignInScheme;
    });
[Authorize]
public class MessageServiceHub : Hub
{
    ...

You need to add the Authorize attribute to the hub.

A Blazor Server app is mostly a server-side ASP.NET Core app and uses the same mechanisms for authentication. SingalR behaves the same way it does for any other ASP.NET Core application. The Authorize users to access hubs and hub methods section in the Authentication and authorization in ASP.NET Core SignalR doc page explains that:

By default, all methods in a hub can be called by an unauthenticated user. To require authentication, apply the Authorize attribute to the hub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM