Reputation: 5141
To maintain compatibility with existing applications I was planing on using Cookie Middleware without ASP.NET Identity, as described in the documentation:
https://docs.asp.net/en/latest/security/authentication/cookie.html
This seems to work as expected as far as logging a user in, but I'm having issues with roles -- specifically when using the [Authorize(Roles = "ADMIN")]
.
In the code below, I can call p.IsInRole("ADMIN")
and my implementation of MyClaimsPrincipal.IsInRole()
is called and returns true.
What doesn't work is the [Authorize(Roles = "ADMIN")]
attribute because it ends up calling ClaimsPrincipal.IsInRole
(which returns False) instead of MyClaimsPrincipal.IsInRole()
(which returns True).
[Authorize(Roles = "ADMIN")]
public class MyAdminController : Controller
{
public IActionResult Index()
{
var p = new MyClaimsPrincipal(ClaimsPrincipal.Current);
bool isAdmin = p.IsInRole("ADMIN");
return View();
}
}
When not using Identity and only using Cookie Middleware, can I use the [Authorize(Roles = "ADMIN")]
attribute?
How? :-)
If I had to guess, I'm not implementing p.IsInRole()
correctly -- currently this method loads the roles, then returns a True/False. Perhaps I have to 'load' my roles elsewhere in such a way that the ClaimsPrincipal.IsInRole
is sufficient. If I was using Identity(), I assume this would be an implementation of IUserRoleStore
.
My other 'if i had to guess' answer is that somewhere in startup.cs I need to replace the current ClaimsPrincipal
with an instance of MyClaimsPrincipal
.
Thank you!
Upvotes: 3
Views: 861
Reputation: 24063
You should add role claims when cookie is created.
In startup.cs:
app.UseCookieAuthentication(options =>
{
options.AuthenticationScheme = "MyCookieMiddlewareInstance";
options.LoginPath = new PathString("/Account/Login/");
options.AccessDeniedPath = new PathString("/Account/Forbidden/");
options.AutomaticAuthenticate = true;
options.AutomaticChallenge = true;
});
And login post method may be something like this(i assume that you have a custom login page):
[HttpPost]
public IActionResult Login(string userName, string password, string returnUrl)
{
var user = _userService.GetUser(userName, password);// i assume that _userService is injected
if (user == null)
{
//return Error;
}
var claims = new List<Claim>()
{
new Claim(ClaimTypes.NameIdentifier, user.Id),
new Claim(ClaimTypes.Name, user.GetFullName() ),
};
var identity = new ClaimsIdentity(claims, "Forms");
identity.AddClaim(new Claim(ClaimTypes.Role, "ADMIN"));
var principal = new ClaimsPrincipal(identity);
HttpContext.Authentication.SignInAsync("MyCookieMiddlewareInstance", principal);
return Redirect(returnUrl);
}
Upvotes: 4