Servizio SignalR binding di input per Funzioni di Azure

Prima che un client possa connettersi al servizio Azure SignalR, deve recuperare l'URL dell'endpoint di servizio e un token di accesso valido. L'associazione di input SignalRConnectionInfogenera l'URL dell'endpoint del servizio SignalR e un token valido per la connessione al servizio. Il token è limitato al tempo e può essere usato per autenticare un utente specifico a una connessione. Pertanto, non è consigliabile memorizzare nella cache il token o condividerlo tra i client. In genere si usa SignalRConnectionInfo con trigger HTTP per i client per recuperare le informazioni di connessione.

Per altre informazioni su come usare questa associazione per creare una funzione "negotiate" compatibile con un SDK client SignalR, vedere Funzioni di Azure sviluppo e configurazione con Servizio Azure SignalR. Per informazioni sui dettagli di impostazione e configurazione, vedere la panoramica.

Esempio

È possibile creare una funzione C# usando una delle modalità C# seguenti:

  • Modello di lavoro isolato: funzione C# compilata eseguita in un processo di lavoro isolato dal runtime. Il processo di lavoro isolato è necessario per supportare le funzioni C# in esecuzione in LTS e versioni non LTS .NET e .NET Framework.
  • Modello in-process: funzione C# compilata eseguita nello stesso processo del runtime di Funzioni.
  • Script C#: usato principalmente quando si creano funzioni C# nel portale di Azure.

L'esempio seguente mostra una funzione C# che acquisisce le informazioni di connessione a SignalR usando l'associazione di input e le restituisce tramite HTTP.

