I have a application where the user is being logged in using the Azure AD with the details then stored in the database. Now if the user exists in the database they are allocated a role. This role is added to the claims in the startup.cs, which is all fine. However when a user is not stored in the database and needs to be created. The issue is then how do I manage to update the cookie with the user role from the UserController.cs
This is my startup.cs ConfigurationService()
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
services.AddRazorPages()
.AddMicrosoftIdentityUI();
For users that are stored in the database, this is where the role is added to the claims
app.Use((context, next) =>
{
var userId = context.User.Identity.Name;
if (userId == null)
{
return next();
}
var userService = context.RequestServices.GetRequiredService<IUserService>();
if (!userService.DoesUserExist())
return next();
var roles = userService.GetUser().Role.Type;
if (!string.IsNullOrEmpty(roles))
{
context.User.Identities.FirstOrDefault().AddClaim(new Claim(ClaimTypes.Role, roles));
}
return next();
});
The application endpoint is
[HttpGet]
public IActionResult SignInRequest()
{
if (_userService.DoesUserExist())
{
return RedirectToAction(nameof(Index), "Bookings");
}
return RedirectToAction(nameof(Create));
}
For users that are not currently stored in the database they are displayed with a create view where they are required to complete some additional information before being saved to the database. The View
[HttpGet]
public IActionResult Create()
{
return View(GetNewUser());
}
Get New User
private UserVM GetNewUser()
{
return new UserVM()
{
Id = Guid.NewGuid(),
Firstname = _claimsPrincipal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.GivenName).Value,
Lastname = _claimsPrincipal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Surname).Value,
Oid = _claimsPrincipal.Claims.FirstOrDefault(c => c.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier").Value,
Roles = _rolesService.GetRoles().Select(s => new SelectListItem(s.Type, s.Id.ToString())).ToList(),
Locations = _locationService.GetAllLocations().Select(s => new SelectListItem(s.Name, s.Id.ToString())).ToList(),
SelectedRole = UserRoles.EmployeeOnly
};
}
Once the new user has completed the additional information. It is here I would like to update the identity and cookie with the roles claim WITHOUT needing the user to log out and log back in again.
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(UserVM user)
{
//here is where I would like to update the cookie and identity claims
return RedirectToAction(nameof(Index), "Bookings");
}
This is my user model for my views
public class UserVM
{
public Guid Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public int RoleId { get; set; }
public Guid? LocationId { get; set; }
public string Oid { get; set; }
public RolesVM Role { get; set; }
public LocationVM Location { get; set; }
[DisplayName("Name")]
public string FullName
{
get { return $"{Firstname} {Lastname}"; }
set { FullName = ""; }
}
public List<SelectListItem> Locations { get; set; }
public List<SelectListItem> Roles { get; set; }
public string SelectedLocation { get; set; }
public string SelectedRole { get; set; }
}
There will also be a user edit page where a user could have their roles changed by a higher levelled user. There are four main Roles "Super User, Management, Admin, Employee" all new users will be given the Employee role until it is changed by some higher.
I have tried to look about on google for some solid examples of this happening and have been pointed in the direction of UserManager and RoleManager but have been unable to date to get this to work mainly due to lack of knowledge using any of these before. I have seen some using IClaimTransformation but again I have not been able to get this to work with the only example I have found. I would thankful if someone could help point out the steps that are needs or to point me in the direction of a good example I could use a reference point.