You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor WASM:User.Identity?.IsAuthenticated为true但无法静默获取访问令牌

解决Blazor WASM Azure AD B2C 认证状态误判问题

1. 替代User.Identity?.IsAuthenticated的判断方式

不要仅依赖ClaimsIdentity的IsAuthenticated属性——只要AuthenticationType非空它就会返回true,哪怕令牌已过期。推荐两种更精准的判断方式:

  • 直接验证令牌有效期
    从用户Claims中提取exp声明,转换为时间后对比当前UTC时间:

    private bool IsUserWithValidToken()
    {
        if (User.Identity?.IsAuthenticated != true)
            return false;
        
        var expClaim = User.Claims.FirstOrDefault(c => c.Type == "exp");
        if (expClaim == null || !long.TryParse(expClaim.Value, out var expTimestamp))
            return false;
        
        var expirationTime = DateTimeOffset.FromUnixTimeSeconds(expTimestamp).UtcDateTime;
        return expirationTime > DateTime.UtcNow;
    }
    
  • 通过MSAL静默验证令牌可用性
    注入IPublicClientApplication,尝试静默获取令牌(不触发跳转),以此判断用户状态:

    private async Task<bool> CanGetValidTokenSilently()
    {
        var accounts = await _publicClientApplication.GetAccountsAsync();
        var currentAccount = accounts.FirstOrDefault();
        if (currentAccount == null)
            return false;
        
        try
        {
            var result = await _publicClientApplication.AcquireTokenSilent(new[] { "你的API作用域" }, currentAccount)
                                                       .ExecuteAsync();
            return !string.IsNullOrEmpty(result.AccessToken);
        }
        catch (MsalUiRequiredException)
        {
            // 需要用户交互才能获取令牌,说明当前令牌无效/已过期
            return false;
        }
    }
    

    这种方式直接验证后续API调用能否拿到有效令牌,从根源避免异常跳转。

2. 是否需要自定义策略?

如果你的场景需要结合角色、特定声明、令牌有效期等多维度认证规则,自定义授权策略是合适的选择:

  • 注册自定义策略
    在Program.cs中添加策略及验证逻辑:

    builder.Services.AddAuthorization(options =>
    {
        options.AddPolicy("ValidAuthenticatedUser", policy =>
        {
            policy.RequireAuthenticatedUser();
            policy.AddRequirements(new ValidTokenRequirement());
        });
    });
    
    public class ValidTokenRequirement : IAuthorizationRequirement { }
    
    public class ValidTokenHandler : AuthorizationHandler<ValidTokenRequirement>
    {
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ValidTokenRequirement requirement)
        {
            var expClaim = context.User.Claims.FirstOrDefault(c => c.Type == "exp");
            if (expClaim != null && long.TryParse(expClaim.Value, out var expTimestamp))
            {
                var expirationTime = DateTimeOffset.FromUnixTimeSeconds(expTimestamp).UtcDateTime;
                if (expirationTime > DateTime.UtcNow)
                {
                    context.Succeed(requirement);
                }
            }
            return Task.CompletedTask;
        }
    }
    
  • 在组件中使用策略
    通过IAuthorizationService验证策略:

    @inject IAuthorizationService AuthorizationService
    
    @code {
        private bool IsValidUser { get; set; }
    
        protected override async Task OnInitializedAsync()
        {
            IsValidUser = (await AuthorizationService.AuthorizeAsync(User, "ValidAuthenticatedUser")).Succeeded;
        }
    }
    

3. 额外优化建议

  • 捕获异常后自定义处理
    若仍有场景触发AccessTokenNotAvailableException,不要直接调用Redirect(),改为提示用户主动登录:

    try
    {
        // API调用逻辑
    }
    catch (AccessTokenNotAvailableException ex)
    {
        ShowLoginPrompt = true;
        // 用户点击登录按钮后,再调用ex.Redirect()
    }
    
  • 调整MSAL缓存策略
    配置MSAL时优化令牌缓存,及时清理无效凭证:

    builder.Services.AddMsalAuthentication(options =>
    {
        // 其他配置...
        options.ProviderOptions.Cache.CacheLocation = CacheLocation.LocalStorage;
        options.ProviderOptions.Cache.StoreAuthStateInCookie = false;
    });
    

内容的提问来源于stack exchange,提问作者Paul Suart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 23:20:29