Hi all,
I’m still new to blazor development but we have decided to use Blazor .NET8 Web Apps with Radzen Components.
I am trying to create an authentication cookie in the web browser using HttpContext.SignInAsync method but have noticed that I am unable to access HttpContext if I use @rendermode InteractiveServer in my login component file.
I tried accessing the httpcontext using an api controller method but it wasn’t working. In the end I had to strip out all Radzen components on my login form, remove @rendermode then I was able to create the cookie successfully. Code is the following:
@page "/login"
@using System.ComponentModel.DataAnnotations
@using System.Security.Claims
@using Microsoft.AspNetCore.Authentication
@using Microsoft.AspNetCore.Authentication.Cookies
@inject NavigationManager Nav
@inject UserService UserService
<div class="row">
<div class="rz-col-lg-4 rz-offset-lg-4 rz-pt-4 rz-pb-4 rz-border">
<EditForm Model="@loginModel" OnValidSubmit="LoginUser" FormName="LoginForm">
<DataAnnotationsValidator />
<div class="rz-mb-3 rz-text-align-center rz-flex-column">
Login
</div>
<div class="rz-mb-3">
<label>Username:</label>
<InputText @bind-Value="loginModel.Username" placeholder="Username" />
<ValidationMessage For="() => loginModel.Username" />
</div>
<div class="rz-mb-3">
<label>Password:</label>
<InputText type="password" @bind-Value="loginModel.Password" placeholder="Password" />
<ValidationMessage For="() => loginModel.Password" />
</div>
@if (!string.IsNullOrEmpty(loginModel.ErrorMessage))
{
<div class="rz-mb-3">
<span>@loginModel.ErrorMessage</span>
</div>
}
<div class="rz-mb-3">
<button type="submit">Login</button>
</div>
</EditForm>
</div>
</div>
@code {
[SupplyParameterFromForm]
private LoginModel loginModel { get; set; } = new();
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
private async Task LoginUser()
{
loginModel = await UserService.LoginAsync(loginModel);
switch (loginModel.Status)
{
case "success":
var claims = new List<Claim>
{
new(ClaimTypes.NameIdentifier, loginModel.UserId),
new(ClaimTypes.Name, loginModel.Username)
};
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
var authProps = new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTimeOffset.UtcNow.AddHours(loginModel.SessionTimeoutPeriod)
};
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, authProps);
break;
case "pwexpired":
// Navigate to change-password page
Nav.NavigateTo("/password-expired");
break;
}
}
}
Now I am having difficulties adding a log out link to my mainlayout file since I am calling Radzen components in there:
@using Microsoft.Extensions.Caching.Memory
@using System.Security.Claims
@using Microsoft.AspNetCore.Authentication
@using Microsoft.AspNetCore.Authentication.Cookies
@inject UserService LoginService
@inject NavigationManager Nav
@inherits LayoutComponentBase
<RadzenComponents @rendermode="InteractiveServer" />
<RadzenLayout>
<RadzenHeader>
<button @onclick="Logout">Logout</button>
</RadzenHeader>
<RadzenBody>
@Body
</RadzenBody>
</RadzenLayout>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
@code {
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
private async Task Logout()
{
var userIdClaim = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (int.TryParse(userIdClaim, out int userId))
{
bool success = LoginService.Logout(userId);
if (success)
{
await HttpContext.SignOutAsync();
Nav.NavigateTo("/login", true);
}
}
}
}
The button click is doing nothing probably because I didn’t add a @rendermode I think? and I think I might have the same problem of not being able to access HttpContext to delete the cookie.
Can someone please provide the correct steps on how I can still use Radzen components and create/delete a cookie successfully in the web browser. Apologies if I missed an easy step to achieve this, I am still a noob at blazor and learning.
Hope to get some help with this, have been struggling for a while and would like to use these nice radzen components in my login form!