Xabaril / AspNetCore.Diagnostics.HealthChecks

Enterprise HealthChecks for ASP.NET Core Diagnostics Package
Apache License 2.0
4.05k stars 793 forks source link

SignalR Health Checks do not work with Azure SignalR #567

Open atwoodr opened 4 years ago

atwoodr commented 4 years ago

What happened: We tried implementing SignalR health checks for our Azure SignalR resource(s), but no matter inputs we tried with the Xabaril .AddSignalRHub(...) method, we always got a 403 Forbidden response, an exception, and an unhealthy health check result.

What you expected to happen: We expect the library to provide some way to verify a healthy Azure SignalR endpoint/hub/resource through either providing the Access Key or proper bearer token as part of the hub connection.

Things that do not appear to work:

AuthenticatedCredentials credentials = tokenManager.RetrieveCredentials(myAppAuthSettings) .GetAwaiter() .GetResult();

HubConnection connection = new HubConnectionBuilder() .WithUrl("https://myapp-signalr.service.signalr.net/notification", options => { options.AccessTokenProvider = () => Task.FromResult(credentials.AccessToken); }) .Build();

services.AddHealthChecks() .AddSignalRHub("https://myapp-signalr.service.signalr.net/notification", "signalrTest2");



**Remaining questions**:
1. Is Azure SignalR supported by Xabaril AspNetCore.Diagnostics.HealthChecks?
2. If I have my Azure SignalR Connection string, is there some way I can use that or the pieces therein to activate the health check without resulting in a 403? (e.g. "Endpoint=https://myapp-signalr.service.signalr.net;AccessKey=2xo7Pgaj6EVGkF8TbMQCOAeZ4AwH2r8/aFQ9+7r87B2=;Version=1.0;")

- .NET Core version: 3.1
- Microsoft.Extensions.Diagnostics.HealthChecks: 3.1.5
- AspNetCore.Healthchecks.SignalR version: 3.1.1
- Microsoft.Azure.SignalR: 1.4.3

**Additional Question/Consideration:**
@ChrisProlls logged issue #524 that implies that a uri of `https://mydomain.com/hub` would allow one to create a signalR health check, but does such a method not work for something like Azure SignalR where an access key or bearer token authentication is required?
unaizorrilla commented 4 years ago

Hi @atwoodr

Azure SignalR is not tested , let me some days to check this issue and I come back with more info! I try to solve the issue you mentioned with Azure SignalR and api key, bearer tokens, probably we need a new extension method for Azure SignalR

Odonno commented 4 years ago

Sorry for the delay. I can confirm that Azure SignalR works as we already use it in several projects (.NET Core 2.2 and .NET Core 3.1). It works the same as SignalR. So, I suppose it is a configuration error.

atwoodr commented 4 years ago

@Odonno, what method does your Azure SignalR Health Check use to authenticate then? I've tried myriad ways of connecting to no avail. Or is your Azure SignalR somehow unsecured?

Odonno commented 4 years ago

Well, it was a real nightmare for us because we use Azure AD authentication. We had to create an access token by reusing the Azure AD authority (the app is calling itself, with something like impersonation but without any real user authenticated). The only missing part is that you have to define this impersonation permission in the Azure AD configuration.

After that, it worked like a charm.

I assume that your problem is during configuration, what if you do this instead:

HubConnection CreateSignalrHubConnection(string url)
{
    return new HubConnectionBuilder()
        .WithUrl(url, options =>
        {
            options.AccessTokenProvider = async () =>
            {
                var credentials = await tokenManager.RetrieveCredentials(myAppAuthSettings);
                return credentials.AccessToken;
            };
        })
        .Build();
}

services.AddHealthChecks()
    .AddSignalRHub(() => CreateSignalrHubConnection("https://myapp-signalr.service.signalr.net/notification"), "signalrTest2");

Note that you can cache the credentials of AccessTokenProvider if you desire.

rnarayana commented 3 years ago

I've been trying to do what @Odonno suggested, but I'm getting a 404 error. Any idea how I can see more details of the error in health checks? This is what I have so far:


var con = "Endpoint=https://abc.service.signalr.net;AccessKey=keyhere;Version=1.0;";
this.serviceManager = new ServiceManagerBuilder()
  .WithOptions(o => o.ConnectionString = con)
  .Build();
hcBuilder.AddSignalRHub(() => CreateSignalrHubConnection(con), "signalr");

private HubConnection CreateSignalrHubConnection(string connString)
{
    var url = $"{connString.Split(';')[0].Split('=')[1]}/notifications";
    return new HubConnectionBuilder()
        .WithUrl(url, options =>
        {
            options.AccessTokenProvider = () =>
                Task.FromResult(this.serviceManager.GenerateClientAccessToken("notifications"));
        })
        .Build();
}
jakehockey10 commented 2 years ago

@unaizorrilla Will Azure SignalR be more supported in the near future? I'd like to be able to use the connection string that includes the key necessary to authenticate, I believe.

dviry commented 2 years ago

In case this helps anyone - instead of checking the Azure SignalR hubs (I am already checking the local ones in my app) I went with the standard health api on my endpoint using the connectionString:

        services.AddHealthChecks()
                .AddUrlGroup(
                    new Uri(
                        new Uri(new ServiceEndpoint(hubOptions.ConnectionString).Endpoint), 
                        "/api/v1/health"),
                    name: "SignalR Azure Hub",
                    failureStatus: HealthStatus.Degraded,
                    tags: new[] { "cloud", "azure" });
pberggreen commented 2 years ago

@dviry This is a beautiful solution. Thanks.

brunochaina commented 10 months ago

Hi, I'm experiencing the same issue with Azure Signal R. I'm getting

Health check signalr with status Unhealthy completed after 669.4466ms with message '(null)' System.Net.Http.HttpRequestException: Response status code does not indicate success: 404 (Not Found).

I used the solution provided by @dviry hitting the Health API directly and it works. Please keep us posted if the issue is resolved for Azure Signal R.