asp.net SignalR + Angular:如何将Bearer令牌添加到Http Header

bxpogfeg  于 12个月前  发布在  .NET
关注(0)|答案(4)|浏览(154)

我做了一个asp.net core 2.0 SignalR Hub,它使用Bearer Token进行身份验证。现在我有点不知道如何通过SignalR Angular 5客户端连接到它。如果我从Hub中删除授权,我实际上可以连接,所以连接工作,现在我相信我只需要将授权承载添加到连接的Http Header。
我的Angular 5项目的package.json文件中的SignalR客户端引用:"@aspnet/signalr-client": "^1.0.0-alpha2-final"
我的Angular组件:

import { Component, OnInit } from '@angular/core';
import { finalize } from 'rxjs/operators';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { ToastrService } from 'ngx-toastr';
import { AuthenticationService } from '../core/authentication/authentication.service';
import { HubConnection } from '@aspnet/signalr-client';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {

  quote: string;
  isLoading: boolean;
  jwtToken:string;
  private hubConnection: HubConnection;

  constructor(
    private _http: HttpClient, 
    private _auth : AuthenticationService,
    private _toastr: ToastrService) { }

  ngOnInit() {
    this.isLoading = false;
    this.jwtToken = this._auth.currentToken;

    this.hubConnection = new HubConnection('http://localhost:27081/hub/notification/');
    this.hubConnection
      .start()
      .then(() => console.log('Connection started!'))
     .catch(err => console.error('Error while establishing connection :(', err));        
    this.hubConnection.on("send", data => {
        console.log(data);
    });
  }

  showToastr(){
    this._toastr.success('Hello world!', 'Toastr fun!');
  }

}

字符串
由于阅读类似的问题,我尝试:this.hubConnection.Headers.Add("token", tokenValue);但它不工作,标题属性不存在。
如何将Bearer令牌添加到HubConnection的Http Header?
谢谢你的帮助

kr98yfug

kr98yfug1#

要使用@aspnet/signalr(^1.1.4)执行此操作,可以使用以下代码

const options: IHttpConnectionOptions = {
  accessTokenFactory: () => {
    return "Token is resolved here";
  }
};

const connection = new signalR.HubConnectionBuilder()
  .configureLogging(signalR.LogLevel.Information)
  .withUrl(`${environment.apiUrl}/notify`, options)
  .build();

字符串
还可向中心添加注解

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]


作为一个侧面说明,SignalR在使用WebSocket协议时似乎没有将Bearer令牌作为头部附加,而是将其作为“access_token”参数添加到请求URL,这需要您配置您的身份验证,以便在SignalR选择使用ws时处理此令牌。

services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
                x.Events= new JwtBearerEvents
                {
                    OnMessageReceived = context =>
                    {
                        var accessToken = context.Request.Query["access_token"];

                        // If the request is for our hub...
                        var path = context.HttpContext.Request.Path;
                        if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/notify")))
                        {
                            // Read the token out of the query string
                            context.Token = accessToken;
                        }
                        return Task.CompletedTask;
                    }
                };
            });

2ul0zpep

2ul0zpep2#

通过阅读它们的源代码和测试,似乎可以提供一个包含访问令牌的选项对象,如下所示

var options = {
    transport: transportType,
    logging: signalR.LogLevel.Trace,
    accessToken: function () {
        return jwtToken;
    }
};

hubConnection = new signalR.HubConnection('/authorizedhub', options);
hubConnection.start();

字符串
特别是测试文件here中的代码

kknvjkwl

kknvjkwl3#

我找不到一种方法来解决使用角,但我做了它使用asp.net以下this article
这就是我所做的:现在为了连接,我在querystring中传递jwt token并指定传输类型:

const options = {
      transport: TransportType.WebSockets
};
this.hubConnection = new HubConnection('http://localhost:27081/hub/notification/?token='+this.jwtToken, options);

字符串
然后在startup.cs > ConfigureServices()中:

services
            .AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(cfg =>
            {
                cfg.RequireHttpsMetadata = false;
                cfg.SaveToken = true;
                cfg.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidIssuer = Configuration["JwtIssuer"],
                    ValidAudience = Configuration["JwtIssuer"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
                    ClockSkew = TimeSpan.Zero // remove delay of token when expire
                };
                cfg.Events = new JwtBearerEvents
                {
                    OnMessageReceived = context =>
                    {
                        if (context.Request.Query.TryGetValue("token", out StringValues token)
                        )
                        {
                            context.Token = token;
                        }

                        return Task.CompletedTask;
                    },
                    OnAuthenticationFailed = context =>
                    {
                        var te = context.Exception;
                        return Task.CompletedTask;
                    }
                };
            });

b4qexyjb

b4qexyjb4#

最简单的方式:使用自定义中间件进行认证前,通过查询参数设置auth header,具体如下:

app.Use(async (context, next) =>
{
  if (context.Request.Query.TryGetValue("access_token", out StringValues token))
  {
    context.Request.Headers.Authorization = $"Bearer {token}";
  }
  await next();
});

app.UseAuthentication();

字符串

相关问题