我一直读到IHttpContextAccessor
不应该与Blazor应用程序一起使用。然而,建议的方法似乎都只关注组件内的使用。我试图在策略授权期间访问http上下文,如果不注入IHttpContextAccessor
,我看不到一个明确的方法来做到这一点。在授权过程中也会出现问题吗?
MS特别指出:
另外,出于安全原因,你不能在Blazor应用程序中使用IHttpContextAccessor。Blazor应用程序运行在ASP的上下文之外。. NET核心管道。HttpContext不能保证在IHttpContextAccessor中可用,也不能保证它持有启动Blazor应用程序的上下文。
编辑:这不是一个重复的问题,因为我说的是一个特定的地点和一个不同的时代的Blazor(微软的声明基本上完全禁止它的使用,在这个问题的时候,我应该是重复的)。那里的问题和答案都没有解决我的特定用例(在授权期间)。我问的是_Host。cshtml是不相关的,因为授权处理程序代码是根据我的断点被击中的顺序在_Host之前执行的。
如果您必须使用HttpContext
,那么您必须在渲染_Host.cshtml
时从HttpContext
获得所需的值,并将其保存在一个变量中,并以级联参数的形式在程序的其余部分的组件中使用该变量。
例如,我使用以下过程在Blazor服务器web应用程序中获取HttpContext
。
我首先修改_Host.cshtml
文件如下所示。这里我正在寻找access_token信息。
@{
var token = await HttpContext.GetTokenAsync("access_token");
}
可以看到,我将access_token信息放入令牌变量中,并将其赋值给组件的param-AccessToken
。然后转到App.razor
文件并将AccessToken
变量定义为级联值。如下:
<CascadingValue Name="AccessToken" Value="AccessToken">
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
@code{
[Parameter]
public string AccessToken { get; set; }
}
最后,任何需要AccessToken
值的组件只需要将其定义为级联参数。例如,我创建了一个名为ShowToken.razor
的组件,并将其代码如下:
@page "/showtoken"
<p>This is part of the access token @(AccessToken != null ? AccessToken.Substring(0,30) : "(null)")</p>
@code {
[CascadingParameter(Name = "AccessToken")] public string AccessToken { get; set; }
}
因为您在_Host.cshtml
中收到了HttpContext
,所以它不会在安全方面威胁到您的程序。