首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >通过提供代理令牌来处理来自webapi的长持有者令牌

通过提供代理令牌来处理来自webapi的长持有者令牌
EN

Stack Overflow用户
提问于 2014-12-08 23:35:16
回答 1查看 6.2K关注 0票数 17

我正在使用ASP.NET WebApi 2构建web应用程序接口,使用声明身份验证,我的用户可以拥有非常多的声明。对于大量的声明,持有者令牌增长得非常快,所以我试图找到一种返回更短的持有者令牌的方法。

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

代码语言:javascript
复制
OAuthOptions = new OAuthAuthorizationServerOptions
{
    TokenEndpointPath = new PathString("/Token"),
    Provider = new ApplicationOAuthProvider(PublicClientId),
    AccessTokenExpireTimeSpan = TimeSpan.FromHours(12),
    AccessTokenProvider = new GuidProvider() // <-- here
};

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

代码语言:javascript
复制
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);
        }
    }
}

所以我的问题是:

  • 这是一个合适的(并且安全的!)如何提供一个代理键来代替我的长声明生成的令牌?
  • 在webapi/OAuth堆栈中有没有更好/更容易的地方来做这件事?

另一件要注意的事情是,我打算支持刷新令牌,事实上,上面的示例是从使用这种刷新令牌机制的示例中提取出来的-除非使用刷新令牌,否则它们看起来是一次性使用的,所以ReceiveAsync方法通常会删除从ConcurrentDictionary提供的刷新令牌,我不完全确定我理解为什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-15 20:33:03

我不建议这样做,因为您最终会将身份验证票证存储到数据库或Redis服务器中,这里的回调是,对于每个包含一个持有者令牌的请求,您将检查这个永久存储区,以便解析Guid并再次获取票证来构造它。

我建议您使用JSON Web Token JWT而不是默认的持有者访问令牌格式,为此您需要在OAuthAuthorizationServerOptions的属性Provider中实现您的自定义访问令牌格式CustomOAuthProvider,如下所示:

代码语言:javascript
复制
 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令牌添加更多声明不会像默认访问令牌格式那样显著增加其大小。

下面是两个JWTs的样本,每个JWTs的内部都有不同的声明,第二个比第一个大50个字符。我建议您使用jwt.io First JWT检查每个文件的编码内容:

代码语言:javascript
复制
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InRhaXNlZXIiLCJzdWIiOiJ0YWlzZWVyIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQxODY0NzMyNywibmJmIjoxNDE4NjQ1NTI3fQ.vH9XPtjtAv2-6SwlyX4fKNJfm5ZTVHd_9a3bRgkA_LI

第二个JWT (更多声明):

代码语言:javascript
复制
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InRhaXNlZXIiLCJzdWIiOiJ0YWlzZWVyIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciIsIlN1cGVydmlzb3IxIiwiU3VwZXJ2aXNvcjIiLCJTdXBlcnZpc29yMyJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQxODY0NzQ1NiwibmJmIjoxNDE4NjQ1NjU2fQ.TFEGDtz1RN8VmCQu7JH4Iug0B8UlWDLVrIlvc-7IK3E

JWT格式正在成为发布OAuth 2.0持有者令牌的标准方式,它也将与刷新令牌授权一起工作。

我已经在bitoftech.net上编写了关于如何在ASP.NET Web API中使用JWT令牌的detailed blog post,以及一个实时演示API和source code on GIthub,请随时查看它,如果您需要更多帮助,请告诉我。

祝好运!

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27361358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档