Wondering if anyone has experience in the azure signalr service(v1.04) and angular cli(v6+). Having some issues understanding how to get the client context after connecting to the hub. Any thoughts?
Here's the context of the hub, any help would be appreciated!
this.getConnectionInfo().subscribe(info => {
console.log("INFO", info);
let options = {
accessTokenFactory: () => info.accessToken
};
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl(info.hubUrl, options)
.configureLogging(signalR.LogLevel.Information)
.build();
this.hubConnection.start().then(() => {
console.log('Hub connection started init');
**[GET hubConnectionContext]**
console.log('Connection', this.hubConnection);
})
.catch(err => console.error(err.toString()));
Related
I am trying to create an app that provide Api methods and SignalR hub connection to authorized clients using microservices architecture. We are using reference token with Identity Server. Identity Server is another project and runs standalone, so my application must authorize a user through Identity Server and get his Claims.
I am getting errors when clients are trying to start a socket connection.
Server:
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder => builder
.WithOrigins("https://localhostClientUrl")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddAuthentication(OAuth2IntrospectionDefaults.AuthenticationScheme)
.AddOAuth2Introspection(options =>
{
options.Authority = "https://identityserverURL";
options.ClientId = "client";
options.ClientSecret = "secret";
options.Events = new OAuth2IntrospectionEvents
{
OnTokenValidated = async context =>
{
var path = context.HttpContext.Request.Path;
var accessToken = context.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments(Configuration["MapHub"])))
{
// Read the token out of the query string
context.SecurityToken = accessToken;
}
await Task.CompletedTask;
}
};
});
also
app.UseCors("CorsPolicy");
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
endpoints.MapRazorPages();
endpoints.MapHub<ChatHub>(Configuration["MapHub"]);
});
Client:
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl(this.hubUrl, { accessTokenFactory: () => "ReferenceToken" })
.withAutomaticReconnect()
.build();
this.hubConnection
.start()
.then(() => {
return true;
})
.catch((err) => {
return false;
});
The client is successfully connected and can get all claims on HttpContext.User for the current connection. Prior successful connection i am receiving many clients errors:
WebSocket connection to 'wss://localhost:2222/myHub?id=ew5CRILwAiTZ955IXCZEkg&access_token=C11235C6ADEA27B5EABC08762E1A1B65077278714' failed: HTTP Authentication failed; no valid credentials available
Error: Failed to start the transport 'WebSockets': Error: WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled.
GET https://localhost:2222/myHub?id=XaHhJ66drE0tfIlI3-_OPA&access_token=C11235C6ADEA27B5EABC08762E1A1B65077278714 401
Error: Failed to start the transport 'ServerSentEvents': Error: EventSource failed to connect. The connection could not be found on the server, either the connection ID is not present on the server, or a proxy is refusing/buffering the connection. If you have multiple servers check that sticky sessions are enabled.
Any ideas? I see that client is sending /myHub/negotiate requests to the server. Also OnTokenValidated the context.Request.Query["access_token"] is empty. What do i miss?
If i change the AddOAuth2Introspection and use AddIdentityServerAuthentication which is deprecated is working wihtout any client errors.
.AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, options =>
{
// base-address of your identityserver
options.Authority ="https://identityserverURL";
options.ApiName = "apiname";
options.ApiSecret = "secret";
options.RequireHttpsMetadata = false;
options.TokenRetriever = new Func<HttpRequest, string>(req =>
{
var fromHeader = TokenRetrieval.FromAuthorizationHeader();
var fromQuery = TokenRetrieval.FromQueryString();
return fromHeader(req) ?? fromQuery(req);
});
});
Thank you
I Have configured the signalr with ASP NET core. When i use local service, it works properly. When i use after host it's not working as expected throws the below error.
Here is the code that i have done.
import * as signalR from '#microsoft/signalr';
const connection: signalR.HubConnection = new signalR.HubConnectionBuilder().withUrl('wss://demo/staging/web-services/hubs/spreadsheethub',
{
skipNegotiation: true,
transport: signalR.HttpTransportType.WebSockets,
}).build();
...
});
connection.on('dataReceived', (data: string) => {
// code
});
connection.start().then(() => {
console.log('server connected!!!');
}).catch(err => console.log(err));
I have a web API written in asp.net core 5.
CORS is configured like below:
services.AddCors(options =>
{
string[] allowedOrigins = _config.GetValue<string>("AllowedOrigins")?.Split(",") ?? new string[0];
options.AddPolicy("Default", builder =>
{
builder.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.WithOrigins("http://localhost:4200");
});
options.AddPolicy("AllowAnyThing", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
// .AllowCredentials();
});
options.AddPolicy("Controlled", builder =>
{
builder.WithOrigins(allowedOrigins);
});
});
and appsettings.json contains the below part:
"AllowedOrigins": "http://localhost:4200,https://localhost:4200",
the client is Angular 11.2
when I try to consume the api through the client application,
it fires up "CORS ERROR" even if I remove and disable CORS in API.
I think the problem is from client side, but I don't know how to fix it.
Thank you for your time and attention.
Hello I am trying to get current user but nothing seems to work every resource I find brings null.
this is the code in my startup
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
services.Configure<JwtBearerOptions>(
IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
var onTokenValidated = options.Events.OnTokenValidated;
options.Events.OnTokenValidated = async context =>
{
await onTokenValidated(context);
};
});
services.ConfigureApplicationCookie(o => {
o.ExpireTimeSpan = TimeSpan.FromDays(5);
o.SlidingExpiration = true;
});
services.Configure<DataProtectionTokenProviderOptions>(o =>
o.TokenLifespan = TimeSpan.FromHours(3));
I am actually creating a chat with angular 5 and signalR on an ASP.NET Framework API. I followed the documentation but it's still not work. Here is my hub:
public class ChatHub : Hub
{
public void Hello()
{
Clients.All.hello();
}
}
Here is my startup class:
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
EnableJSONP = true
};
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
});
and here is my angular part which create the hubconnection:
ngOnInit() {
this._hubConnection = new HubConnection('http://localhost:58525/signalr/hubs');
this._hubConnection
.start()
.then(() => console.log('Connection started!'))
.catch(err => console.log('Error while establishing connection :( : ' + err));
this._hubConnection.on('send', data => {
console.log(data);
});
}
I get this error:
If your ASP.NET page runs on another server, then your URL looks not correct.
https://learn.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client#crossdomain
You have to connect to:
this._hubConnection = new HubConnection('http://localhost:58525/signalr');