I am doing a semester project with my group (https://github.com/Tymon2115/ABDOT), and right now I am trying to create login functionality in blazor.
The problem I have is that when I log in i get correctly authorized, but I would like to get the returned User ID so I can load user’s profile page and so on, but I get that exception.
Code:
<NotAuthorized>
<h3>Login</h3>
<div class="form-group">
<p>@confirmationMessage</p>
<input type="text" placeholder="e-mail" @bind-value="email"/>
</div>
<div class="form-group">
<input type="password" placeholder="password" @bind-value="password"/>
</div>
<div style="color:red">@errorMessage</div>
<p class="actions">
<button class="btn-outline-dark" @onclick="PerformLogin">Login</button>
<button class="btn-outline-dark" @onclick="Cancel">Cancel</button>
</p>
</NotAuthorized>
@code{
public async Task PerformLogin()
{
errorMessage = " ";
Console.WriteLine("logging in");
try {
User returnedUser = await ((CustomAuthenticationStateProvider) AuthenticationStateProvider).ValidateLogin(email, password);
email = "";
password = "";
Id = returnedUser.Id;
}
catch (Exception e) {
Console.WriteLine(e);
errorMessage = e.Message;
throw;
}
Console.WriteLine("Success");
}
}
public class CustomAuthenticationStateProvider : AuthenticationStateProvider {
private readonly IJSRuntime jsRuntime;
private readonly IUserService userService;
private User cachedUser;
public CustomAuthenticationStateProvider(IJSRuntime jsRuntime, IUserService userService)
{
this.jsRuntime = jsRuntime;
this.userService = userService;
}
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var identity = new ClaimsIdentity();
if (cachedUser == null)
{
string userAsJson = await jsRuntime.InvokeAsync<string>("sessionStorage.getItem", "currentUser");
if (!string.IsNullOrEmpty(userAsJson))
{
cachedUser = JsonSerializer.Deserialize<User>(userAsJson);
identity = SetupClaimsForUser(cachedUser);
}
}
else
{
identity = SetupClaimsForUser(cachedUser);
}
ClaimsPrincipal cachedClaimsPrincipal = new ClaimsPrincipal(identity);
return await Task.FromResult(new AuthenticationState(cachedClaimsPrincipal));
}
public async Task<User> ValidateLogin(string username, string password)
{
Console.WriteLine("Validating log in");
if (string.IsNullOrEmpty(username)) throw new Exception("Enter username");
if (string.IsNullOrEmpty(password)) throw new Exception("Enter password");
ClaimsIdentity identity = new ClaimsIdentity();
try
{
User user = await userService.ValidateUser(username, password);
identity = SetupClaimsForUser(user);
string serialisedData = JsonSerializer.Serialize(user);
await jsRuntime.InvokeVoidAsync("sessionStorage.setItem", "currentUser", serialisedData);
cachedUser = user;
}
catch (Exception e)
{
throw e;
}
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(new ClaimsPrincipal(identity))));
return cachedUser;
}
public async Task Logout()
{
cachedUser = null;
var user = new ClaimsPrincipal(new ClaimsIdentity());
await jsRuntime.InvokeVoidAsync("sessionStorage.setItem", "currentUser", "");
NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user)));
}
private ClaimsIdentity SetupClaimsForUser(User user)
{
List<Claim> claims = new List<Claim>();
ClaimsIdentity identity = new ClaimsIdentity(claims, "apiauth_type");
return identity;
}
}