Closed RbsTechOnline closed 2 years ago
Claims in X-ASRS-User-Claims
consists of claims in the accessToken. So, you just need to add your custom claims when generating access token in the negotiate method.
If you're using in-process C#, then you can easily use ServerlessHub.NegotiateAsync
to pass in custom claims. But as you're using isolated process, you can also simulate the implementation in ServerlessHub
to generate accessToken. https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/signalr/Microsoft.Azure.WebJobs.Extensions.SignalRService/src/TriggerBindings/ServerlessHub.cs#L134
In dotnet isolated process worker, you can also use the "IdToken" and "claimTypeList" properties in the SignalRConnectionInfo
binding as follows to pass your customized claims. Specify the location of your jwt claim in the "IdToken", and the claim types you want to put into the user claims.
[Function("CustomIdToken")]
public static SignalRConnectionInfo Negotiate([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req,
[SignalRConnectionInfoInput(HubName = "chat", ConnectionStringSetting = "SignalRConnection", IdToken = "{headers.headerName}", ClaimTypeList = new string[] { "email" })] SignalRConnectionInfo connectionInfo)
{
return connectionInfo;
}
A payload sample of the required JWT token:
{
"Issuer": "Issuer",
"Issued At": "2022-07-05T10:03:31.050Z",
"Expiration": "2022-07-05T10:03:31.050Z",
"email": "me@outlook.com"
}
And we will update our documents to make this feature clearer.
Thanks @Y-Sindo and @zackliu, this all makes perfect sense, i am kicking myself as i must have looked at SignalRConnectionInfoInput
and overlooked _serviceManager.GenerateClientAccessToken
many times.
The documentation for serverless + isolated is still a little raw and disjointed, yet just a small bit clarity around claims and the nature of how they propagate would have likely just the tipped the scales for me a bit quicker and the last piece of the puzzle i needed.
Thanks for all your help, you both need a payrise :)
@RbsTechOnline
can you help with below questions, I am looking for some guidance
1) question1 2) When to use this SDK if I could already follow the traditional model of creating negotiate, other functions to send messages to clients.
@Chays21
can you help with below questions, I am looking for some guidance
- question1
- When to use this SDK if I could already follow the traditional model of creating negotiate, other functions to send messages to clients.
InvocationContext
of SignalR trigger, see the doc here for details. You could tell us more about your scenario if you have any questions.@Y-Sindo I assume that my understanding might need to be corrected with Azure SignalR service design and Azure functions. I might be asking a question which might be not actually logical or achievable.
My scenario includes processing a message received from service bus topic trigger and sending to the react js client app with Signalr output binding. The code for azure functions negotiate, ProcessUpdate is implemented in .net core with Azure function bindings. below is the code for ProcessUpdate.
[FunctionName("ProcessUpdate")]
public static void Test([ServiceBusTrigger(topicName: "test", subscriptionName: "test", Connection = "AzureServiceBusConnectionString")] ServiceBusReceivedMessage message,
[SignalR(HubName = "Notification")] IAsyncCollector<SignalRMessage> signalrMessageCollector, ILogger logger)
{
var signalrMessage = new SignalRMessage()
{
UserId = //assign authenticated user id
Target = "receiveUpdate",
Arguments = new[] { message.Body.ToString() }
};
signalrMessageCollector.AddAsync(signalrMessage);
}
i) I understand now that currently this sdk only supports .net core signalr clients. so I can't make use of SignalR Management SDK here as I have ReactJS client application.
ii) So If I have to follow Azure function bindings, I cannot use the two input trigger bindings (Topic trigger, SignalR trigger) in the azure function ProcessUpdate.
so My question is
When client application negotiates, as part of the SignalRConnectionInfo object an access token will be sent back to the client application and client application uses further this to connect to SignalR Service so is there a way I can access this token in ProcessUpdate azure function
public static SignalRConnectionInfo Negotiate(
[HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req,
[SignalRConnectionInfo(HubName = "test", UserId = "{headers.x-ms-client-principal-id}")] SignalRConnectionInfo connectionInfo, ILogger logger)
{
logger.LogInformation($"Returning connection: {connectionInfo.Url} {connectionInfo.AccessToken}");
return connectionInfo;
}
2) I assume the SDK you mention is the SignalR management SDK. The SignalR Functions binding is implemented based on this SDK. SignalR Functions binding for C# in-process functions model provides most of the functionalities in the SDK, so if the Functions bindings satisfy your need, you can just use Functions bindings. However, SignalR bindings for C# out-of-process functions model have limited functionalities, you might want to use the SDK directly if you have complicated requirements, for example, you want to preprocess the claims before passing them to services for negotation, or you want to customize the JSON serialization.
How do I know what all function bindings are available with SDK to use? are there any limitations?
i) I understand now that currently this sdk only supports .net core signalr clients. so I can't make use of SignalR Management SDK here as I have ReactJS client application.
This is not true. ASP.NET Core SignalR
refers to the server-side technique you're using. For the client side, you could choose the proper JS library according to your server-side technique. For JS client, you should use @microsoft/signalr
library.
ii) So If I have to follow Azure function bindings, I cannot use the two input trigger bindings (Topic trigger, SignalR trigger) in the azure function ProcessUpdate.
Yes, you cannot use two trigger bindings in one function.
When client application negotiates, as part of the SignalRConnectionInfo object an access token will be sent back to the client application and client application uses further this to connect to SignalR Service so is there a way I can access this token in ProcessUpdate azure function.
I am also confused by your question. Given that your ProcessUpdate
is a ServiceBus trigger function, and Service Bus is another service independent of SignalR Service, how do you know which SignalR client to access if you don't pass any information to the Service Bus?
How do I know what all function bindings are available with SDK to use? are there any limitations?
I am not sure if I understand your first question. Do you mean that you want to find all the functionalities/features
provided by the management SDK? You can see this doc https://github.com/Azure/azure-signalr/blob/dev/docs/management-sdk-guide.md for more details.
Hi @Y-Sindo
1)
How do I know what all function bindings are available with SDK to use? are there any limitations?
I am not sure if I understand your first question. Do you mean that you want to find all the functionalities/features provided by the management SDK? You can see this doc https://github.com/Azure/azure-signalr/blob/dev/docs/management-sdk-guide.md for more details.
I can not figure out the what `names of bindings are there to use? Can you list down the names of bindings that can be used from sdk.
2)
This is not true. ASP.NET Core SignalR refers to the server-side technique you're using. For the client side, you could choose the proper JS library according to your server-side technique. For JS client, you should use @microsoft/signalr library.
ASP.NET Core SignalR JS client Differences between ASP.NET SignalR and ASP.NET Core SignalR
but I see the below note, here https://github.com/Azure/azure-signalr/blob/dev/docs/management-sdk-guide.md.
Azure SignalR Service Management SDK NOTE
Azure SignalR Service only supports this SDK for ASP.NET CORE SignalR clients.
This means I can only use this SDK to manage asp.net core signalr clients from my server side code not the reactjs signalr clients. is this understanding correct? other way the question is can I use this SDK to implement negotiate, processupdate functions instead of Azure function bindings to work with ReactJs signalr client?
Environment
My problem is, i cant seem to find a reliable way to authorize a hub method after negotiation.
The use-case here, is i have connected clients authorized from the front end clients through a jwt token supplied azure B2C. I also have back-end MS Orleans Daemon services that push messages through to those clients.
I am trying to limit what hub methods the clients can use, and allowing only Daemons to use service type hub methods. Obviously its not optimal to have certain types of hub methods un authorized.
All though i can pass claims/roles from the authenticated Daemons (via app registrations jwts) through to the negotiation method, i cant seem to find a way to distinguish the Daemon services after the fact when calling hub methods.
The only work around i can see atm, is pushing the UserId/ConnectionId and roles (on negotiation) to a azure cosmos / redis servicem using the roles to determine the class/type of user (E.g Front Client or Daemon). then in the hub methods doing a lookup on those ids to determine the type of user, in turn restricting access.
Unless there is some other solution to this that i am unaware of (very likely), maybe there is the possibility of using the input binding of the negotiate method to populate the X-ASRS-User-Claims with custom claims, which could be checked in hub methods?