简体   繁体   English

Blazor 服务器与 Signalr - 通过第三方验证用户 OAuth

[英]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.我正在开发一个 Blazor 服务器应用程序,该应用程序通过 Spotify 通过第三方 OAuth 进行身份验证。

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.我已将其配置为保存 spotify access_token 以供以后使用,因此我可以查询该用户的 spotify API。

ExternalLogin.cshtml.cs 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.现在,除了通过 Blazor 服务器功能使用 SignalR 之外,我还在当前用户的“前端”页面上使用 SignalR 客户端连接到我的服务器。

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 :因此,当用户导航到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 :我遇到的问题是,即使用户通过了 Blazor 应用程序的身份验证,我也无法在我的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.我尝试为HubConnectionBuilder > options.AccessTokenProvider提供一个值,但我不确定应该提供哪个访问代码。 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?由于我通过第三方令牌对我的用户进行身份验证,我应该提供我为用户存储的 Spotify access_token,还是应该为的应用程序生成一个令牌,我发送该令牌以对我的HostHub我的用户进行身份验证连接到?

I've tried sending the Spotify access token, and still get no claims on my user.我已经尝试发送 Spotify 访问令牌,但仍然没有对我的用户提出任何要求。 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.我将它与针对 Identity Server 4 或 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.您需要将Authorize属性添加到集线器。

A Blazor Server app is mostly a server-side ASP.NET Core app and uses the same mechanisms for authentication. Blazor 服务器应用程序主要是服务器端 ASP.NET 核心应用程序,并使用相同的身份验证机制。 SingalR behaves the same way it does for any other ASP.NET Core application. SingalR 的行为方式与任何其他 ASP.NET 核心应用程序的行为方式相同。 The Authorize users to access hubs and hub methods section in the Authentication and authorization in ASP.NET Core SignalR doc page explains that: ASP.NET Core SignalR 文档页面中的身份验证和授权中授权用户访问集线器和集线器方法部分解释说:

By default, all methods in a hub can be called by an unauthenticated user.默认情况下,集线器中的所有方法都可以由未经身份验证的用户调用。 To require authentication, apply the Authorize attribute to the hub要要求身份验证,请将 Authorize 属性应用于集线器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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