Using the Blazor template provided in Visual Studio 2019 with Identity 4 and individual accounts.
I have this controller on the server side
[ApiController, Route("api/[controller]")]
public class DataController : Controller
{
[HttpGet, Route("GetUser")]
public async Task<ActionResult<bool>> GetUser()
{
return User?.Identity?.IsAuthenticated;
}
}
And on the client side I have a Page with this code
@page "/User"
@inject HttpClient Http
@userIsLogged
@code {
private bool userIsLogged;
protected override async Task OnInitializedAsync()
{
userIsLogged = await Http.GetFromJsonAsync<bool>("api/data/GetUser");
}
}
If the user is logged on and I enter into the page from the browser I can see the True text indicating that the user is already logged.
But if I try to request the controller result directly in the browser by entering in https://localhost:44395/Api/Data/GetUser, without using the HttpClient I don't see the expected result even if the user is already logged.
From other posts like this, I guess the problem is related to this line
services.AddAuthentication().AddIdentityServerJwt()
But I don't find how to solve.
My goal is to be able to access to the Identity information of the logged user, usermane, roles, etc from the client using the HttpClient as well as from calling the ActionResult directly from the browser. Can you point me out what is missing in the project in order to do that?
Thanks Ignacio
IdentityServer uses JWT ( Json Web Token) to protect its resources ( in this case is the API ) in same time the application is registered as a client that allowed to access the Web Api ( which included within it's Scope)
So the reason it is working during the connection from the application because the httpclient send the token as you see in the following pic
The Token issued by IdentityServer
Also Notice when you start your application Blazor application will request the required parameters from identityserver (OidcConfigurationController) as you see in the following pic
Also see the returned parameters to the blazor app which show the scope clearly
So the conclusion, yes you won't be able to access your secure api unless it is within the application that has access to it
Update (after Question has been updated )
You will need to inject The following provider in your page
@inject Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider AuthenticationStateProvider
Then use it as following
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
user = authState.User;
var claims = user.Claims?.ToList();
Also if you want to secure your pages based on Roles/policy you could add the policy in program.cs
as following
builder.Services.AddAuthorizationCore(options =>
{
options.AddPolicy("Admin", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireRole("Admin");
});
});
Then use it within your partial class as following
[Authorize(Policy = "Admin")]
or within your page as following
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy ="Admin")]
Good luck
If this answered your question, feel free to Mark as answered