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

ASP.NET Identity如何获取Blazor WASM托管应用中保存的Spotify第三方访问令牌

问题核心原因

你当前的操作有4个核心错误导致无法取到令牌:

  • HttpContext.Items、HttpContext.Features都是单次请求生命周期有效,OnCreatingTicket 执行在Spotify OAuth回调的请求中,回调完成后会触发302重定向到应用页面,新的请求里这两个存储的值会全部清空,完全没必要通过这两个位置存令牌
  • 你自定义存储的令牌名拼写错误:将SpotifyAccessToken错写为SpofityAccessToken,就算存储成功也无法按正确名称读取
  • 配置Spotify OAuth时没有开启SaveTokens = true,导致你存入AuthenticationProperties的令牌不会持久化到认证Cookie中,后续请求自然无法读取
  • 新增的自定义声明没有配置映射规则,会被ASP.NET Core默认的声明过滤策略丢弃,导致User.Claims集合中找不到对应项

修复步骤

1. 修正OAuth配置

在Program.cs的Spotify认证配置中开启令牌保存,配置声明映射:

builder.Services.AddAuthentication()
    .AddSpotify(options =>
    {
        options.ClientId = "你的Spotify ClientId";
        options.ClientSecret = "你的Spotify ClientSecret";
        // 核心配置:开启令牌持久化到Cookie
        options.SaveTokens = true;
        // 配置自定义声明映射,避免被过滤
        options.ClaimActions.MapCustomJson("SpotifyAccessToken", json => 
            json.GetString("access_token"));
        
        options.Events.OnCreatingTicket = ctx =>
        {
            List<AuthenticationToken> tokens = ctx.Properties.GetTokens().ToList();
            tokens.Add(new AuthenticationToken()
            {
                Name = "TicketCreated",
                Value = DateTime.UtcNow.ToString("O")
            });
            ctx.Properties.StoreTokens(tokens);
            
            // 新增自定义声明
            var spotifyAccessToken = tokens.First(x => x.Name == "access_token").Value;
            ctx.Identity.AddClaim(new Claim("SpotifyAccessToken", spotifyAccessToken));
            return Task.CompletedTask;
        };
    });

2. (可选)如果使用ASP.NET Core Identity,配置自定义声明工厂

如果你的项目集成了Identity,需要自定义声明工厂避免自定义声明被Identity过滤:

public class CustomClaimsPrincipalFactory : UserClaimsPrincipalFactory<IdentityUser>
{
    public CustomClaimsPrincipalFactory(UserManager<IdentityUser> userManager, 
        IOptions<IdentityOptions> optionsAccessor) : base(userManager, optionsAccessor)
    {
    }

    protected override async Task<ClaimsIdentity> GenerateClaimsAsync(IdentityUser user)
    {
        var identity = await base.GenerateClaimsAsync(user);
        return identity;
    }
}

// Program.cs中注册工厂
builder.Services.AddScoped<IUserClaimsPrincipalFactory<IdentityUser>, CustomClaimsPrincipalFactory>();

3. 控制器中正确读取令牌

不需要手动调用AuthenticateAsync或者SignInAsync,直接用ASP.NET Core内置的扩展方法或者取Claims即可:

[HttpGet]
[Authorize]
public async Task Get()
{
    // 方法1:直接读取官方持久化的Spotify access_token,无需自定义存储
    var accessToken = await HttpContext.GetTokenAsync("Spotify", "access_token");
    
    // 方法2:读取你自定义存入的声明
    var customToken = User.Claims.FirstOrDefault(c => c.Type == "SpotifyAccessToken")?.Value;

    var client = new SpotifyAPI.Web.SpotifyClient(accessToken);
    var res2 = await client.Player.GetCurrentPlayback();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:45:07