gpt4 book ai didi

c# - 通过提供代理 token 处理来自 webapi 的长承载 token

转载 作者:可可西里 更新时间:2023-11-01 03:02:01 24 4
gpt4 key购买 nike

我正在使用声明身份验证使用 ASP.NET WebApi 2 构建 Web API,我的用户可以拥有大量声明。由于存在大量声明,不记名 token 会迅速增长,因此我试图找到一种方法来返回更短的不记名 token 。

到目前为止,我发现我可以提供 IAuthenticationTokenProvider到 OAuth 选项 OAuthAuthorizationServerOptions.AccessTokenProvider属性:

OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AccessTokenExpireTimeSpan = TimeSpan.FromHours(12),
AccessTokenProvider = new GuidProvider() // <-- here
};

这让我有机会拦截 AuthenticationTicket并把它藏起来,用更简单的东西代替它——在我下面的例子中是一个散列的 guid。 (注意:目前这个类只包含一个 ConcurrentDictionary<string,AuthenticationTicket> 和我的 session - 在一个真实世界的例子中,我打算将 session 存储在一些持久存储中)

public class GuidProvider : IAuthenticationTokenProvider
{
private static ConcurrentDictionary<string, AuthenticationTicket> tokens
= new ConcurrentDictionary<string, AuthenticationTicket>();

public void Create(AuthenticationTokenCreateContext context)
{
throw new NotImplementedException();
}

public async System.Threading.Tasks.Task CreateAsync(AuthenticationTokenCreateContext context)
{
var guid = Guid.NewGuid().ToString();

var ticket = Crypto.Hash(guid);

tokens.TryAdd(ticket, context.Ticket);

context.SetToken(ticket);
}

public void Receive(AuthenticationTokenReceiveContext context)
{
throw new NotImplementedException();
}

public async System.Threading.Tasks.Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
AuthenticationTicket ticket;

if (tokens.TryGetValue(context.Token, out ticket))
{
if (ticket.Properties.ExpiresUtc.Value < DateTime.UtcNow)
{
tokens.TryRemove(context.Token, out ticket);
}
context.SetTicket(ticket);
}
}
}

所以我的问题:

  • 这是提供代理 key 来代替我的长声明生成 token 的适当(且安全!)方式吗?
  • 我应该在 webapi/OAuth 堆栈中执行此操作的更好/更容易的地方吗?

另一件需要注意的事情是我打算支持刷新 token ,事实上上面的例子是从使用这种刷新 token 机制的例子中提取的——除了刷新 token 它们似乎是一次性的,所以 ReceiveAsync方法通常总是删除 ConcurrentDictionary 提供的刷新 token , 我不完全确定我理解为什么?

最佳答案

我不建议这样做,因为您最终会将身份验证票证存储到数据库或 Redis 服务器中,这里的缺点是每个包含不记名 token 的请求,您将按顺序检查此永久存储解析 Guid 并再次获取票证以构建它。

我建议您使用 JSON Web Token JWT 而不是默认的承载访问 token 格式,为此您需要实现自定义访问 token 格式 CustomOAuthProvider在属性(property)ProviderOAuthAuthorizationServerOptions如下面的代码:

 OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
//For Dev enviroment only (on production should be AllowInsecureHttp = false)
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/oauth2/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = new CustomOAuthProvider(),
AccessTokenFormat = new CustomJwtFormat("http://jwtauthzsrv.azurewebsites.net")
};

我注意到,向 JWT token 添加更多声明不会像默认访问 token 格式那样显着增加其大小。

下面是 2 个 JWT 的示例,每个 JWT 中的声明都不同,第二个仅比第一个大 50 个字符。我建议您使用 jwt.io 检查每个编码的内容第一个智威汤逊:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InRhaXNlZXIiLCJzdWIiOiJ0YWlzZWVyIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQxODY0NzMyNywibmJmIjoxNDE4NjQ1NTI3fQ.vH9XPtjtAv2-6SwlyX4fKNJfm5ZTVHd_9a3bRgkA_LI

第二个 JWT(更多声明):

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InRhaXNlZXIiLCJzdWIiOiJ0YWlzZWVyIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciIsIlN1cGVydmlzb3IxIiwiU3VwZXJ2aXNvcjIiLCJTdXBlcnZpc29yMyJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQxODY0NzQ1NiwibmJmIjoxNDE4NjQ1NjU2fQ.TFEGDtz1RN8VmCQu7JH4Iug0B8UlWDLVrIlvc-7IK3E

JWT 格式正在成为颁发 OAuth 2.0 不记名 token 的标准方式,它也将与刷新 token 授权一起使用。但请记住,JWT 只是签名 token ,并没有像默认访问 token 格式那样加密,因此不要将 secret 数据存储在其中。

我写了detailed blog post在 bitoftech.net 上关于如何在 ASP.NET Web API 中使用 JWT token 以及现场演示 API 和 source code on GIthub , 请随时检查它,如果您需要更多帮助,请告诉我。

祝你好运!

关于c# - 通过提供代理 token 处理来自 webapi 的长承载 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27361358/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com