Azure / azure-functions-signalrservice-extension

Azure Functions bindings for SignalR Service. Project moved to https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/signalr/Microsoft.Azure.WebJobs.Extensions.SignalRService .
MIT License
97 stars 48 forks source link

MissingMethodException: at Microsoft.Azure.SignalR.AuthenticationHelper.GenerateJwtBearer #88

Open bmeijwaard opened 4 years ago

bmeijwaard commented 4 years ago

Receiving mentioned error as of today, yesterday it was working fine. Currently using Azure SignalR standard price tier set on 'Default' service mode.

The expetion is raised when using this method, calling signalRMessage.AddAsync:

[FunctionName("send-message")]
public static async Task<IActionResult> SendMessage(
  [HttpTrigger(AuthorizationLevel.Function, "post", Route = "chat/send-message")]HttpRequestMessage request,
  [SignalR(HubName = "hubname")] IAsyncCollector<SignalRMessage> signalRMessage)
{
    var message = await request.Content.ReadAsAsync<MessageDto>();
    await _chatService.CreateAsync(message);

    await signalRMessage.AddAsync(
        new SignalRMessage
        {
            Target = "message-emitter",
            Arguments = new[] { message }
        });
}

Exception:

MissingMethodException message
Method not found: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.CreateJwtSecurityToken(System.String, System.String, System.Security.Claims.ClaimsIdentity, System.Nullable`1<System.DateTime>, System.Nullable`1<System.DateTime>, System.Nullable`1<System.DateTime>, Microsoft.IdentityModel.Tokens.SigningCredentials)'.

Stacktrace:
at Microsoft.Azure.SignalR.AuthenticationHelper.GenerateJwtBearer(String issuer, String audience, ClaimsIdentity subject, Nullable`1 expires, String signingKey)
   at Microsoft.Azure.SignalR.AuthenticationHelper.GenerateJwtBearer(String issuer, String audience, IEnumerable`1 claims, Nullable`1 expires, String signingKey, String requestId)
   at Microsoft.Azure.SignalR.AuthenticationHelper.GenerateAccessToken(String signingKey, String audience, IEnumerable`1 claims, TimeSpan lifetime, String requestId)
   at Microsoft.Azure.SignalR.Management.RestApiAccessTokenGenerator.Generate(String audience, Nullable`1 lifetime)
   at Microsoft.Azure.SignalR.Management.RestApiProvider.GenerateRestApiEndpoint(String path, Nullable`1 lifetime)
   at Microsoft.Azure.SignalR.Management.RestApiProvider.GetBroadcastEndpoint(Nullable`1 lifetime)
   at Microsoft.Azure.SignalR.Management.RestHubLifetimeManager.SendAllAsync(String methodName, Object[] args, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.SignalR.Internal.AllClientProxy`1.SendCoreAsync(String method, Object[] args, CancellationToken cancellationToken)
   at Microsoft.Azure.WebJobs.Extensions.SignalRService.AzureSignalRClient.SendToAll(SignalRData data)
   at Microsoft.Azure.WebJobs.Extensions.SignalRService.SignalRAsyncCollector`1.AddAsync(T item, CancellationToken cancellationToken)
   at ProjoName.Functions.Triggers.Cosmos.ScoreTriggers.Run(IReadOnlyList`1 documents, IAsyncCollector`1 signalRMessage) in C:\Projects\ProjoName\src\functions\ProjoName.Functions\Triggers\Cosmos\ScoreTriggers.cs:line 34"

Package.json:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AzureFunctionsVersion>v3</AzureFunctionsVersion>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <UserSecretsId>8a1d9684-980f-41fb-9d25-861f2be8dfcc</UserSecretsId>
  </PropertyGroup>

  <ItemGroup>
    <Content Include="..\..\web\ProjoName.Auth\appsettings.json" Link="appsettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="AutoMapper" Version="9.0.0" />
    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />    
    <PackageReference Include="Microsoft.Azure.SignalR.Management" Version="1.2.1" />    
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.CosmosDB" Version="3.0.5" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.SignalRService" Version="1.0.2" />
    <PackageReference Include="System.Configuration.ConfigurationManager" Version="4.7.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="3.1.0" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.2" />
    <PackageReference Include="Microsoft.Azure.EventGrid" Version="3.2.0" />
    <PackageReference Include="Microsoft.IdentityModel.Protocols" Version="5.6.0" />
    <PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="5.6.0" />    
    <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.6.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.0">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.0">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\..\core\ProjoName.Core.Contracts\ProjoName.Core.Contracts.csproj" />
    <ProjectReference Include="..\..\core\ProjoName.Mapping\ProjoName.Mapping.csproj" />
    <ProjectReference Include="..\..\_shared\ProjoName.Common\ProjoName.Common.csproj" />
  </ItemGroup>

  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>

</Project>
bmeijwaard commented 4 years ago

Also opened an issue here at Microsoft.Azure.SignalR: https://github.com/Azure/azure-signalr/issues/776

etortec commented 4 years ago

We have the exact same problem with our .Net Core 3.1 v3 functions that attempt to send SignalR messages: Sometimes it works correctly but after a while MissingMethodException begin to appear. Restarting the function appears to sometimes fix the problem for a while, but it inevitably returns.

According to our logs the problem started around February 5, which seems to close to the time when we upgrade our functions from from V2 to V3.

After performing a memory dump we noticed our function loaded D:\Program Files (x86)\SiteExtensions\Functions\3.0.13107\32bit\System.IdentityModel.Tokens.Jwt.dll version 5.5.0.60624, thus not the System.IdentityModel.Tokens.Jwt.dll we ship with our function code. Since Microsoft.Azure.WebJobs.Extensions.SignalRService version 1.0.2 has a transitive dependency on System.IdentityModel.Tokens.Jwt version 5.2.1 and we therefore ship this older version we thought we had found the problem and attempted to fix it by adding a direct dependency on Microsoft.Azure.SignalR.Management version 1.4.0 which, which ensures we also ship transitive dependencies that depend on version 5.5.0 of System.IdentityModel.Tokens.Jwt.

After testing we however soon noticed this did not solve the problem.

Function app info in case someone from the Azure function team can take a look at logs from their side:

etortec commented 4 years ago

Fixed problem was fixed by https://github.com/Azure/azure-signalr/issues/776#issuecomment-591459921