Asp.net core Blazor WebAssembly授权

Asp.net core Blazor WebAssembly授权,asp.net-core,blazor-client-side,blazor-webassembly,Asp.net Core,Blazor Client Side,Blazor Webassembly,我从一个VisualStudio模板开始,这是一个新的Blazor WebAssembly,服务器端使用身份验证和web API 现在我想保护我的页面和服务器API。我做了以下工作: Page: <AuthorizeView Roles="Administrator"> <Authorized> <h1>Weather forecast</h1> <p>This compon

我从一个VisualStudio模板开始,这是一个新的Blazor WebAssembly,服务器端使用身份验证和web API

现在我想保护我的页面和服务器API。我做了以下工作:

Page:
<AuthorizeView Roles="Administrator">
    <Authorized>
        <h1>Weather forecast</h1>

        <p>This component demonstrates fetching data from the server.</p>

        @if (forecasts == null)
        {
            <p><em>Loading...</em></p>
        }
        else
        {
            <table class="table">
                <thead>
                    <tr>
                        <th>Date</th>
                        <th>Temp. (C)</th>
                        <th>Temp. (F)</th>
                        <th>Summary</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var forecast in forecasts)
                    {
                        <tr>
                            <td>@forecast.Date.ToShortDateString()</td>
                            <td>@forecast.TemperatureC</td>
                            <td>@forecast.TemperatureF</td>
                            <td>@forecast.Summary</td>
                        </tr>
                    }
                </tbody>
            </table>
        }
    </Authorized>
    <NotAuthorized>
    ...
    </NotAuthorized>
</AuthorizeView>

@code {

    private WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {
        var response = await Http.GetAsync("Api/WeatherForecast/Get");
        //var resp = await Http.GetFromJsonAsync<WeatherForecast[]>("Api/WeatherForecast/Get");

        if (response.IsSuccessStatusCode)
        {
            var s = await response.Content.ReadAsStringAsync();
            forecasts = await response.Content.ReadFromJsonAsync<WeatherForecast[]>();
        }
    }
}

API
[Authorize]
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class WeatherForecastController : Controller
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            this.logger = logger;
        }

      
        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
页面:
天气预报
此组件演示如何从服务器获取数据

@如果(预测==null) { 加载

} 其他的 { 日期 温度(C) 温度(F) 总结 @foreach(预测中的var预测) { @forecast.Date.ToShortDateString()的 @预测温度 @预测温度 @预测.摘要 } } ... @代码{ 私人天气预报[]预测; 受保护的重写异步任务OnInitializedAsync() { var response=wait Http.GetAsync(“Api/WeatherForecast/Get”); //var resp=await Http.GetFromJsonAsync(“Api/WeatherForecast/Get”); if(响应。IsSuccessStatusCode) { var s=await response.Content.ReadAsStringAsync(); 预测=等待响应.Content.ReadFromJsonAsync(); } } } 美国石油学会 [授权] [ApiController] [路由(“api/[controller]/[action]”) 公共类天气预报控制器:控制器 { 私有静态只读字符串[]摘要=新[] { “冻结”、“支撑”、“寒冷”、“凉爽”、“温和”、“温暖”、“温和”、“炎热”、“闷热”、“灼热” }; 专用只读ILogger记录器; 公共天气预报控制器(ILogger记录器) { this.logger=记录器; } [HttpGet] 公共IEnumerable Get() { var rng=新随机数(); 返回可枚举的范围(1,5)。选择(索引=>NewWeatherForecast { 日期=DateTime.Now.AddDays(索引), 温度c=下一个温度(-20,55), 摘要=摘要[rng.Next(摘要长度)] }) .ToArray(); } }
调用页面“fetchdata”的用户未登录,无法显示des站点。 但是仍然调用OnInitializedAsync。由于[Authorize],API被阻止

但现在问题来了。 使用var response=wait Http.GetAsync(“Api/WeatherForecast/Get”);我得到了一个HttpCode 200。但API从未被调用过?!它来自哪里

这里有什么问题吗?如何使我的页面和API安全

我不希望在每个页面中都像这样使用AuthenticationStateProvider:

@代码{

private WeatherForecast[] forecasts;

[CascadingParameter]
Task<AuthenticationState> authenticationStateTask { get; set; }

protected override async Task OnInitializedAsync()
{

    if(authenticationStateTask.Result.User.IsInRole("Administrator"))
    {
        var response = await Http.GetAsync("Api/WeatherForecast/Get");
        //var resp = await Http.GetFromJsonAsync<WeatherForecast[]>("Api/WeatherForecast/Get");

        if (response.IsSuccessStatusCode)
        {
            var s = await response.Content.ReadAsStringAsync();
            forecasts = await response.Content.ReadFromJsonAsync<WeatherForecast[]>();
        }
    }

}
私人天气预报[]预测;
[CascadingParameter]
任务authenticationStateTask{get;set;}
受保护的重写异步任务OnInitializedAsync()
{
if(authenticationStateTask.Result.User.IsInRole(“管理员”))
{
var response=wait Http.GetAsync(“Api/WeatherForecast/Get”);
//var resp=await Http.GetFromJsonAsync(“Api/WeatherForecast/Get”);
if(响应。IsSuccessStatusCode)
{
var s=await response.Content.ReadAsStringAsync();
预测=等待响应.Content.ReadFromJsonAsync();
}
}
}
}你不必这么做!:)但问题是,你希望整个应用程序都是安全的,还是仅仅几个页面

就个人而言,我更喜欢注入
@injectauthenticationstateprovider AuthenticationStateProvider
,然后使用
getauthenticationstatesync()获取身份验证状态
OnInitializedAsync()
的内部。例如:

受保护的重写异步任务OnInitializedAsync()
{
尝试
{
var authState=等待AuthenticationStateProvider.GetAuthenticationStateAync();
if(authState.User.Identity.IsAuthenticated)
UserName=$“嗨,{authState.User.Claims.FirstOrDefault(x=>x.Type==“display_name”)?.Value}!”;
}
捕获(例外情况除外)
{
Logger.LogError($”未能初始化菜单。错误:{ex}”);
}
}
您可以使用
组件为经过身份验证/授权的用户处理呈现内容。我自己的应用程序中的示例:


我使用此选项仅在当前用户登录时呈现导航。如果没有,没有菜单