I had develop the blazor WASM application using JWT Authentication when login
I had get Authenticationstate using authentication state provider and implement Customimplement for Authentication state provider:
CustomAuthenticationStateProvider
public class CustomAuthenticationStateProvider : AuthenticationStateProvider
{
private readonly HttpClient _httpClient;
private readonly ILocalStorageService _localStorageService;
public CustomAuthenticationStateProvider(HttpClient httpClient, ILocalStorageService localStorageService)
{
_httpClient = httpClient;
_localStorageService = localStorageService;
}
public async override Task<AuthenticationState> GetAuthenticationStateAsync()
{
User currentUser = await GetUserByJWTAsync();
if (currentUser != null && currentUser.LoginName != null)
{
var claimEmailAddress = new Claim(ClaimTypes.Name, currentUser.LoginName);
var claimNameIdentifier = new Claim(ClaimTypes.NameIdentifier, Convert.ToString(currentUser.Id));
var claimsIdentity = new ClaimsIdentity(new[] { claimEmailAddress, claimNameIdentifier }, "serverAuth");
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
return new AuthenticationState(claimsPrincipal);
}
else
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
public async Task<User> GetUserByJWTAsync()
{
var returnedUser = new User();
var jwtToken = await _localStorageService.GetItemAsStringAsync("jwt_token");
if (jwtToken == null) return null;
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "api/Account/GetUserByJWT");
requestMessage.Content = new StringContent(jwtToken);
requestMessage.Content.Headers.ContentType
= new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
var response = await _httpClient.SendAsync(requestMessage);
if (response.IsSuccessStatusCode)
{
returnedUser = await response.Content.ReadFromJsonAsync<User>();
}
if (returnedUser != null) return await Task.FromResult(returnedUser);
else return null;
}
}
APP.razor
@using Microsoft.AspNetCore.Components.Authorization
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject NavigationManager Navigation
@using WebAssembly.Client.Pages;
@using System.Security.Claims;
<CascadingAuthenticationState>
<CascadingValue Value="Authstate">
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
<NotAuthorized>
<!--
@if (!context.User.Identity.IsAuthenticated)
{
<Login />
}
</NotAuthorized>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingValue>
</CascadingAuthenticationState>
@code{
protected AuthenticationState Authstate{ get; set; }
protected override async Task OnInitializedAsync()
{
Authstate = await AuthenticationStateProvider.GetAuthenticationStateAsync();
}
}
Login.razor
[CascadingParameter]
private AuthenticationState authState { get; set; }
protected override async Task OnInitializedAsync()
{
var authtstate = authState;
if(authState.User.Identity.IsAuthenticated)
{
}
}
protected async void sign()
{
Dictionary<string, string> keyvalues = new Dictionary<string, string>();
keyvalues.Add("userName", auth.Username);
keyvalues.Add("password", auth.Password);
var request = new HttpRequestMessage(HttpMethod.Post, "api/Account/Login");
var content = JsonConvert.SerializeObject(keyvalues);
StringContent stringContent = new StringContent(content,
System.Text.Encoding.UTF8, "application/json");
HttpResponseMessage response = await
Httpclient.PostAsync(request.RequestUri, stringContent);
if (response.IsSuccessStatusCode)
{
var data = response.Content.ReadAsStringAsync().Result;
Root result = JsonConvert.DeserializeObject<Root>(data);
if(result.status)
{
await _localStorageService.SetItemAsync("jwt_token",result.JWT);
}
authState=await_authenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity.IsAuthenticated)
{
navigationManager.NavigateTo($"/Location");
}
}
}
Location.razor.cs
[Microsoft.AspNetCore.Authorization.Authorize]
Public partial class Location : componentbase
{
}
I had used JWT token concept. Whenever login JWT token created in Login api
that was return back to client and stored in local storage and then get the
user using token validation then Authentication status. First timeApplication
loaded at the time Authentication state false. In this application app.razor
get the Authentication status using GetAuthenticationstateAsync() that was
shared to all child component like Login page. Whenever click sign at the
time Login api get suucess then jwt stored local storage then get the
Authentication status valid then LOgin page need to navigate Location page
but in app.razor IsAuthentication is false then redirect back to login page
i.e Location page unauthorized. [Authorize] attribute can not allow the user
navigate to Location page.
please help. I want to find what is the issue
Thanks&Regards
Ramesh
What I have tried:
I had used JWT token concept. Whenever login JWT token created in Login api
that was return back to client and stored in local storage and then get the
user using token validation then Authentication status. First timeApplication
loaded at the time Authentication state false. In this application app.razor
get the Authentication status using GetAuthenticationstateAsync() that was
shared to all child component like Login page. Whenever click sign at the
time Login api get suucess then jwt stored local storage then get the
Authentication status valid then LOgin page need to navigate Location page
but in app.razor IsAuthentication is false then redirect back to login page
i.e Location page unauthorized. [Authorize] attribute can not allow the user
navigate to Location page.