首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用外部登录提供程序创建刷新令牌?

如何使用外部登录提供程序创建刷新令牌?
EN

Stack Overflow用户
提问于 2014-09-09 16:15:34
回答 1查看 7.8K关注 0票数 21

我已经在网上找过了,也找不到我的问题的解决方案。我正在我的应用程序中实现OAuth。我使用的是ASPWebAPI2和.NET。场景是这样的,一旦用户向令牌端点发出请求,他或她将收到访问令牌以及刷新令牌,以生成新的访问令牌。我有一个帮助我生成刷新令牌的类。这就是它:

代码语言:javascript
复制
   public class SimpleRefreshTokenProvider : IAuthenticationTokenProvider
    {


       private static ConcurrentDictionary<string, AuthenticationTicket> _refreshTokens = new ConcurrentDictionary<string, AuthenticationTicket>();



    public async Task CreateAsync(AuthenticationTokenCreateContext context)
        {

            var refreshTokenId = Guid.NewGuid().ToString("n");
            using (AuthRepository _repo = new AuthRepository())
            {
                var refreshTokenLifeTime = context.OwinContext.Get<string>                                    ("as:clientRefreshTokenLifeTime");
                var token = new RefreshToken() 
                { 
                    Id = Helper.GetHash(refreshTokenId),
                    ClientId = clientid, 
                    Subject = context.Ticket.Identity.Name,
                    IssuedUtc = DateTime.UtcNow,
                    ExpiresUtc = DateTime.UtcNow.AddMinutes(15)
                };
                context.Ticket.Properties.IssuedUtc = token.IssuedUtc;
                context.Ticket.Properties.ExpiresUtc = token.ExpiresUtc;
                token.ProtectedTicket = context.SerializeTicket();
                var result = await _repo.AddRefreshToken(token);
                if (result)
                {        
                    context.SetToken(refreshTokenId);
                }
            }
        }

        // this method will be used to generate Access Token using the Refresh Token
        public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
        {

            string hashedTokenId = Helper.GetHash(context.Token);
            using (AuthRepository _repo = new AuthRepository())
            {
                var refreshToken = await _repo.FindRefreshToken(hashedTokenId);
                if (refreshToken != null )
                {
                    //Get protectedTicket from refreshToken class
                    context.DeserializeTicket(refreshToken.ProtectedTicket);
                    // one refresh token per user and client
                    var result = await _repo.RemoveRefreshToken(hashedTokenId);
                }
            }
        }

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

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

现在我允许我的用户通过facebook注册。一旦用户在facebook注册,我就会生成一个访问令牌并将其提供给他。我是否也应该生成刷新令牌?我想到一件事,就是生成一个很长的访问令牌,就像有一天,然后这个用户必须再次登录facebook。但如果我不想这样做,我可以给客户端一个刷新令牌,他可以使用它来刷新生成的访问令牌并获得一个新的令牌。当有人在facebook或外部注册或登录时,如何创建刷新令牌并将其附加到响应?

这是我的外部注册API

代码语言:javascript
复制
  public class AccountController : ApiController
    {
      [AllowAnonymous]
      [Route("RegisterExternal")]
      public async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model)
      {

         if (!ModelState.IsValid)
         {
            return BadRequest(ModelState);
         }
         var accessTokenResponse = GenerateLocalAccessTokenResponse(model.UserName);
         return Ok(accessTokenResponse);
      }


    }

//生成访问令牌的私有方法

代码语言:javascript
复制
private JObject GenerateLocalAccessTokenResponse(string userName)
        {

            var tokenExpiration = TimeSpan.FromDays(1);
            ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
            identity.AddClaim(new Claim(ClaimTypes.Name, userName));
            identity.AddClaim(new Claim("role", "user"));
            var props = new AuthenticationProperties()
            {
                IssuedUtc = DateTime.UtcNow,
                ExpiresUtc = DateTime.UtcNow.Add(tokenExpiration),
            };
            var ticket = new AuthenticationTicket(identity, props);
            var accessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);
            JObject tokenResponse = new JObject(
                                        new JProperty("userName", userName),
                                        new JProperty("access_token", accessToken),
                                        // Here is what I need
                                        new JProperty("resfresh_token", GetRefreshToken()),
                                        new JProperty("token_type", "bearer"),
                                        new JProperty("refresh_token",refreshToken),
                                        new JProperty("expires_in", tokenExpiration.TotalSeconds.ToString()),
                                        new JProperty(".issued", ticket.Properties.IssuedUtc.ToString()),
                                        new JProperty(".expires", ticket.Properties.ExpiresUtc.ToString())
        );
            return tokenResponse;
        }
EN

回答 1

Stack Overflow用户

发布于 2015-11-30 23:12:03

@长颈鹿和其他当然

我有几句话。不需要使用定制的tickerserializer。

下面这行代码:

代码语言:javascript
复制
Microsoft.Owin.Security.Infrastructure.AuthenticationTokenCreateContext context = 
                new Microsoft.Owin.Security.Infrastructure.AuthenticationTokenCreateContext(
                    Request.GetOwinContext(), 
                    Startup.OAuthOptions.AccessTokenFormat, ticket);

作为令牌格式:使用Startup.OAuthOptions.AccessTokenFormat。由于我们希望提供refeshtoken,因此需要将其更改为:Startup.OAuthOptions.RefreshTokenFormat

否则,如果您想要获取新的访问令牌并刷新刷新令牌( grant_type=refresh_token&refresh_token=......)反序列化程序/非保护器将失败。因为它在解密阶段使用了错误的目的关键字。

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

https://stackoverflow.com/questions/25739710

复制
相关文章

相似问题

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