ASP.NET Core 3.1 - routing Issue - asp.net-core

Since upgrading to 3.1, I seemed to have lost my routing. My endpoints are now just returning a 404 and I have ran out of ideas of what the issue could be. Can anyone see if I'm doing something stupid in my below setup code? All that really changed in my setup code was that I stopped using
app.UseMvc
And now use the endpoint instead
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
Code below
[ApiController]
[Authorize]
[Route("api/guild")]
public class GuildController : Controller
{
[HttpPost("create")]
public async Task<IActionResult> Create([FromBody]CreateGuildRequest request)
{
return Ok();
}
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
var domain = Configuration["Auth0:Domain"];
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = domain;
options.Audience = Configuration["Auth0:Audience"];
});
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(origin => true)
.AllowCredentials()
.Build());
});
services.AddControllers();
services.AddSpaStaticFiles(configuration => { configuration.RootPath = "clientapp/dist"; });
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseSpa(spa =>
{
spa.Options.SourcePath = "clientApp";
if (env.IsDevelopment())
{
spa.UseVueCli(npmScript: "serve", port: 8080);
}
});
app.UseCors("CorsPolicy");
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}

Middleware order matters. Place your UseSpa() after UseEndpoints()
// this should be the last two middlewares, in this order
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "clientApp";
if (env.IsDevelopment())
{
spa.UseVueCli(npmScript: "serve", port: 8080);
}
});

Related

AAD Authentication between client and .Net Core API

I m getting this error when I reach the API from the client. I use MSAL, and I can see in the request the token is load.
Here is my startup configuration.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddAuthentication(defaultScheme: AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options =>
{
options.ClientId = "example";
options.TenantId = "example";
options.ClientSecret = "example";
options.Instance = "https://login.microsoftonline.com/";
});
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins("https://localhost:5001", "http://localhost:5000")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.WithExposedHeaders("Content-Disposition");
});
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors();
//app.UseCors(options =>
//{
// options.WithOrigins("https://localhost:5001", "http://localhost:5000")
// .AllowAnyHeader()
// .AllowAnyMethod()
// .AllowCredentials()
// .WithExposedHeaders("Content-Disposition");
//});
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
I solve the problem chaingin the Configure Services like this:
services.AddAuthentication(defaultScheme: AzureADDefaults.JwtBearerAuthenticationScheme)
.AddAzureADBearer(options =>
{
options.Instance = Environment.GetEnvironmentVariable("AAD_INSTANCE");
options.TenantId = Environment.GetEnvironmentVariable("AAD_TENANT_ID");
options.ClientId = Environment.GetEnvironmentVariable("AAD_CLIENT_ID");
options.ClientSecret = Environment.GetEnvironmentVariable("AAD_CLIENT_SECRET");
});

How to get raw request header in token validation stage of IdentityServer4 (asp.net core)?

