I have created a custom authentication state provider which checks the username and password on our internal LDAP service. My below code works fine during initial login. But after login if I press F5 or refresh the page than it automatically goes to Login Page. Can someone please help?
public class CustomAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly ILdapAuthenticationService _ldapAuthenticationService;
private ClaimsPrincipal _cachedClaimsPrincipal;
public CustomAuthenticationStateProvider(ILdapAuthenticationService
ldapAuthenticationService)
{
_ldapAuthenticationService = ldapAuthenticationService;
}
public override async
Task<Microsoft.AspNetCore.Components.Authorization.AuthenticationState>
GetAuthenticationStateAsync()
{
if (_cachedClaimsPrincipal != null)
return await Task.FromResult(
new
Microsoft.AspNetCore.Components.Authorization.AuthenticationState(_cachedClaimsPrincipal));
return await Task.FromResult(new
Microsoft.AspNetCore.Components.Authorization.AuthenticationState(new ClaimsPrincipal(new
ClaimsIdentity())));
}
public void ValidateLogin(string username, string password)
{
if (string.IsNullOrEmpty(username)) throw new Exception("Enter username");
if (string.IsNullOrEmpty(password)) throw new Exception("Enter password");
if (_ldapAuthenticationService.AuthenticateUser(username, password))
{
_cachedClaimsPrincipal = _ldapAuthenticationService.CurrentUser.ClaimsPrincipal;
}
NotifyAuthenticationStateChanged(
Task.FromResult(new
AuthenticationState(_ldapAuthenticationService.CurrentUser.ClaimsPrincipal)));
}
}
public class RedirectToLogin : ComponentBase
{
[Inject]
protected NavigationManager NavigationManager { get; set; }
[CascadingParameter]
private Task<Microsoft.AspNetCore.Components.Authorization.AuthenticationState>
authenticationStateTask { get; set; }
protected override void OnInitialized()
{
NavigationManager.NavigateTo("/");
}
}
RedirectToLogin is created so that user has to authenticate before browsing any page
Your CustomAuthenticationStateProvider will have a scope that dies after the request, so caching the ClaimsPrincipal in a local member of this class won't work:
private ClaimsPrincipal _cachedClaimsPrincipal;
Add a debug log on the constructor and you'll see its created for each request (hence any stored value in _cachedClaimsPrincipal is lost).
public CustomAuthenticationStateProvider(ILdapAuthenticationService
ldapAuthenticationService)
{
System.Diagnostics.Debug.WriteLine("Constructor");
_ldapAuthenticationService = ldapAuthenticationService;
}
You need to cache it in a persistent location (e.g. Session object for Server-Side or Local Storage for client side).