title: ASP.NET Core SignalR returns 401 Unauthorized using Azure AD
body: <p>I have a SPA (angular 7) and an API (.Net Core) which I authenticate with Azure AD. I'm using <a href="https://github.com/benbaran/adal-angular4" rel="nofollow noreferrer">adal-angular4</a> to integrate my angular application with AAD.</p>
  
  <p>Everything works great, but I'm also using SignalR with the API as server and when I try to connect from my SPA I get 401 Unauthorized on the negotiate "request" and I get this back in the Response Headers:</p>
  
  <p><a href="https://i.stack.imgur.com/ORcR2.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ORcR2.png" alt="Response Header"></a></p>
  
  <p>The request contains my Bearer token in the Authorization header, and when I run the token through <a href="https://jtw.io" rel="nofollow noreferrer">jwt.io</a>, I can see that the "aud" value is the Azure AD ClientId for my SPA. </p>
  
  <p>All regular request to the API contains the same token and I have no issues with those. I have [Authorize] on all my Controllers and on my Hub, but it's only the SignalR Hub that causes this issue.</p>
  
  <p>My server Startup:</p>
  
  <pre><code>public Startup(IConfiguration configuration, IHostingEnvironment env)
  {
      Configuration = configuration;
      _env = env;
  }
  
  public IConfiguration Configuration { get; }
  private IHostingEnvironment _env;
  public void ConfigureServices(IServiceCollection services)
  {
  
      StartupHandler.SetupDbContext(services, Configuration.GetConnectionString("DevDb"));
  
  
      // Setup Authentication
      services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
          .AddAzureADBearer(options =&gt;
          {
              Configuration.Bind("AzureAD", options);
  
  
          });
  
      services.AddMvc()
          .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
  
      // Add functionality to inject IOptions&lt;T&gt;
      services.AddOptions();
  
      // Add AzureAD object so it can be injected
      services.Configure&lt;AzureAdConfig&gt;(Configuration.GetSection("AzureAd"));
  
      services.AddSignalR(options =&gt;
      {
          options.EnableDetailedErrors = true;
          options.KeepAliveInterval = TimeSpan.FromSeconds(10);
      });
  }
  
  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  {
      if (env.IsDevelopment())
      {
          app.UseDeveloperExceptionPage();
      }
      else
      {
          app.UseDeveloperExceptionPage();
          app.UseHsts();
      }
  
      app.UseCookiePolicy();
  
      app.UseHttpsRedirection();
  
      //app.UseCors("AllowAllOrigins");
      app.UseCors(builder =&gt;
      {
          builder.AllowAnyOrigin();
          builder.AllowAnyMethod().AllowAnyHeader();
          builder.AllowCredentials();
      });
  
  
      app.UseAuthentication();
  
      app.UseSignalR(routes =&gt; routes.MapHub&lt;MainHub&gt;("/mainhub"));
  
      app.UseStaticFiles(new StaticFileOptions()
      {
          FileProvider = new PhysicalFileProvider(Path.Combine(_env.ContentRootPath, "Files")),
          RequestPath = new PathString("/Files")
      });
  
      app.UseMvc();
  }
  </code></pre>
  
  <p>My SignalR Hub:</p>
  
  <pre><code>[Authorize]
  public class MainHub : Hub
  {
      private readonly IEntityDbContext _ctx;
  
      public MainHub(IEntityDbContext ctx)
      {
          _ctx = ctx;
          _signalRService = signalRService;
      }
  
      public override Task OnConnectedAsync()
      {
          return base.OnConnectedAsync();
      }
  
      public override Task OnDisconnectedAsync(Exception exception)
      {
          return base.OnDisconnectedAsync(exception);
      }
  }
  </code></pre>
  
  <p>And this is my SignalRService on my angular client. I'm running startConnection() in the constructor of app.component.ts.</p>
  
  <pre><code>export class SignalRService {
      private hubConnection: signalR.HubConnection;
  
      constructor(private adal: AdalService) {}
  
      startConnection(): void {
          this.hubConnection = new signalR.HubConnectionBuilder()
              .withUrl(AppConstants.SignalRUrl, { accessTokenFactory: () =&gt; this.adal.userInfo.token})
              .build();
  
          this.hubConnection.serverTimeoutInMilliseconds = 60000;
  
          this.hubConnection.on('userConnected', (user) =&gt; 
          {
              console.log(user);
          });
  
          this.hubConnection.start()
              .then(() =&gt; console.log('Connection started'))
              .catch(err =&gt; 
              {
                  console.log('Error while starting connection: ' + err);
              });
      }
  }
  </code></pre>
  
  <p>I have tried <a href="https://docs.microsoft.com/en-us/aspnet/core/signalr/authn-and-authz?view=aspnetcore-2.2" rel="nofollow noreferrer">this</a> solution, but I can't get that to work either.</p>
  
  <p><strong>Edit</strong></p>
  
  <p>When I've implemented the solution from the official docs, the API stops working on regular requests as well and I get back:</p>
  
  <p><a href="https://i.stack.imgur.com/D8aVb.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/D8aVb.png" alt="Signature key was not found"></a></p>
  
  <p>I've populate the <code>IssuerSigningKey</code> property in <code>TokenValidationParameters</code> with <code>new SymmetricSecurityKey(Guid.NewGuid().ToByteArray());</code>. Am I doing anything wrong here?</p>
  
  <p><strong>/EDIT</strong></p>
  
  <p>Why won't SignalR accept my accesstoken when the API otherwise accept it?</p>