I need to read the IP address from request header in ResourcePasswordValidator when people login. But I could not find it in ResourceOwnerPasswordValidationContext. The document I followed: https://identityserver4.readthedocs.io/en/latest/topics/resource_owner.html
PS: LocalApiAuthentication is used, and I'm new to IdentityServer4 framework. Thanks.
Codes in Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiScopes(ApiConfig.GetApis())
.AddInMemoryClients(ApiConfig.GetClients())
.AddInMemoryIdentityResources(ApiConfig.GetIdentityResources())
.AddResourceOwnerValidator<ResourcePasswordValidator>()
.AddProfileService<ProfileService>();
services.AddLocalApiAuthentication();
services.AddAuthorization(options =>
{
options.AddPolicy(IdentityServerConstants.LocalApi.PolicyName, policy =>
{
policy.AddAuthenticationSchemes(IdentityServerConstants.LocalApi.AuthenticationScheme);
policy.RequireAuthenticatedUser();
});
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseIdentityServer();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Inside OWIN Startup.cs, add the password validator middleware to your Identity configuration:
services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
{
options.SignIn.RequireConfirmedAccount = false;
options.SignIn.RequireConfirmedEmail = false;
options.SignIn.RequireConfirmedPhoneNumber = false;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddUserStore<ApplicationUserStore>()
.AddRoleStore<ApplicationRoleStore>()
.AddUserManager<ApplicationUserManager>()
.AddRoleManager<ApplicationRoleManager>()
.AddPasswordValidator<IResourceOwnerPasswordValidator>() //right here
.AddDefaultTokenProviders();

CORS problem .NetCore3 web api,Response to preflight request doesn't pass access control check

NetCore 3.0 and Angular the both are running on my LOCALHOST,
its an Authentication project and i setup my Startup like:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(opt => {
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "https://localhost:44361",
ValidAudience = "https://localhost:4200",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey#345"))
};
});
services.AddCors(options =>
{
options.AddPolicy("EnableCORS", builder =>
{
builder.WithOrigins("http://localhost:4200")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseCors("EnableCORS");
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
My Angular is running on port localhost:4200 and my API runs on localhost:44361
any idea why I get that error?its very strange seems everything is fine should not be that complicated,or im missing something?its 3 days im working on it still no success
With endpoint routing, the CORS middleware must be configured to execute between the calls to UseRouting and UseEndpoints.
You can read this in the Enable Cross-Origin Requests documentation on Microsoft docs.
Move your app.UseCors() so it sits somewhere in between of the routing and endpoint middleware.
app.UseRouting();
app.UseCors("EnableCORS");
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});

Identity Server 4 request validation failed because of invalid scopes

first time seeking help here so I hope i will explain my problem on proper way.
I have a .NET Core 3.0 MVC application up and running and I was trying to add a Identity Server 4 authentication to it. I'm struggling for hours with the following problem.
Sorry, there was an error : invalid_scope
Invalid scope
In the log I got this message
[ERR] Invalid scope: profile
[ERR] Request validation failed
Line bellow that In the info log when checking for scopes I found this JSON objects, and can't see whats problem here.
"scope":"openid profile",
"RequestedScopes":"openid profile"
Here is the config.cs file of the Identity Server project
public static IEnumerable<IdentityResource> Ids =>
new IdentityResource[]
{
new IdentityResources.OpenId()
};
public static IEnumerable<ApiResource> Apis =>
new ApiResource[]
{ };
public static IEnumerable<Client> Clients =>
new Client[]
{
new Client
{
ClientId = "mvc",
ClientName = "Festival MVC",
AllowedGrantTypes = GrantTypes.Implicit,
RedirectUris = { "https://127.0.0.1:44330/signin-oidc" },
PostLogoutRedirectUris = { "https://127.0.0.1:44330/signout-callback-oidc" },
AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId }
}
};
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// uncomment, if you want to add an MVC-based UI
services.AddControllersWithViews();
var builder = services.AddIdentityServer()
.AddTestUsers(TestUsers.Users)
.AddInMemoryIdentityResources(Config.Ids)
.AddInMemoryApiResources(Config.Apis)
.AddInMemoryClients(Config.Clients);
// not recommended for production - you need to store your key material somewhere secure
builder.AddDeveloperSigningCredential();
}
public void Configure(IApplicationBuilder app)
{
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// uncomment if you want to add MVC
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
// uncomment, if you want to add MVC
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
On the .NET Core MVC project I configured the follow in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:5000"; // Auth Server
options.RequireHttpsMetadata = false; // only for development
options.ClientId = "mvc"; // client setup in Auth Server
options.SaveTokens = true;
});
services.AddControllersWithViews();
services.AddDbContext<FestivalContext>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
If you need any other info or code snippet feel free to post.
Thanks in advance and greetings,
Anes !

Asp.net core 3.1 backend does not get the Identity from cookie

I have vue.js frontend and asp.net core 3.1 backend. Backend uses SignInManager and Identity. I am trying to use cookie authentication. Api requests work from Postman(!!) roles are applied, everything, but do not from vue app (httpContext.User.Identity.IsAuthenticated is false). Indentity is empty. Cookie is present in the HttpContext
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDBContext>(options => options.UseSqlServer(Configuration["ConnectionStrings:Default"]));
services.AddCors();
services.AddControllers()
services.AddIdentity<AppUser, IdentityRole>(
opts =>
{
opts.SignIn.RequireConfirmedEmail = true;
}
)
.AddSignInManager<SignInManager<AppUser>>()
.AddEntityFrameworkStores<MyDBContext>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.Cookie.SameSite = SameSiteMode.None;
options.SlidingExpiration = true;
});
//some DI
...
//
}
bit more Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, UserManager<AppUser> userManager)
{
app.UseRouting();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
I was trying to proxy requests to api in vue app. Did not help
module.exports = {
devServer: {
proxy: {
'^/api': {
target: 'https://localhost:44376',
ws: true,
changeOrigin: true
}
}
}
}
What can be wrong?
Maybe you are missing AddRoles<IdentityRoles>()?
services.AddIdentity<AppUser, IdentityRole>(
opts =>
{
opts.SignIn.RequireConfirmedEmail = true;
}
)
.AddRoles<IdentityRoles>() .// <== this line
.AddSignInManager<SignInManager<AppUser>>()
.AddEntityFrameworkStores<MyDBContext>()
.AddDefaultTokenProviders();