ASP.NET标识-获取已保存的第三方访问令牌



我有一个几乎完全在Spotify OAuth上运行的应用程序,它将具有更改音乐播放的功能。

我可以让Spotify OAuth完美工作,这样我就可以登录我的应用程序,但登录后,我需要访问当前用户的Spotify access_token,这样我才能将其转发给我的Spotify请求。

我遵循了ms的指南,试图保存令牌:https://learn.microsoft.com/en-us/aspnet/core/security/authentication/social/?view=aspnetcore-6.0&tabs=visual studio

我尝试了所有这些方法,然后将该令牌保存到HttpContext中,这样我就可以访问它:

options.Events.OnCreatingTicket = ctx =>
{
List<AuthenticationToken> tokens = ctx.Properties.GetTokens().ToList();
tokens.Add(new AuthenticationToken()
{
Name = "TicketCreated",
Value = DateTime.UtcNow.ToString()
});
var spotifyAccessToken = tokens.FirstOrDefault(x => x.Name == "access_token").Value;
tokens.Add(new AuthenticationToken()
{
Name = "SpofityAccessToken",
Value = spotifyAccessToken
});
//store all the tokens as directed by MS
ctx.Properties.StoreTokens(tokens);
//store the properties into the HttpContext in 2 different ways
ctx.HttpContext.Items["Properties"] = ctx.Properties;
ctx.HttpContext.Features.Set(ctx.Properties);
//try adding a claim to the user
ctx.Identity.AddClaims(new[] { new Claim("SpotifyAccessToken", spotifyAccessToken) });
return Task.CompletedTask;
};

我遇到的问题是,我该如何取出这个代币?所有这些方法都不起作用:

[HttpGet]
public async Task Get()
{
await HttpContext.SignInAsync(User);
// try to re-run Authenticate, even though i'm already in an [Authorize] controller
var res = await HttpContext.AuthenticateAsync();
//props2 does not have the tokens i set
var props2 = res.Properties;
//props comes back null
var props = HttpContext.Features.Get<AuthenticationProperties>();
//claims has no SpotifyAccessToken claim
var claims = User.Claims.ToList();
var token = "hard-coded";
//here is where i need the token to then query spotify
var client = new SpotifyAPI.Web.SpotifyClient(token);
var res2 = await client.Player.GetCurrentPlayback();
}

我觉得我什么都试过了,我做错了什么?

这是在一个.NET 6 blazor wasm,.NET核心托管的应用程序中。

还尝试了此处的解决方案,但在HttpContext.SignInAsync 之后在当前HttpRequest中获取AuthenticationProperties无效

signInManager.UpdateExternalAuthenticationTokensSync添加[dbo]中的身份验证令牌。[AspNetUserTokens]

外部登录就是我所说的:

// Sign in the user with this external login provider if the user already has a login.
var signInResult = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: true, bypassTwoFactor: true);
if (signInResult.Succeeded)
{
await _signInManager.UpdateExternalAuthenticationTokensAsync(info);
_logger.LogInformation("{Name} logged in with {LoginProvider} provider.", info.Principal.Identity.Name, info.LoginProvider);
return LocalRedirect(returnUrl);
}

稍后您可以使用获得它

var token = await userManager
.GetAuthenticationTokenAsync(user, "Spotify", "access_token");
var expiresAtStr = await userManager
.GetAuthenticationTokenAsync(user, "Spotify", "expires_at");

如果令牌存储在Cookie中,则可以使用访问各种令牌

string accessToken = await HttpContext.GetTokenAsync("access_token");
string idToken = await HttpContext.GetTokenAsync("id_token");
string refreshToken = await HttpContext.GetTokenAsync("refresh_token");
string tokenType = await HttpContext.GetTokenAsync("token_type");         
string accessTokenExpire = await HttpContext.GetTokenAsync("expires_at");    

但是,您不能将数据存储在ctx中。HttpContext,并假设它将在请求之间持久化。要么使用cookie中间件登录用户,要么将令牌存储在UserSession对象中。

请参阅本文,了解如何在会话中配置和存储数据,这些数据将跨请求持久化。

ASP.NET Core 中的会话和状态管理

如果你正确配置它,那么你可以像一样使用它

HttpContext.Session.SetString("token", token.Trim());

最新更新