How to get raw request header in token validation stage of IdentityServer4 (asp.net core)? - 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();

Related

has been blocked by CORS policy --why am I getting this error for post request in asp.net core?

for GET request, I got the same error and I fixed that but now for POST request again getting this error. For the GET request I fixed that by writing this in a startup.cs file. What can I do?
public void ConfigureServices(IServiceCollection services) {
services.AddCors(options => {
options.AddPolicy(name: MyAllowSpecificOrigins,
builder => {
builder.WithOrigins("https://localhost:fhfhhfh",
"https://localhost:fhfhf");
});
});
services.AddControllers();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, GameUserContext db) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
db.Database.EnsureCreated();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseCors(MyAllowSpecificOrigins);
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
endpoints.MapRazorPages();
});
}
Allow POST method by extending your builder like this:
builder.WithOrigins("https://localhost:fhfhhfh", "https://localhost:fhfhf")
.WithMethods("POST", "GET");
WithMethods
Or you can allow any method:
builder.WithOrigins("https://localhost:fhfhhfh", "https://localhost:fhfhf")
.AllowAnyMethod();
AllowAnyMethod
Change app.UseCors() to app.UseCors(MyAllowSpecificOrigins);
if it is still not working
try to change your builder to builder => {
builder.WithOrigins("https://localhost:fhfhhfh",
"https://localhost:fhfhf")
.AllowAnyHeader()
.AllowAnyMethod();
});

ASP.NET Core 3.1 - routing Issue

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);
}
});

Is it possible to use tokens for API and cookies for get Razor page or Controller Action in the same app with using identity server?

I have an SPA project with .net core 3.1 & identity server and react.i want to Authorize API with token and Authorize Controller Action or Razor Pages with cookies in Get Request, Is it possible to use both of them in same app?
For example, I want admin area to be Authorize with cookie and the admin to have access to its views by cookie but User area works with react and Api by token.
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>().AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
var builder = services.AddIdentityServer()
.AddApiAuthorization<IdentityUser, ApplicationDbContext>();
builder.Services.ConfigureExternalCookie(options => {
options.Cookie.IsEssential = true;
options.Cookie.SameSite = (SameSiteMode.Unspecified);
});
builder.Services.ConfigureApplicationCookie(options => {
options.Cookie.IsEssential = true;
options.Cookie.SameSite = (SameSiteMode.Unspecified);
});
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddControllersWithViews();
services.AddRazorPages();
services.AddMvc().AddNewtonsoftJson(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
endpoints.MapControllerRoute("adminArea", "{area=Admin}/{controller=Dashboard}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
Yes, it's possible to authorize with different auth schemes in an ASP.Net Core application, you just have to specify it on the [Authorize] tag that you call before the method.
First you have to add both authentications at the services.AddAuthentication() call.
Then, lets say that you want your method to authenticate with JWT token:
[Authorize(AuthenticationSchemes =
JwtBearerDefaults.AuthenticationScheme)]
On the other hand, if you want it to authenticate with a cookie:
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
You can check more of how it works at https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-3.1.

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();