[Function(nameof(Negotiate))]
public static string Negotiate([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequestData req,
    [SignalRConnectionInfoInput(HubName = "serverless")] string connectionInfo)
{
    // The serialization of the connection info object is done by the framework. It should be camel case. The SignalR client respects the camel case response only.
    return connectionInfo;
}

L'esempio seguente mostra un'associazione di input delle informazioni di connessione SignalR in un file function.json e una funzione che usa l'associazione per restituire le informazioni di connessione.

Ecco i dati di associazione per l'esempio nel file function.json :

{
    "type": "signalRConnectionInfo",
    "name": "connectionInfo",
    "hubName": "hubName1",
    "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
    "direction": "in"
}

Ecco il codice JavaScript:

const { app, input } = require('@azure/functions');

const inputSignalR = input.generic({
    type: 'signalRConnectionInfo',
    name: 'connectionInfo',
    hubName: 'hubName1',
    connectionStringSetting: 'AzureSignalRConnectionString',
});

app.post('negotiate', {
    authLevel: 'function',
    handler: (request, context) => {
        return { body: JSON.stringify(context.extraInputs.get(inputSignalR)) }
    },
    route: 'negotiate',
    extraInputs: [inputSignalR],
});

Gli esempi completi di PowerShell sono in sospeso.

L'esempio seguente mostra un'associazione di input delle informazioni di connessione SignalR in un file function.json e una funzione Python che usa l'associazione per restituire le informazioni di connessione.

Ecco il codice Python:

def main(req: func.HttpRequest, connectionInfoJson: str) -> func.HttpResponse:
    return func.HttpResponse(
        connectionInfoJson,
        status_code=200,
        headers={
            'Content-type': 'application/json'
        }
    )

L'esempio seguente illustra una funzione Java che acquisisce informazioni di connessione SignalR usando l'associazione di input e la restituisce su HTTP.

@FunctionName("negotiate")
public SignalRConnectionInfo negotiate(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> req,
        @SignalRConnectionInfoInput(
            name = "connectionInfo",
            HubName = "hubName1") SignalRConnectionInfo connectionInfo) {
    return connectionInfo;
}

Utilizzo

Token autenticati

Quando un client autenticato attiva la funzione, è possibile aggiungere un'attestazione ID utente al token generato. È possibile aggiungere facilmente l'autenticazione a un'app per le funzioni usando servizio app l'autenticazione.

servizio app l'autenticazione imposta le intestazioni HTTP denominate x-ms-client-principal-id e x-ms-client-principal-name che contengono rispettivamente l'ID entità client e il nome dell'utente autenticato.

È possibile impostare la proprietà UserId dell'associazione sul valore ottenuto da una delle intestazioni con un'espressione di associazione: {headers.x-ms-client-principal-id} o {headers.x-ms-client-principal-name}.

[Function("Negotiate")]
public static string Negotiate([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequestData req,
    [SignalRConnectionInfoInput(HubName = "hubName1", UserId = "{headers.x-ms-client-principal-id}")] string connectionInfo)
{
    // The serialization of the connection info object is done by the framework. It should be camel case. The SignalR client respects the camel case response only.
    return connectionInfo;
}
@FunctionName("negotiate")
public SignalRConnectionInfo negotiate(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST, HttpMethod.GET },
            authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> req,
        @SignalRConnectionInfoInput(name = "connectionInfo", hubName = "hubName1", userId = "{headers.x-ms-signalr-userid}") SignalRConnectionInfo connectionInfo) {
    return connectionInfo;
}

Ecco i dati di associazione nel file function.json:

{
    "type": "signalRConnectionInfo",
    "name": "connectionInfo",
    "hubName": "hubName1",
    "userId": "{headers.x-ms-client-principal-id}",
    "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
    "direction": "in"
}

Ecco il codice JavaScript:

const { app, input } = require('@azure/functions');

const inputSignalR = input.generic({
    type: 'signalRConnectionInfo',
    name: 'connectionInfo',
    hubName: 'hubName1',
    connectionStringSetting: 'AzureSignalRConnectionString',
    userId: '{headers.x-ms-client-principal-id}',
});

app.post('negotiate', {
    authLevel: 'function',
    handler: (request, context) => {
        return { body: JSON.stringify(context.extraInputs.get(inputSignalR)) }
    },
    route: 'negotiate',
    extraInputs: [inputSignalR],
});

Gli esempi completi di PowerShell sono in sospeso.

Ecco il codice Python:

def main(req: func.HttpRequest, connectionInfo: str) -> func.HttpResponse:
    # connectionInfo contains an access key token with a name identifier
    # claim set to the authenticated user
    return func.HttpResponse(
        connectionInfo,
        status_code=200,
        headers={
            'Content-type': 'application/json'
        }
    )
@FunctionName("negotiate")
public SignalRConnectionInfo negotiate(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> req,
        @SignalRConnectionInfoInput(
            name = "connectionInfo",
            HubName = "hubName1",
            userId = "{headers.x-ms-client-principal-id}") SignalRConnectionInfo connectionInfo) {
    return connectionInfo;
}

Attributi

Sia le librerie C# in-process che il processo di lavoro isolato usano l'attributo per definire la funzione. Lo script C# usa invece un file di configurazione function.json.

Nella tabella seguente vengono illustrate le proprietà dell'attributo SignalRConnectionInfoInput :

Proprietà dell'attributo Descrizione
HubName Obbligatorio. Nome dell'hub.
ConnectionStringSetting Nome dell'impostazione dell'app che contiene il Servizio SignalR stringa di connessione, che per impostazione predefinita è AzureSignalRConnectionString.
ID utente Facoltativo. Identificatore utente di una connessione SignalR. È possibile usare un'espressione di associazione per associare il valore a un'intestazione o a una query di richiesta HTTP.
IdToken Facoltativo. Token JWT le cui attestazioni verranno aggiunte alle attestazioni utente. Deve essere usato insieme a ClaimTypeList. È possibile usare un'espressione di associazione per associare il valore a un'intestazione o a una query di richiesta HTTP.
ClaimTypeList Facoltativo. Elenco di tipi di attestazione, che filtrano le attestazioni in IdToken .

Annotazioni

Nella tabella seguente vengono illustrate le impostazioni supportate per l'annotazione SignalRConnectionInfoInput .

Impostazione Description
name Nome della variabile usato nel codice della funzione per l'oggetto informazioni di connessione.
hubName Obbligatorio. Nome dell'hub.
connectionStringSetting Nome dell'impostazione dell'app che contiene il Servizio SignalR stringa di connessione, che per impostazione predefinita è AzureSignalRConnectionString.
userId Facoltativo. Identificatore utente di una connessione SignalR. È possibile usare un'espressione di associazione per associare il valore a un'intestazione o a una query di richiesta HTTP.
idToken Facoltativo. Token JWT le cui attestazioni verranno aggiunte alle attestazioni utente. Deve essere usato insieme a claimTypeList. È possibile usare un'espressione di associazione per associare il valore a un'intestazione o a una query di richiesta HTTP.
claimTypeList Facoltativo. Elenco di tipi di attestazione, che filtrano le attestazioni in idToken .

Annotazioni

Nella tabella seguente vengono illustrate le impostazioni supportate per l'annotazione SignalRConnectionInfoInput .

Impostazione Description
name Nome della variabile usato nel codice della funzione per l'oggetto informazioni di connessione.
hubName Obbligatorio. Nome dell'hub.
connectionStringSetting Nome dell'impostazione dell'app che contiene il Servizio SignalR stringa di connessione, che per impostazione predefinita è AzureSignalRConnectionString.
userId Facoltativo. Identificatore utente di una connessione SignalR. È possibile usare un'espressione di associazione per associare il valore a un'intestazione o a una query di richiesta HTTP.
idToken Facoltativo. Token JWT le cui attestazioni verranno aggiunte alle attestazioni utente. Deve essere usato insieme a claimTypeList. È possibile usare un'espressione di associazione per associare il valore a un'intestazione o a una query di richiesta HTTP.
claimTypeList Facoltativo. Elenco di tipi di attestazione, che filtrano le attestazioni in idToken .

Impostazione

Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione impostate nel file function.json.

Proprietà di function.json Descrizione
type Deve essere impostato su signalRConnectionInfo.
direction Deve essere impostato su in.
hubName Obbligatorio. Nome dell'hub.
connectionStringSetting Nome dell'impostazione dell'app che contiene il Servizio SignalR stringa di connessione, che per impostazione predefinita è AzureSignalRConnectionString.
userId Facoltativo. Identificatore utente di una connessione SignalR. È possibile usare un'espressione di associazione per associare il valore a un'intestazione o a una query di richiesta HTTP.
idToken Facoltativo. Token JWT le cui attestazioni verranno aggiunte alle attestazioni utente. Deve essere usato insieme a claimTypeList. È possibile usare un'espressione di associazione per associare il valore a un'intestazione o a una query di richiesta HTTP.
claimTypeList Facoltativo. Elenco di tipi di attestazione, che filtrano le attestazioni in idToken .

Espressioni di associazione per il trigger HTTP

Si tratta di uno scenario comune in cui i valori di alcuni attributi dell'associazione di input SignalR provengono da richieste HTTP. Di conseguenza, viene illustrato come associare valori dalle richieste HTTP agli attributi di associazione di input SignalR tramite l'espressione di associazione.

Tipo di metadati HTTP Formato dell'espressione di associazione Descrizione Esempio
Query di richiesta HTTP {query.QUERY_PARAMETER_NAME} Associa il valore del parametro di query corrispondente a un attributo {query.userName}
Intestazione della richiesta HTTP {headers.HEADER_NAME} Associa il valore di un'intestazione a un attributo {headers.token}

Passaggi successivi