Why Authorize Identity not work correctly? - asp.net-mvc

Hi I try Create project with asp.net core mvc. I Create some Controller and also user Identity 3.1 for add manage users and add role to them. I Create 2 role (Normal, Admin) and for example I want only normal user access to the My AccountController. also the users default role is Normal after Registered. But when this type of user login and try open the account they redirect to the signin page. How can I fix this ?
i change all of the password option false temporary to create user test faster.
the below code is all of my configure from startup.
[Authorize(Roles = "Normal")]
public class AccountController : Controller
{
public IActionResult Index()
{
return View("Account");
}
}
enter code| services.AddDbContext<DataAcessLayer.DB>(s => s.UseSqlServer(Configuration.GetConnectionString("CON1")) );
services.AddIdentity<User, IdentityRole>(option =>
{
option.Password.RequireDigit = false;
option.Password.RequireLowercase = false;
option.Password.RequireUppercase = false;
option.Password.RequireNonAlphanumeric = false;
option.Password.RequiredLength = 5;
option.SignIn.RequireConfirmedPhoneNumber = false;
option.SignIn.RequireConfirmedAccount = false;
option.SignIn.RequireConfirmedEmail = false;
})
.AddUserManager<UserManager<User>>()
.AddRoles<IdentityRole>()
.AddRoleManager<RoleManager<IdentityRole>>()
.AddEntityFrameworkStores<DataAcessLayer.DB>();
services.ConfigureApplicationCookie(options =>
{
options.AccessDeniedPath = "/Sign/404";
options.Cookie.Name = "WebAppIdentityCookie";
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
options.LoginPath = "/Sign/SignIn";
options.SlidingExpiration = true;
});
and this is my login code:
[HttpPost]
public async Task<IActionResult> login(Models.UserModel usermodel)
{
var user = await userManager.FindByNameAsync(usermodel.UserName);
if (user == null)
{
ModelState.AddModelError("", "نام کاربری یا رمز عبور اشتباه است.");
return View("SignIn", usermodel);
}
var SignInResult = await signInManager.PasswordSignInAsync(user, usermodel.Password, true, true);
if (SignInResult.Succeeded)
{
return RedirectToAction("Index", "Account");
}
else
{
ModelState.AddModelError("", "نام کاربری یا رمز عبور اشتباه است.");
return View("SignIn", usermodel);
}
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/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.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}

try changing
app.UseAuthorization();
app.UseAuthentication();
to
app.UseAuthentication();
app.UseAuthorization()
read this article:
Asp.net Core Middlewares

Related

This Page isn't working Localhost redirected too many times MVC

Program.cs File with Cookie authentication:
builder.Services.AddAuthentication("CookieAuthentication").AddCookie("CookieAuthentication", options =>
{
options.LoginPath = "/<Login/LoginView";
options.AccessDeniedPath = "/Login/AccessDenied";
});
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Login}/{action=Signup}/{id?}");
app.Run();
Login Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult LoginView(string username, string password)
{
if (!ModelState.IsValid)
{
//Error code here
}
if (!UserExists(username, password))//Check if user exists in Database
{
//Error code here
}
TempData["Username"] = username;
return RedirectToAction("Index", "Home");
//I used breakpoint here and this code runs but doesn't work properly.
}
I have also used the [Authorize] attribute on Home Controller to prevent users from accessing it without login.Login/LoginView is the Login rage Path.
This Page isn't working Localhost redirected too many times MVC
For your current scenario,be sure add the [AllowAnonymous] on your Index action in the HomeController. And your LoginPath is /Home/Index, it is no need to be authorized.
[Authorize]
public class HomeController : Controller
{
[AllowAnonymous]
public async Task<IActionResult> Index()
{
//do your stuff...
return View();
}
//....
}
Update:
Cookie authentication to login
Program.cs:
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
{
options.LoginPath = "/Login/LoginView";
options.AccessDeniedPath = "/Login/AccessDenied";
});
var app = builder. Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication(); //be sure add authentication and authorization middleware.....
app.UseAuthorization();
//...
How to sigh in the user:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> LoginView(string username, string password)
{
if (!ModelState.IsValid)
{
//Error code here
}
if (!UserExists(username, password))//Check if user exists in Database
{
//Error code here
}
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier,username) //add the claims you want...
};
//authProperties you can choose any option you want, below is a sample...
var authProperties = new AuthenticationProperties
{
//IssuedUtc = DateTimeOffset.UtcNow,
//ExpiresUtc = DateTimeOffset.UtcNow.AddHours(1),
//IsPersistent = false
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
TempData["Username"] = username;
return RedirectToAction("Index", "Home");
}

Asp.Net Core Twitch OAuth: Correlation Failed

