Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SignalR input binding fails to parse standard Authorization header #2055

Open
yohny opened this issue Oct 1, 2024 · 2 comments
Open

SignalR input binding fails to parse standard Authorization header #2055

yohny opened this issue Oct 1, 2024 · 2 comments

Comments

@yohny
Copy link

yohny commented Oct 1, 2024

When using the idToken property on SignalR input binding as specified in the documentation it should be possible to use binding expession to specify the header from which the JWT token should be extracted. Then using claimTypeList you can specify which extracted claims should be propagated to resulting access token for SignalR. However if standard Authorization header is specified in idToken, the JWT token parsing fails.
Sample Azure function (nodejs runtime, programing model v4):

const inputSignalR = input.generic({
  type: "signalRConnectionInfo",
  name: "connectionInfo",
  hubName: "my-hub",
  idToken: "{headers.authorization}", // extract JWT from standard Authorization header with Bearer JWT token in it
  claimTypeList: ["name", "email"], // propagate name and email claims to SignalR Service access token
});

async function negotiate(
  request: HttpRequest,
  context: InvocationContext
): Promise<HttpResponseInit> {
    return { body: JSON.stringify(context.extraInputs.get(inputSignalR)) };
}

app.post("negotiate", {
  authLevel: "anonymous",
  handler: negotiate,
  route: "negotiate",
  extraInputs: [inputSignalR],
});

when such negotiate endpoint is invoked, it however fails with error:

Executed 'Functions.negotiate' (Failed, Id=8c21bcd7-d061-4184-bac7-3f1046b00f99, Duration=71ms)
[2024-09-29T20:21:11.648Z] System.Private.CoreLib: Exception while executing function: Functions.negotiate. System.IdentityModel.Tokens.Jwt: IDX12709: CanReadToken() returned false. JWT is not well formed.
The token needs to be in JWS or JWE Compact Serialization Format. (JWS): 'EncodedHeader.EndcodedPayload.EncodedSignature'. (JWE): 'EncodedProtectedHeader.EncodedEncryptedKey.EncodedInitializationVector.EncodedCiphertext.EncodedAuthenticationTag'.

this can be resolved by removing the Bearer string from the begginning of the incoming Authorizzation header. If this is done, the JWT header is parsed successfully and the specified claims are propagated to accessToken returned by negotiate endpoint.
It would be helpful if parsing of JWT token could handle common Bearer prefix in the Authorization header without failure.

Further technical details

Nodejs 20.15..1
@azure/functions 4.5.1

@Y-Sindo
Copy link
Member

Y-Sindo commented Oct 8, 2024

Are you using a specific identity provider, the provider tokens are injected into the request headers. See https://learn.microsoft.com/azure/app-service/configure-authentication-oauth-tokens#retrieve-tokens-in-app-code for more information. Does it satisfy your need?

@yohny
Copy link
Author

yohny commented Oct 8, 2024

We use a third party Identity Provider and in JWT token issued by it, the user identifier claim is named account_id, but there are of course also other more standard claims present there like email and name . Which claims will be propagated into those automatically populated headers (X-MS-CLIENT-PRINCIPAL-ID, X-MS-CLIENT-PRINCIPAL-NAME)? Or is it somehow configurable?
Because if its name or enail, that does not help. We need the claim account_id to be used as the user identifier for SignalR.

I actually created a future request #2056 to allow to explicitly specify the claim that should be used as user identifier for SignalR, for which the ability to parse the standard Bearer Authorization header is a prerequisite (as normally the Bearer prefix is present there).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants