Following the documentation, I created my custom AuthenticationStateProvider as follows:
public class ApiAuthStateProvider : AuthenticationStateProvider
{
private static AuthenticationState anonymousState = ?
private AuthenticationState _authState;
public ApiAuthStateProvider()
{
_authState = anonymousState;
}
public void SetAuthenticationState(AuthenticationState authState)
{
_authState = authState ?? anonymousState;
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
}
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
return Task.FromResult(_authState);
}
}
The issue is how to initialize anonymous state, so that _authState.User.Identity.IsAuthenticated is false. As in the document, the following will result in authenticated user:
private static AuthenticationState anonymousState =
new AuthenticationState(new ClaimsPrincipal(
new ClaimsIdentity(new Claim[] {}, "none")));
Even the following resulted in authenticated user:
public class AnonymousIdentity : IIdentity
{
public string AuthenticationType => "none";
public bool IsAuthenticated => false;
public string Name => string.Empty;
}
private static AuthenticationState anonymousState;
static ApiAuthStateProvider()
{
var anonymousIdentity = new AnonymousIdentity();
var user = new ClaimsIdentity(anonymousIdentity);
anonymousState = new AuthenticationState(
new ClaimsPrincipal(user));
}
What am I missing here?
Yes, just use:
new AuthenticationState(new ClaimsPrincipal());
This code works for me:
public class CustomAuthenticationProvider : AuthenticationStateProvider
{
private readonly HttpClient _httpClient;
public CustomAuthenticationProvider(HttpClient httpClient)
{
_httpClient = httpClient;
}
public override async Task<AuthenticationState>
GetAuthenticationStateAsync()
{
ClaimsPrincipal user;
// Call the GetUser method to get the status
// This only sets things like the AuthorizeView
// and the AuthenticationState CascadingParameter
var result =
await _httpClient.GetJsonAsync<BlazorUser>("api/user/GetUser");
// Was a UserName returned?
if (result.UserName != "")
{
// Create a ClaimsPrincipal for the user
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, result.UserName),
}, "AzureAdAuth");
user = new ClaimsPrincipal(identity);
}
else
{
user = new ClaimsPrincipal(); // Not logged in
}
return await Task.FromResult(new AuthenticationState(user));
}
}
See: Client Side Blazor Authentication Using Azure AD and a Custom AuthenticationStateProvider