I configured Twitch authentication for my website using this tutorial: https://blog.elmah.io/cookie-authentication-with-social-providers-in-asp-net-core/
In the Twitch dev console I added the https://localhost:44348/signin-twitch url to the callback urls. I've implemented oauth for other providers before, but having troubles with Twitch.
When I try to login, I get the Twitch authorization screen, but after clicking 'Authorize' it redirects me to /signin-twitch + params which returns a Correlation Failed exception.
Exception: An error was encountered while handling the remote login.
I have a feeling it might have to do with the routing. It's setup like this because I have a frontend application with it's own routing (hence the Fallback)
Here is all relevant code.
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication(options =>
{
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = "/signin";
options.LogoutPath = "/signout";
})
.AddTwitch(TwitchAuthenticationDefaults.AuthenticationScheme, options =>
{
options.ClientId = "xxx";
options.ClientSecret = "xxx";
options.Scope.Add("user:read:email");
options.SaveTokens = true;
options.AccessDeniedPath = "/";
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapFallbackToController("Index", "Home");
});
}
public class AuthenticationController : Controller
{
[HttpGet("~/signin")]
public IActionResult SignIn(string returnUrl = "")
{
return Challenge(TwitchAuthenticationDefaults.AuthenticationScheme);
}
}
I think that the error occurs because you're trying to access the URL which is assigned as Callback Path.
Try some variant of this:
[HttpGet("~/signin")]
public IActionResult SignIn()
{
var authProperties = _signInManager
.ConfigureExternalAuthenticationProperties("Twitch",
Url.Action("LoggingIn", "Account", null, Request.Scheme));
return Challenge(authProperties, "Twitch");
}
Source: this answer and this one.
Other stuff to check:
Multiple clients with the same Callback Path
CookiePolicyOptions
HTTPS redirect

how to set identity page by default and and after login it redirect to perticular page

I have added identity in asp.net core 3.1, How can i set identity login page as default and after successfully login it should redirect to particular page ?
In the Public void ConfigureServices(IServiceCollection services) method add the following codes at the bottom:
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(15);
options.LoginPath = "/Identity/Account/Login";
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.SlidingExpiration = true;
});
Note the LoginPath and AccessDeniedPath properties. Change the other properties to fit your requirements.
For the redirection it is actually coded in the login action which will redirect the user to a specific page. On successful login write the followings to redirect to the root page:
returnUrl = returnUrl ?? Url.Content("~/");
return LocalRedirect(returnUrl);
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddRazorPages();
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(15);
options.LoginPath = "/Identity/Account/Login";
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.SlidingExpiration = true;
});
}
// 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("/Home/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.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}

How to solve Usermanage System.AggregateException: 'One or more errors occurred.'

The code was working perfectly but all of a sudden the seed method for the user is no longer working after I push to the production server with a fresh database.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequiredLength = 4;
options.Password.RequireUppercase = false;
})
.AddErrorDescriber<JapaneseErrorDescriber>()
.AddRoleManager<RoleManager<IdentityRole>>()
.AddDefaultUI()
.AddDefaultTokenProviders()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddDistributedMemoryCache();
services.AddMemoryCache();
services.AddHttpContextAccessor();
services.AddSession(options =>
{
options.Cookie.Name = ".AdventureWorks.Session";
options.IdleTimeout = TimeSpan.FromDays(365);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, UserManager<IdentityUser> userManager, ApplicationDbContext context, IServiceProvider service)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
ApplicationDbInitializer.SeedUsers(userManager, context);
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
-- Seed method
public static void SeedUsers(UserManager<IdentityUser> userManager, ApplicationDbContext context)
{
if (userManager.FindByEmailAsync("admin#admin.com").Result == null)
{
IdentityUser user = new IdentityUser
{
UserName = "admin#admin.com",
Email = "admin#admin.com"
};
IdentityResult result = userManager.CreateAsync(user, "adminpass").Result;
> System.AggregateException: 'One or more errors occurred. (Object reference not set to an instance of an object.)'
> NullReferenceException: Object reference not set to an instance of an object.
if (result.Succeeded)
{
userManager.AddToRoleAsync(user, "Admin").Wait();
}
}
}
So I deleted all the data from the Dev Database and tried to see what was going on. In debugging mode, I was getting the instance of the Usermanger but when the call to the CreateAsync() was called the error occurs.

Pass TempData between Contollers for Modal return Null?

I want to pass Some String between two controllers to show successful login with modal.I read this topics :
ViewBag, ViewData and TempData
and
RedirectToAction with parameter
but it doesn't work for me and TempData returns Null.it's works fine in this Controllers.
public async Task<IActionResult> LoginConfirm(LoginViewModel model)
{
ApplicationUser user = await userManager.FindByNameAsync(model.Email);
if (user!=null)
{
var status = await signInManager.PasswordSignInAsync(user, model.Pass,model.RememberMe,true);
if (status.Succeeded)
{
TempData["msg"] = "You Login successful ";
return RedirectToAction("Index","Home");
}
}
TempData["msg"] = "Somethings Wrong!";
return View("Login");
}
you have two way
1)
when you using the
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
you enable the GDPR ( General Data Protection Regulation ) And so for as long as the user does not accept your cookie, you will not be able to set cookie in site. And that makes the TempData empty.
2)
After Migrating to ASP Core 2.1 I had this issue and after working for a day find the solution:
in Startup.Configure() app.UseCookiePolicy(); should be after app.UseMVC();
namespace GiftSite
{
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.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddAuthentication();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/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.UseHttpMethodOverride();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}

Resources