Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
For security reasons, your server may host in an independent tenant from your Azure SignalR resource.
Since managed identity can't be used across tenants, you need to register an application in tenantA
and then provision it as an enterprise application in tenantB
.
This doc helps you create an application in tenantA
and use it to connect to a SignalR resource in tenantB
.
Register a multitenant application in tenant A
The first step is to create a multitenant application, see:
Quickstart: Register an application in Microsoft Entra ID
In the case that you already have a single tenant application.
Convert single-tenant app to multitenant on Microsoft Entra ID
There are four account types:
- Accounts in this organizational directory
- Accounts in any organizational directory
- Accounts in any organizational directory and personal Microsoft accounts
- Personal Microsoft accounts
Be sure to select either type 2 or type 3 when creating the application.
Note down the Application (client) ID and Directory (tenant) ID, they can be useful in the following steps.
Provision the application in tenant B
The role can't be assigned to the application registered in other tenants. We have to provision it as an external enterprise application in the tenant B.
Click to learn differences between App registration and Enterprise applications.
For short, the enterprise application is a service principal, while the app registration isn't. The enterprise application inherits certain properties from the application object, such as Application (client) ID.
A default service principal is created in the tenant where the app is registered. For other tenants, you need to provision the app to get an enterprise application service principal, see:
Create an enterprise application from a multitenant application in Microsoft Entra ID
Enterprise applications in different tenant have different Directory (tenant) ID, but share the same Application (client) ID.
Assign roles to the enterprise application
Once you have the enterprise application provisioned in your tenant B. You will be able to assign roles to it.
The following steps describe how to assign a SignalR App Server role to a service principal or a managed identity for an Azure SignalR Service resource. For detailed steps, see Assign Azure roles using the Azure portal.
Note
A role can be assigned to any scope, including management group, subscription, resource group, or single resource. To learn more about scope, see Understand scope for Azure RBAC.
In the Azure portal, go to your Azure SignalR Service resource.
Select Access control (IAM) in the sidebar.
Select Add > Add role assignment.
On the Role tab, select SignalR App Server or other SignalR built-in roles depends on your scenario.
Role Description Use case SignalR App Server Access to the server connection creation and key generation APIs. Most commonly used for app server with Azure SignalR resource run in Default mode. SignalR Service Owner Full access to all data-plane APIs, including REST APIs, the server connection creation, and key/token generation APIs. For negotiation server with Azure SignalR resource run in Serverless mode, as it requires both REST API permissions and authentication API permissions. SignalR REST API Owner Full access to data-plane REST APIs. For using Azure SignalR Management SDK to manage connections and groups, but does NOT make server connections or handle negotiation requests. SignalR REST API Reader Read-only access to data-plane REST APIs. Use it when write a monitoring tool that calls readonly REST APIs. Select Next.
For Microsoft Entra application.
- In the
Assign access
to row, select User, group, or service principal. - In the
Members
row, clickselect members
, then choose the identity in the pop-up window.
- In the
For managed identity for Azure resources.
- In the
Assign access
to row, select Managed identity. - In the
Members
row, clickselect members
, then choose the application in the pop-up window.
- In the
Select Next.
Review your assignment, then click Review + assign to confirm the role assignment.
Important
Newly added role assignments might take up to 30 minutes to propagate.
To learn more about how to assign and manage Azure roles, see these articles:
- Assign Azure roles using the Azure portal
- Assign Azure roles using the REST API
- Assign Azure roles using Azure PowerShell
- Assign Azure roles using the Azure CLI
- Assign Azure roles using Azure Resource Manager templates
Configure SignalR SDK to use the enterprise application
There are 3 different types of credentials for an application to authenticate itself:
- Certificates
- Client secrets
- Federated identity
We strongly recommend you to use the first 2 ways to make cross tenant requests.
Use Certificates or Client secrets
tenantId
should be the ID of your Tenant B.clientId
in both tenants are equal.clientSecret
andclientCert
should be configured in Tenant A, see Add credentials.
If you aren't sure about your tenant ID, see Find your Microsoft Entra tenant
services.AddSignalR().AddAzureSignalR(option =>
{
var credential1 = new ClientSecretCredential("tenantId", "clientId", "clientSecret", new TokenCredentialOptions { AuthorityHost=AzureAuthorityHosts.AzureChina});
var credential2 = new ClientCertificateCredential("tenantId", "clientId", "path-to-cert", new TokenCredentialOptions { AuthorityHost=AzureAuthorityHosts.AzureChina});
option.Endpoints = new ServiceEndpoint[]
{
new ServiceEndpoint(new Uri("https://<resource1>.signalr.azure.cn"), credential1),
new ServiceEndpoint(new Uri("https://<resource2>.signalr.azure.cn"), credential2),
};
});
Use Federated identity
However, for security reasons, certificates and client secrets might be disabled in your subscription. In this case, you need to either use an external identity provider or try the preview support for managed identity.
- Configure an app to trust an external identity provider
- Configure an application to trust a managed identity (preview)
When using managed identity as an identity provider, the code should look like this:
tenantId
should be the ID of your Tenant B.clientId
in both tenants are equal.
services.AddSignalR().AddAzureSignalR(option =>
{
var msiCredential = new ManagedIdentityCredential("msiClientId");
var credential = new ClientAssertionCredential("tenantId", "appClientId", async (ctoken) =>
{
// Entra ID China operated by 21Vianet: api://AzureADTokenExchangeChina
var request = new TokenRequestContext([$"api://AzureADTokenExchangeChina/.default"]);
var response = await msiCredential.GetTokenAsync(request, ctoken).ConfigureAwait(false);
return response.Token;
});
option.Endpoints = [
new ServiceEndpoint(new Uri(), "https://<resource>.signalr.azure.cn"), credential);
];
});
When using external identity providers, the code should look like this:
services.AddSignalR().AddAzureSignalR(option =>
{
var credential = new ClientAssertionCredential("tenantId", "appClientId", async (ctoken) =>
{
// Find your own way to get a token from the external identity provider.
// The audience of the token should be "api://AzureADTokenExchangeChina", as it is the recommended value.
return "TheTokenYouGetFromYourExternalIdentityProvider";
});
option.Endpoints = [
new ServiceEndpoint(new Uri(), "https://<resource>.signalr.azure.cn"), credential);
];
});
Debugging token acquisition with the SignalR SDK can be challenging since it depends on the token results. We recommend testing the token acquisition process locally before integrating with the SignalR SDK.
var assertion = new ClientAssertionCredential("tenantId", "appClientId", async (ctoken) =>
{
// Find your own way to get a token from the external identity provider.
// The audience of the token should be "api://AzureADTokenExchangeChina", as it is the recommended value.
return TheTokenYouGetFromYourExternalIdentityProvider;
});
var request = new TokenRequestContext(["https://signalr.azure.cn/.default");
var token = await assertion.GetTokenAsync(assertion);
Console.log(token.Token);
The key point is to use an inner credential to get a clientAssertion
from api://AzureADTokenExchangeChina
or other trusted identity platforms. Then use it to exchange for a token with https://signalr.azure.cn/.default
audience to access your resource.
Your goal is to get a token with following claims. Use jwt.io to help you decode the token:
oid
The value should be equal to your enterprise application object ID.
If you don't know where to get it, see How Retrieve Enterprise Object ID
tid
The value should be equal to the Directory ID of your tenant B.
If you aren't sure about your tenant ID, see Find your Microsoft Entra tenant
audience
Has to be
https://signalr.azure.cn/.default
to access SignalR resources.
Next steps
See the following related articles: