****我正在使用.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;
}
}
}
正如我所解释的,我想在客户端尝试建立第一个连接时在服务器端检入令牌,并在令牌不好的情况下拒绝。 非常感谢!
答案 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();
}