Skip to content

Commit cee7db7

Browse files
Split files
1 parent 26b5ac9 commit cee7db7

File tree

3 files changed

+1047
-1005
lines changed

3 files changed

+1047
-1005
lines changed
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
---
2+
title: Azure Functions SignalR Service input binding
3+
description: Learn to return a SignalR service endpoint URL and access token in Azure Functions.
4+
author: craigshoemaker
5+
ms.topic: reference
6+
ms.date: 02/20/2020
7+
ms.author: cshoe
8+
---
9+
10+
# SignalR Service input binding for Azure Functions
11+
12+
Before a client can connect to Azure SignalR Service, it must retrieve the service endpoint URL and a valid access token. The *SignalRConnectionInfo* input binding produces the SignalR Service endpoint URL and a valid token that are used to connect to the service. Because the token is time-limited and can be used to authenticate a specific user to a connection, you should not cache the token or share it between clients. An HTTP trigger using this binding can be used by clients to retrieve the connection information.
13+
14+
For more information on how this binding is used to create a "negotiate" function that can be consumed by a SignalR client SDK, see the [Azure Functions development and configuration article](../azure-signalr/signalr-concept-serverless-development-config.md) in the SignalR Service concepts documentation.
15+
16+
For information on setup and configuration details, see the [overview](functions-bindings-signalr-service.md).
17+
18+
# [C#](#tab/csharp)
19+
20+
The following example shows a [C# function](functions-dotnet-class-library.md) that acquires SignalR connection information using the input binding and returns it over HTTP.
21+
22+
```cs
23+
[FunctionName("negotiate")]
24+
public static SignalRConnectionInfo Negotiate(
25+
[HttpTrigger(AuthorizationLevel.Anonymous)]HttpRequest req,
26+
[SignalRConnectionInfo(HubName = "chat")]SignalRConnectionInfo connectionInfo)
27+
{
28+
return connectionInfo;
29+
}
30+
```
31+
32+
# [C# Script](#tab/csharp-script)
33+
34+
The following example shows a SignalR connection info input binding in a *function.json* file and a [C# Script function](functions-reference-csharp.md) that uses the binding to return the connection information.
35+
36+
Here's binding data in the *function.json* file:
37+
38+
Example function.json:
39+
40+
```json
41+
{
42+
"type": "signalRConnectionInfo",
43+
"name": "connectionInfo",
44+
"hubName": "chat",
45+
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
46+
"direction": "in"
47+
}
48+
```
49+
50+
Here's the C# Script code:
51+
52+
```cs
53+
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
54+
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
55+
56+
public static SignalRConnectionInfo Run(HttpRequest req, SignalRConnectionInfo connectionInfo)
57+
{
58+
return connectionInfo;
59+
}
60+
```
61+
62+
# [JavaScript](#tab/javascript)
63+
64+
The following example shows a SignalR connection info input binding in a *function.json* file and a [JavaScript function](functions-reference-node.md) that uses the binding to return the connection information.
65+
66+
Here's binding data in the *function.json* file:
67+
68+
Example function.json:
69+
70+
```json
71+
{
72+
"type": "signalRConnectionInfo",
73+
"name": "connectionInfo",
74+
"hubName": "chat",
75+
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
76+
"direction": "in"
77+
}
78+
```
79+
80+
Here's the JavaScript code:
81+
82+
```javascript
83+
module.exports = async function (context, req, connectionInfo) {
84+
context.res.body = connectionInfo;
85+
};
86+
```
87+
88+
# [Python](#tab/python)
89+
90+
The following example shows a SignalR connection info input binding in a *function.json* file and a [Python function](functions-reference-python.md) that uses the binding to return the connection information.
91+
92+
Here's binding data in the *function.json* file:
93+
94+
Example function.json:
95+
96+
```json
97+
{
98+
"type": "signalRConnectionInfo",
99+
"name": "connectionInfo",
100+
"hubName": "chat",
101+
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
102+
"direction": "in"
103+
}
104+
```
105+
106+
Here's the Python code:
107+
108+
```python
109+
def main(req: func.HttpRequest, connectionInfoJson: str) -> func.HttpResponse:
110+
return func.HttpResponse(
111+
connectionInfoJson,
112+
status_code=200,
113+
headers={
114+
'Content-type': 'application/json'
115+
}
116+
)
117+
```
118+
119+
# [Java](#tab/java)
120+
121+
The following example shows a [Java function](functions-reference-java.md) that acquires SignalR connection information using the input binding and returns it over HTTP.
122+
123+
```java
124+
@FunctionName("negotiate")
125+
public SignalRConnectionInfo negotiate(
126+
@HttpTrigger(
127+
name = "req",
128+
methods = { HttpMethod.POST },
129+
authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> req,
130+
@SignalRConnectionInfoInput(
131+
name = "connectionInfo",
132+
hubName = "chat") SignalRConnectionInfo connectionInfo) {
133+
return connectionInfo;
134+
}
135+
```
136+
137+
---
138+
139+
### Authenticated tokens
140+
141+
If the function is triggered by an authenticated client, you can add a user ID claim to the generated token. You can easily add authentication to a function app using [App Service Authentication](../app-service/overview-authentication-authorization.md).
142+
143+
App Service Authentication sets HTTP headers named `x-ms-client-principal-id` and `x-ms-client-principal-name` that contain the authenticated user's client principal ID and name, respectively.
144+
145+
# [C#](#tab/csharp)
146+
147+
You can set the `UserId` property of the binding to the value from either header using a [binding expression](./functions-bindings-expressions-patterns.md): `{headers.x-ms-client-principal-id}` or `{headers.x-ms-client-principal-name}`.
148+
149+
```cs
150+
[FunctionName("negotiate")]
151+
public static SignalRConnectionInfo Negotiate(
152+
[HttpTrigger(AuthorizationLevel.Anonymous)]HttpRequest req,
153+
[SignalRConnectionInfo
154+
(HubName = "chat", UserId = "{headers.x-ms-client-principal-id}")]
155+
SignalRConnectionInfo connectionInfo)
156+
{
157+
// connectionInfo contains an access key token with a name identifier claim set to the authenticated user
158+
return connectionInfo;
159+
}
160+
```
161+
162+
# [C# Script](#tab/csharp-script)
163+
164+
You can set the `userId` property of the binding to the value from either header using a [binding expression](./functions-bindings-expressions-patterns.md): `{headers.x-ms-client-principal-id}` or `{headers.x-ms-client-principal-name}`.
165+
166+
Example function.json:
167+
168+
```json
169+
{
170+
"type": "signalRConnectionInfo",
171+
"name": "connectionInfo",
172+
"hubName": "chat",
173+
"userId": "{headers.x-ms-client-principal-id}",
174+
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
175+
"direction": "in"
176+
}
177+
```
178+
179+
Here's the C# Script code:
180+
181+
```cs
182+
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
183+
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
184+
185+
public static SignalRConnectionInfo Run(HttpRequest req, SignalRConnectionInfo connectionInfo)
186+
{
187+
// connectionInfo contains an access key token with a name identifier
188+
// claim set to the authenticated user
189+
return connectionInfo;
190+
}
191+
```
192+
193+
# [JavaScript](#tab/javascript)
194+
195+
You can set the `userId` property of the binding to the value from either header using a [binding expression](./functions-bindings-expressions-patterns.md): `{headers.x-ms-client-principal-id}` or `{headers.x-ms-client-principal-name}`.
196+
197+
Example function.json:
198+
199+
```json
200+
{
201+
"type": "signalRConnectionInfo",
202+
"name": "connectionInfo",
203+
"hubName": "chat",
204+
"userId": "{headers.x-ms-client-principal-id}",
205+
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
206+
"direction": "in"
207+
}
208+
```
209+
210+
Here's the JavaScript code:
211+
212+
```javascript
213+
module.exports = async function (context, req, connectionInfo) {
214+
// connectionInfo contains an access key token with a name identifier
215+
// claim set to the authenticated user
216+
context.res.body = connectionInfo;
217+
};
218+
```
219+
220+
# [Python](#tab/python)
221+
222+
You can set the `userId` property of the binding to the value from either header using a [binding expression](./functions-bindings-expressions-patterns.md): `{headers.x-ms-client-principal-id}` or `{headers.x-ms-client-principal-name}`.
223+
224+
Example function.json:
225+
226+
```json
227+
{
228+
"type": "signalRConnectionInfo",
229+
"name": "connectionInfo",
230+
"hubName": "chat",
231+
"userId": "{headers.x-ms-client-principal-id}",
232+
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
233+
"direction": "in"
234+
}
235+
```
236+
237+
Here's the Python code:
238+
239+
```python
240+
def main(req: func.HttpRequest, connectionInfoJson: str) -> func.HttpResponse:
241+
# connectionInfo contains an access key token with a name identifier
242+
# claim set to the authenticated user
243+
return func.HttpResponse(
244+
connectionInfoJson,
245+
status_code=200,
246+
headers={
247+
'Content-type': 'application/json'
248+
}
249+
)
250+
```
251+
252+
# [Java](#tab/java)
253+
254+
You can set the `userId` property of the binding to the value from either header using a [binding expression](./functions-bindings-expressions-patterns.md): `{headers.x-ms-client-principal-id}` or `{headers.x-ms-client-principal-name}`.
255+
256+
```java
257+
@FunctionName("negotiate")
258+
public SignalRConnectionInfo negotiate(
259+
@HttpTrigger(
260+
name = "req",
261+
methods = { HttpMethod.POST },
262+
authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> req,
263+
@SignalRConnectionInfoInput(
264+
name = "connectionInfo",
265+
hubName = "chat",
266+
userId = "{headers.x-ms-client-principal-id}") SignalRConnectionInfo connectionInfo) {
267+
return connectionInfo;
268+
}
269+
```
270+
271+
---
272+
273+
## Next steps
274+
275+
- [Send SignalR Service messages (Output binding)](./functions-bindings-signalr-service-output.md)

0 commit comments

Comments
 (0)