【问题标题】:Notify all components that authentication has been changed in Blazor通知所有组件 Blazor 中的身份验证已更改
【发布时间】:2020-11-16 13:47:24
【问题描述】:

我有一个带有很多 html 标记的 Blazor(版本 net5.0)组件,这里是其中的一部分:

<a class="@(IsAuthenticated?"":"hide")" href="#">My link for logged in users</a>

这是我的 c# 代码(MyComponent.Razor):

    [CascadingParameter] private Task<AuthenticationState> authenticationState { get; set; }
    private AuthenticationState auth;
    public bool IsAuthenticated { get; set; }

    protected async override Task OnInitializedAsync()
    {
        auth = await authenticationState;
        var user = auth.User.Identity.IsAuthenticated;
        await base.OnInitializedAsync();
    }

在我的登录组件中成功登录后我调用StateHasChanged();

  void Login()
  {
    ...
    StateHasChanged();
  }

但登录后不会应用对 MyComponent 的任何更改,除非我刷新页面以便组件重新呈现自身。

注意:我不想使用AuthorizeView,因为正如我所提到的,MyComponent 中有很多标记和组件,我不想使用对于我想根据用户身份验证更改其行为的每种样式或元素,都有一个 AuthorizeView

更新:我的App.razor 组件中有以下代码:

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(Layout)" >
            <Authorizing>
                <text> my Custom Authotizing in app.razor ...</text>
            </Authorizing> 
            <NotAuthorized>
                <text> my Custom NOT Authotized in app.razor ...</text>
            </NotAuthorized>
        </AuthorizeRouteView>
    </Found>
    <NotFound>
        <CascadingAuthenticationState>
            <LayoutView Layout="@typeof(Layout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        </CascadingAuthenticationState>
    </NotFound>
</Router>

【问题讨论】:

  • 另一个不允许使用 Blazor 标签的例子。 OP 应该始终说明他使用的是什么风味的 Blazor
  • @enet 没有主机的独立 WebAssembly
  • @enet 我不使用 OIDC 或 IdentyServer4。我认为当用户验证(无论如何)组件时应该通知。
  • @enet 谢谢。我使用 Jwt 令牌身份验证。它工作正常。 AuthorizeView 也可以正常工作。
  • @enet 不,我没有解决问题,我只是说我的代码的其他部分没有问题

标签: c# asp.net-core authentication blazor blazor-webassembly


【解决方案1】:

查看AuthorizedView源代码我终于发现我应该使用OnParametersSetAsync和一个属性:

<a class="@MyClassProp" href="#">My link for logged in users</a>

代码:

public string MyClassProp { get; set; } = "hide";
public async Task<string> GetClassAsync()=> (await authenticationState).User.Identity.IsAuthenticated ? "" : "hide";
    
protected async override Task OnParametersSetAsync()
{
    MyClassProp = await GetClassAsync(); // also call GetClass in OnInitializedAsync
    StateHasChanged();
    await base.OnParametersSetAsync();
}

我在问题中创建的IsAuthenticated 属性始终等于其初始状态,并且不会随着AuthenticationState 的更改而更改,即使我在OnParametersSetAsync 中重置其值也是如此。不需要在 Login 和 Logout 方法中调用 StateHasChanged()。如果我不使用MyClassProp 属性,而是从标记中调用GetClassAsync,它也不起作用。

警告:通过为未经授权的用户设置css类来隐藏元素的整个方法存在安全问题,因为即使用户仅使用浏览器,内容仍然可以被暴露或修改.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-30
    • 2021-04-22
    • 2021-11-05
    • 2020-02-27
    • 2020-11-02
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    相关资源
    最近更新 更多