I'm implementing a custom AuthenticationStateProvider
and using information from user claims in mainLayout. As far as I understood after executing NotifyAuthenticationStateChanged
method should itself rerender all the components which use <AuthorizeView>
e.t.c. But it doesn't. Moreover, I implemented my own reloader for mainLayout and I reload it using StateHasChanged
after the user logs in. But for some reason it still thinks that there is no one authorized and renders block of code in <NotAuthorized>
block. But if I reload the page manually GetAuthenticationStateAsync
method is executed and after that block of code inside <Authorized>
is rendered. Am I doing smth wrong or it's a bug?My CustomAuthenticationStateProvider
code:
public class CustomAuthenticationStateProvider : AuthenticationStateProvider{ private readonly ISessionStorageService _sessionStorage; public CustomAuthenticationStateProvider(ISessionStorageService sessionStorage) { _sessionStorage = sessionStorage; } public override async Task<AuthenticationState> GetAuthenticationStateAsync() { var userModel = await _sessionStorage.GetItemAsync<AuthorizedModel>("userModel"); var identity = new ClaimsIdentity(); if (userModel != null) { identity = new ClaimsIdentity( new [] { //Some my claims ... }, "api"); } else { identity = new ClaimsIdentity(); } var claimsPrincipal = new ClaimsPrincipal(identity); return new AuthenticationState(claimsPrincipal); } public void AuthenticateUser(AuthorizedModel model) { var identity = new ClaimsIdentity(new [] { //Some my claims ... }); var user = new ClaimsPrincipal(identity); NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user))); } public async Task LogUserOut() { await _sessionStorage.RemoveItemAsync("nickName"); var identity = new ClaimsIdentity(); var user = new ClaimsPrincipal(identity); NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user))); }}
My login:
public async Task HandleValidSubmit(){ var authorizedUser = await loginRepository.TryLogin(_model); ... ((CustomAuthenticationStateProvider)authenticationStateProvider).AuthenticateUser(authorizedUser); await sessionStorage.SetItemAsync("userModel", authorizedUser); navigationManager.NavigateTo("/"); //This is for my custom page reload authorizationState.LoggedIn = true;}
My MainLayout:
@inherits LayoutComponentBase...<AuthorizeView><Authorized><UserInfo /></Authorized><NotAuthorized> //Some block of code for non-authorized ...</NotAuthorized></AuthorizeView> ...
And finally UserInfo code:
@using System.Security.Claims...<div class="user-info"><span class="user-name"> @userFirstName<strong>@userSecondName</strong></span><span class="user-role">@userNickName</span><span class="user-status"><i class="fa fa-circle"></i><span>Online</span></span></div>@code{ [CascadingParameter] private Task<AuthenticationState> authenticationStateTask { get; set; } ClaimsPrincipal user; string userFirstName; ... protected override async Task OnInitializedAsync() { user = (await authenticationStateTask).User; //Here I just get userInfo from claims ... } }