验证信号中心集线器

时间:2019-07-15 07:18:26

标签: c# .net signalr angular7

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

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

这是我的服务器端: Startup.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;
         }
     }
}

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

2 个答案:

答案 0 :(得分:0)

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

string connectionString = @"uid=spacecraftU1;pwd=Appolo11; database=spacecraft_db; server=DESKTOP-99K0FRS\\PRANEETHDB"; SqlConnection con = new SqlConnection(connectionString); 中,您应该配置JWT:

Program.cs

配置文件:

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

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

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

答案 1 :(得分:0)

如果您使用自己的自定义令牌,则可以执行以下操作:

客户端(.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();
    }