【问题标题】:Authenticate signalr hubConnection验证信号器 hubConnection
【发布时间】:2019-07-15 07:18:26
【问题描述】:

****我使用的是 .Net 框架,而不是 Core****

我有一个连接到服务器并订阅一些 Hub 功能的 Web 界面。我正在尝试找到一种方法来限制对服务器的订阅,因此只有具有正确令牌的客户端才能连接和订阅。

这是我的服务器端: 启动.cs:

public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.Map("/signalr", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                var hubConfiguration = new HubConfiguration
                {
                    EnableDetailedErrors = true
                };
                map.RunSignalR(hubConfiguration);
            });
        }
    }

我的 Hub 类:

[HubName("CordioHub")]
    public class CordioHub : Hub
    {
        private static IHubContext CordioHubContext
        {
            get
            {
                return GlobalHost.ConnectionManager.GetHubContext<CordioHub>();
            }
        }

        public static void UpdateClient(string message)
        {
            CordioHubContext.Clients.All.UpdateClient(message);
        }

        public override Task OnDisconnected(bool stopCalled)
        {
            return Clients.All.leave(Context.ConnectionId, DateTime.Now.ToString());
        }

        public override Task OnConnected()
        {
            return Clients.All.joined(Context.ConnectionId, DateTime.Now.ToString());
        }

        public override Task OnReconnected()
        {
            return Clients.All.rejoined(Context.ConnectionId, DateTime.Now.ToString());
        }

        //Status page events:
        public static void UpdatePatientCout(int delta)
        {
            CordioHubContext.Clients.All.UpdatePatientCout(delta);
        }
    }

还有我的客户信号服务:

import { Injectable, Inject } from '@angular/core';

// declare the global variables  
declare var $: any;
@Injectable()
export class SignalRService {
    // Declare the variables  
    private proxy: any;
    private proxyName: string = 'CordioHub';
    private connection: any;
    // create the Event Emitter  
    public connectionExists: Boolean;

    constructor(@Inject('BASE_URL') private originUrl: string) {
        // Constructor initialization  
        this.connectionExists = false;
        // create hub connection  
        this.connection = $.hubConnection(originUrl + '/signalr');

        // add access token to connection
        this.addAccessToken();

        // create new proxy as name already given in top  
        this.proxy = this.connection.createHubProxy(this.proxyName);
        // register on server events  
        this.registerOnServerEvents();
        // call the connecion start method to start the connection to send and receive events.  
        this.startConnection();
    }


    // check in the browser console for either signalr connected or not  
    private startConnection(): void {
        this.connection.start().done((data: any) => {
            console.log('Now connected ' + data.transport.name + ', connection ID= ' + data.id);
            this.connectionExists = true;
        }).fail((error: any) => {
            console.log('Could not connect ' + error);
        });
    }

     private addAccessToken(): void {
         let token = this.getToken();
         this.connection.qs = {
             "access_token": token
         };
     }

    private registerOnServerEvents(): void {
        this.proxy.on('UpdateClient', (data: string) => {
            console.log('received in SignalRService: ' + JSON.stringify(data));
        });

        this.proxy.on('leave', (connectionId: string, date: Date) => {
            console.log('received in SignalRService: ' + connectionId + ' time: ' + date);
        });

        this.proxy.on('joined', (connectionId: string, date: Date) => {
            console.log('received in SignalRService: ' + connectionId + ' time: ' + date);
        });

        this.proxy.on('rejoined', (connectionId: string, date: Date) => {
            console.log('received in SignalRService: ' + connectionId + ' time: ' + date);
        });
    }

     private getToken(): string {
         if (localStorage.getItem('currentUser')) {
             return JSON.parse(localStorage.getItem('currentUser')).AccessToken;
         }
     }
}

正如我所解释的,我想在客户端尝试建立第一个连接时检查服务器端的令牌,并在令牌不好的情况下拒绝。 非常感谢!

【问题讨论】:

    标签: c# .net signalr angular7


    【解决方案1】:

    如果您使用自己的自定义令牌,您可以这样做:

    客户端(.NET,但我想你会明白的):

    var connection = new HubConnection("url", "CustomToken=SomeToken");
    connection.Start().Wait();
    

    服务器:

        public override Task OnConnected()
        {
            if(Context.QueryString["CustomToken"] != "CorrectToken")
            {
                ///Forcefully close the connection
                HttpContext.Current.Response.Close();
            }
            return base.OnConnected();
        }
    

    【讨论】:

      【解决方案2】:

      在这种情况下,您可以使用 JWT 令牌。配置真的很简单:

      Program.cs你应该配置JWT:

      JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
      
              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["Jwt:Issuer"],
                          ValidAudience = configuration["Jwt:Issuer"],
                          IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:Key"])),
                          ClockSkew = TimeSpan.Zero
                      };
                      cfg.Events = new JwtBearerEvents
                      {
                          OnMessageReceived = context =>
                          {
                              if (context.Request.Query.TryGetValue("token", out var token)
                              )
                                  context.Token = token;
      
                              return Task.CompletedTask;
                          }
                      };
                  });
      

      配置文件:

       "Jwt": {
          "Key": "someKey",
          "Issuer": "http://yourdomain.com",
          "ExpireDays": 0,
          "ExpireHours": 1,
          "ExpireMinutes": 0
      },
      

      在 Angular 中,您应该创建拦截器,它将向每个请求添加 Authentications 标头:

      @Injectable()
      export class JwtInterceptor implements HttpInterceptor {
          constructor(private userContext: UserContext) { }
      
      intercept(
          request: HttpRequest<any>,
          next: HttpHandler
      ): Observable<HttpEvent<any>> {
          const authToken = this.userContext.getToken();
          if (!!authToken) {
              request = request.clone({
                  setHeaders: {
                      Authorization: `Bearer ${authToken}`
                  }
              });
          }
      
          return next.handle(request);
          }
      }
      

      【讨论】:

      • 我的 Web 应用程序项目中没有 Program.cs 文件。我使用的是 c# .net 框架,而不是核心。
      • 好的,对不起,我没看到。也许这个链接对你有用link
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 2012-07-12
      • 2012-01-01
      • 1970-01-01
      • 2011-05-09
      相关资源
      最近更新 更多