Gia*_*rra 8 c# asp.net-core-mvc asp.net-core blazor blazor-server-side
随着 ASP.NET Core 3.0 的推出,我尝试在 MVC Core 应用程序中利用服务器端 Blazor 功能。我首先创建一个简单的导航组件,尝试让用户使用指向控制器操作的按钮退出。但是,我遇到了防伪造令牌验证错误,内容如下:
Microsoft.AspNetCore.Mvc.Infrastruct.ControllerActionInvoker:信息:过滤器“Microsoft.AspNetCore.Mvc.ViewFeatures.Filters.ValidateAntiforgeryTokenAuthorizationFilter”处的请求授权失败。
然后服务器返回 HTTP 400 状态代码。
我正在遵循 Blazor 应用程序模板代码(带有 Visual Studio 2019 的 Blazor 版本 0.7.0):
<AuthorizeView>
<Authorized>
<a href="/Account/Manage">Hello, @context.User.Identity.Name!</a>
<form method="post" action="/Account/Logout">
<button type="submit">Sign out</button>
</form>
</Authorized>
<NotAuthorized>
<a href="/Account/Register">Register</a>
<a href="/Account/Login">Log in</a>
</NotAuthorized>
</AuthorizeView>
Run Code Online (Sandbox Code Playgroud)
我的 MVCAccount控制器有一个带有 注释的注销操作[ValidateAntiForgeryToken],如下所示:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Logout()
{
await _signInManager.SignOutAsync();
_logger.LogInformation("User logged out.");
return RedirectToAction(nameof(HomeController.Index), "Home");
}
Run Code Online (Sandbox Code Playgroud)
过去,我会@Html.AntiForgeryToken()在表单中添加一个以符合我注释的注销操作。在较新版本的 ASP.NET Core 中,您不再需要手动添加它,因为它包含在表单标记帮助程序中。但这两种方法似乎都无法在 Blazor 组件中转换或可用。
如何从 Blazor 组件调用此 MVC 操作并为控制器验证提供防伪令牌?或者根本不再需要这种验证?
即使我的退出案例不是一个大威胁,这对于调用类似注释的任何其他操作也是一样的。
我可能缺少一个适用于混合 MVC 和 Blazor 场景的 CSRF 技术概念。
Rob*_*Rob 14
我一直在尝试让防伪功能适用于注销帖子。我想我刚刚成功让它发挥作用。我愿意接受改进建议!
我在Blazor Server 附加安全方案中使用了 MS 文档,该文档解释了存储 OIDC 访问和刷新令牌以便在 Blazor 组件中使用的方法。我修改了该示例,以便以类似的方式使用防伪令牌,如下所示:
TokenProvider类来存储防伪令牌。public class TokenProvider
{
public string AntiforgeryToken { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
TokenProvider到 DI 中Startup.ConfigureServices()public void ConfigureServices(IServiceCollection services)
{
...
services.AddScoped<TokenProvider>();
...
}
Run Code Online (Sandbox Code Playgroud)
_Host.cshtml并将其作为参数传递给我的App组件@page "/"
@namespace My.Pages
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery antiforgery
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
var token = antiforgery.GetAndStoreTokens(HttpContext).RequestToken;
}
...
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" param-AntiforgeryToken="token" />
...
Run Code Online (Sandbox Code Playgroud)
App.razor然后填充TokenProvider期间OnInitializedAsync()@inject TokenProvider tokenProvider
<Router ....
</Router>
@code {
[Parameter]
public string AntiforgeryToken { get; set; }
protected override Task OnInitializedAsync()
{
tokenProvider.AntiforgeryToken = AntiforgeryToken;
return base.OnInitializedAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
TokenProviderLogout.razor然后可以通过在我的组件中注入来使用@inject TokenProvider tokenProvider
...
<form method="post" action="Logout">
<input name="__RequestVerificationToken" type="hidden" value="@tokenProvider.AntiforgeryToken">
<button type="submit" class="nav-link btn btn-link" title="Log out">
<span class="oi oi-account-logout"></span>
</button>
</form>
...
Run Code Online (Sandbox Code Playgroud)
不知道为什么会弹出这个异常。但这对我有用。只需将其添加到 _Host.cshtml 文件的末尾即可。
@Html.AntiForgeryToken()
</body>
Run Code Online (Sandbox Code Playgroud)