Hope everyone is safe and well 😊
I thought of discussing azure signalr using terraform in this part, but today I found a very interesting things from azure signalr authentication which is not yet officially documented by Microsoft. So, I'm going to discuss that in this part.
Now a days its common and best practice to use managed identity as much as you can to avoid using the keys/connection string/password in your application or event vault. So, I also would want to use managed identity for authentication from my azure app service to the Azure SignalR resource. This has been explained so well at here
So I thought it would be super simple to implement this in my POC until I hit one road block, let’s see what is the problem and how can we solve that.
If you have followed this series from the beginning, you already noticed that I was doing a POC where I am trying to securely connect my azure signalr from my azure web app. If you missed the earlier parts, no worries please check this Part 1 and Part 2 before going further into this part.
As of now my architecture will look like
And my azure signalr NAC will look like
I have securely connected my azure signal from my azure web app, but my authentication is still using the connection string with accesskey.
The typical azure signalr connection string will look like this.
In order to enable the managed identity, I followed the above MS doc and did like the steps like below
Update my connection by replacing the
AuthType=aad. So, my new connection string will be
After enabling the managed identity when I tried to test my app I got 500 Internal Server Error for the negotiate connection
hmm.. not much useful error/information to debug further. So, I have enabled the Application Insights to see where the failure is occurring.
So the actual error is
Failed in authorizing AccessKey for 'https://xxxxx-signalr-01.service.signalr.net', will retry in 3 seconds.
The real 403 Forbidden endpoint is.
at Microsoft.Azure.SignalR.AadAccessKey+<UpdateAccessKeyAsync>d__23.MoveNext (Microsoft.Azure.SignalR.Common, Version=126.96.36.199, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=188.8.131.52, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=184.108.40.206, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=220.127.116.11, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult (System.Private.CoreLib, Version=18.104.22.168, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.Azure.SignalR.AccessKeySynchronizer+<UpdateAccessKeyAsync>d__13.MoveNext (Microsoft.Azure.SignalR.Common, Version=22.214.171.124, Culture=neutral, PublicKeyToken=adb9793829ddae60)
Inner exception System.Net.Http.HttpRequestException handled at Microsoft.Azure.SignalR.AadAccessKey+<UpdateAccessKeyAsync>d__23.MoveNext:
If you read the error properly you will understand what is going wrong.
From the forbidden endpoint it seems that azure signalr is trying to call a REST API to Azure AD to get the token (for Managed identity) behind the screen
In this we have allowed only Server Connection from our private endpoint, there are a couple of other connections also visible in the dropdown. such as
- REST API
- TRACE API
Perfect, lets enable the REST API connection also from our private endpoint. Now our NAC will look like
That’s it, I have waited for 30min, and my application is working as expected.
The documentation about REST API and TRACE API is still not available public or under development phase. So, it is kind of difficult to get the relevant information for now about these two API’s.
I reached out to azure signalr team about this, and I got the response like
We would get rid of API calls in AAD authenticating process, which means if our customer’s use our future SDK, they will not have to enable REST API explicitly.
We will make it internally in our server connection, instead of sending a rest API. This change would take 1-2 months and the newly released SDK will be like 1.9.x. it will be documented in future release.