I have configured SignalR in my .NET Core Web API as below.
using AutoMapper;
using Azure.Storage.Blobs;
using DinkToPdf;
using DinkToPdf.Contracts;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Identity.Client;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System;
using System.Reflection;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyMethod()
.SetIsOriginAllowed(_ => true)
.AllowAnyHeader()
.AllowCredentials());
});
builder.Services.AddScoped<IDapperWrapper, DapperWrapper>();
//Use below code for global authorization and add AllowAnonymous to login route.
//otherwise use Authorize in the required controller and/or action
builder.Services.AddControllers(options =>
{
options.Filters.Add(new AuthorizeFilter());
});
builder.Services.AddApiVersioning(x =>
{
x.DefaultApiVersion = new ApiVersion(1, 0);
x.AssumeDefaultVersionWhenUnspecified = true;
x.ReportApiVersions = true;
});
builder.Services.AddAntiforgery(antiforgeryOptions =>
{
antiforgeryOptions.HeaderName = "X-XSRF-TOKEN";
antiforgeryOptions.Cookie.HttpOnly = true;
antiforgeryOptions.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
#region --> JWT Authentication
builder.Services.Configure<JWTSettings>(options =>
{
builder.Configuration.GetSection("Jwt").Bind(options);
var securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(options.Secret));
options.ValidFor = TimeSpan.FromMinutes(Convert.ToInt32(builder.Configuration["Jwt:ValidFor"]));
options.SigningCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
});
JWTSettings jwtSettings = builder.Configuration.GetSection("Jwt").Get<JWTSettings>();
builder.Services.AddJWTAuthentication(jwtSettings);
#endregion
builder.Services.AddSingleton<CustomIDataProtection>();
builder.Services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
builder.Services.AddSignalR(o => { o.EnableDetailedErrors = true; });
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseMiddleware<ExceptionMiddleware>();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseAntiforgeryToken();
app.UseAuthorization();
app.Use(async (context, next) =>
{
if (!context.Response.Headers.ContainsKey("X-Frame-Options"))
{
context.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
}
await next();
});
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "api",
pattern: "{controller}/{action}/{id?}");
endpoints.MapControllerRoute(
name: "api",
pattern: "{controller}/{action}/{name}");
endpoints.MapControllerRoute(
name: "api",
pattern: "{controller}/{action}/{date}");
endpoints.MapControllerRoute(
name: "api",
pattern: "{controller}/{action}/{email}");
});
if (bool.Parse(builder.Configuration["UseSwagger"]))
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API");
c.DefaultModelsExpandDepth(-1);
});
}
app.MapHub<HjsHub>("/hjsHub");
app.Run();
It works flawlessly with my localhost
.
Azure App Service hosts my Web API. When I ran this code and attempted to connect SignalR, I received the error method is not allowed.
Is there any configuration needed at Azure or am I missing something in my code?
I have tried above code in local server and tried it on Azure App service.
UPDATE
Please change your middleware order like below and test again.
You should use below code to allow all Origins for testing.
If you want it works for specific url, please don't use
WithOrigins
andAllowAnyOrigin
together.