Hi,
I defined the authentication login/register in my application with ASPNET core.
It work well!
I'd like to add an admin page where I can place the table for assigning/changing the roles of each user.
In Seed AspnetRole in class server project/RoleConfiguration.cs
as below
public class RoleConfiguration : IEntityTypeConfiguration<IdentityRole>
{
public void Configure(EntityTypeBuilder<IdentityRole> builder)
{
builder.HasData(
new IdentityRole
{
Name = "Visitor",
NormalizedName = "VISITOR"
},
new IdentityRole
{
Name = "Administrator",
NormalizedName = "ADMINISTRATOR"
}
);
}
I don't how I can assign the role to user? can you help to do that ?
You will find below the code for authentication :
is based on : https://codewithmukesh.com/blog/authentication-in-blazor-webassembly/
Controller
[Route("api/[controller]/[action]")]
[ApiController]
public class AuthController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
public AuthController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}
// Login
[HttpPost]
public async Task<IActionResult> Login(LoginRequest request)
{
var user = await _userManager.FindByNameAsync(request.UserName);
if (user == null) return BadRequest("User does not exist");
var singInResult = await _signInManager.CheckPasswordSignInAsync(user, request.Password, false);
if (!singInResult.Succeeded) return BadRequest("Invalid password");
await _signInManager.SignInAsync(user, request.RememberMe);
return Ok();
}
// Register
[HttpPost]
public async Task<IActionResult> Register(RegisterRequest parameters)
{
var user = new ApplicationUser();
user.UserName = parameters.UserName;
var result = await _userManager.CreateAsync(user, parameters.Password);
if (!result.Succeeded) return BadRequest(result.Errors.FirstOrDefault()?.Description);
return await Login(new LoginRequest
{
UserName = parameters.UserName,
Password = parameters.Password
});
// await _userManager.AddToRoleAsync(user, "Visitor");
}
//Logout
[Authorize]
[HttpPost]
public async Task<IActionResult> Logout()
{
await _signInManager.SignOutAsync();
return Ok();
}
//Get Current User
[HttpGet]
public CurrentUser CurrentUserInfo()
{
return new CurrentUser
{
IsAuthenticated = User.Identity.IsAuthenticated,
UserName = User.Identity.Name,
Claims = User.Claims
.ToDictionary(c => c.Type, c => c.Value)
};
}
}
In client project Service/ CustomStateProvider.cs
public class CustomStateProvider : AuthenticationStateProvider
{
private readonly IAuthService api;
private CurrentUser _currentUser;
public CustomStateProvider(IAuthService api)
{
this.api = api;
}
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var identity = new ClaimsIdentity();
try
{
var userInfo = await GetCurrentUser();
if (userInfo.IsAuthenticated)
{
var claims = new[] { new Claim(ClaimTypes.Name, _currentUser.UserName) }.Concat(_currentUser.Claims.Select(c => new Claim(c.Key, c.Value)))
identity = new ClaimsIdentity(claims, "Server authentication");
}
}
catch (HttpRequestException ex)
{
Console.WriteLine("Request failed:" + ex.ToString());
}
return new AuthenticationState(new ClaimsPrincipal(identity));
}
private async Task<CurrentUser> GetCurrentUser()
{
if (_currentUser != null && _currentUser.IsAuthenticated) return _currentUser;
_currentUser = await api.CurrentUserInfo();
return _currentUser;
}
public async Task Logout()
{
await api.Logout();
_currentUser = null;
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
public async Task Login(LoginRequest loginParameters)
{
await api.Login(loginParameters);
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
public async Task Register(RegisterRequest registerParameters)
{
await api.Register(registerParameters);
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
}
IAuthService
public interface IAuthService
{
Task Login(LoginRequest loginRequest);
Task Register(RegisterRequest registerRequest);
Task Logout();
Task<CurrentUser> CurrentUserInfo();
}
AuthService.cs
public class AuthService : IAuthService
{
private readonly HttpClient _httpClient;
public AuthService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<CurrentUser> CurrentUserInfo()
{
var result = await _httpClient.GetFromJsonAsync<CurrentUser>("api/auth/currentuserinfo");
return result;
}
public async Task Login(LoginRequest loginRequest)
{
var result = await _httpClient.PostAsJsonAsync("api/auth/login", loginRequest);
if (result.StatusCode == System.Net.HttpStatusCode.BadRequest) throw new Exception(await result.Content.ReadAsStringAsync());
result.EnsureSuccessStatusCode();
}
public async Task Logout()
{
var result = await _httpClient.PostAsync("api/auth/logout", null);
result.EnsureSuccessStatusCode();
}
public async Task Register(RegisterRequest registerRequest)
{
var result = await _httpClient.PostAsJsonAsync("api/auth/register", registerRequest);
if (result.StatusCode == System.Net.HttpStatusCode.BadRequest) throw new Exception(await result.Content.ReadAsStringAsync());
result.EnsureSuccessStatusCode();
}
}
Program.cs
builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.ConfigureApplicationCookie(options =>
{
options.Cookie.HttpOnly = false;
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = 401;
return Task.CompletedTask;
};
});
Thanks in advance to your help!