【问题标题】:Generate OAuth2 token programiticly , No lgoin needed in my case以编程方式生成 OAuth2 令牌,在我的情况下不需要 lgoin
【发布时间】:2016-02-01 18:04:52
【问题描述】:

我将 OAuth2 与 asp.net WEB API 一起使用。

在我的例子中,用户将只使用他们的电话号码登录,他们将收到带有验证码的短信。

用户通过这种方式使用验证码确认手机号码:

    [AllowAnonymous]
    [Route("ConfrimPhoneNumber")]
    [HttpPost]
    public async Task<IHttpActionResult> VerifyPhoneNumber(VerfyPhoneModel Model)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        // Verify phone number.
        //..
        //..

        //Get Application User

        //  I need to genereate and return token from here .
    }

我想要的是为这个用户生成访问令牌和刷新令牌。

提前感谢您的帮助。

【问题讨论】:

    标签: c# asp.net-web-api oauth oauth-2.0 asp.net-web-api2


    【解决方案1】:

    我假设您使用 Visual Studio 中的默认 SPA 模板。在 Startup.Auth.cs 你有一个静态属性:

    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
    

    如果你想创建一个 OAuth2 令牌,你可以使用这个静态引用来生成令牌:

    Startup.OAuthOptions.AccessTokenFormat.Protect(authenticationTicket);
    

    【讨论】:

      【解决方案2】:

      我想分享完成这项工作的必要条件,我从其他不同的帖子中收集了答案;您可以在此答案的末尾找到链接。

      如果有人有任何意见或想法,请与我们分享。

      用户注册为响应后,使用刷新令牌生成本地访问令牌。

      作为Peter Hedberg 回答;我们需要在启动类中将 OAuthOptions 设为公开和静态:

       public static OAuthAuthorizationServerOptions OAuthServerOptions { get; private set; }
      

      然后我创建了帮助类来生成本地访问令牌并刷新

          public async Task<JObject> GenerateLocalAccessToken(ApplicationUser user)
                  {
                      ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
                              OAuthDefaults.AuthenticationType);
      
      
                      AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
      
                      //Create the ticket then the access token
                      var ticket = new AuthenticationTicket(oAuthIdentity, properties);
      
                      ticket.Properties.IssuedUtc = DateTime.UtcNow;
                      ticket.Properties.ExpiresUtc = DateTime.UtcNow.Add(Startup.OAuthServerOptions.AccessTokenExpireTimeSpan);
      
                      var accessToken = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket);
      
      
                      //Create refresh token
                      Microsoft.Owin.Security.Infrastructure.AuthenticationTokenCreateContext context =
                          new Microsoft.Owin.Security.Infrastructure.AuthenticationTokenCreateContext(
                              Request.GetOwinContext(),
                              Startup.OAuthOptions.AccessTokenFormat, ticket);
      
                      await Startup.OAuthOptions.RefreshTokenProvider.CreateAsync(context);
                      properties.Dictionary.Add("refresh_token", context.Token);
      
      
      
                      //create the Token Response
                      JObject tokenResponse = new JObject(
                                                  new JProperty("access_token", accessToken),
                                                  new JProperty("token_type", "bearer"),
                                                  new JProperty("expires_in", Startup.OAuthServerOptions.AccessTokenExpireTimeSpan.TotalSeconds.ToString()),
                                                  new JProperty("refresh_token", context.Token),
                                                  new JProperty("userName", user.UserName),
                                                  new JProperty(".issued", ticket.Properties.IssuedUtc.ToString()),
                                                  new JProperty(".expires", ticket.Properties.ExpiresUtc.ToString())
                  );
                      return tokenResponse;
      
                  }
      

      在 SimpleRefreshTokenProvider CreateAsync 方法中使用基本 context.SerializeTicket 存在问题。来自Bit Of Technology的消息

      好像在ReceiveAsync方法中,context.DeserializeTicket不是 在外部登录案例中完全返回身份验证票。 当我在调用之后查看 context.Ticket 属性时,它是空的。 与本地登录流程相比,DeserializeTicket 方法 将 context.Ticket 属性设置为 AuthenticationTicket。所以 现在的谜团是 DeserializeTicket 的行为如何不同 两个流动。创建数据库中受保护的票证字符串 在同一个 CreateAsync 方法中,不同之处仅在于我称之为 在 GenerateLocalAccessTokenResponse 中手动方法,与 Owin middlware 正常调用它...... SerializeTicket 或 DeserializeTicket 抛出错误……

      因此,您需要使用 Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer 对票证进行序列化和反序列化。它看起来像这样:

      Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer serializer
                      = new Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer();
      
      token.ProtectedTicket = System.Text.Encoding.Default.GetString(serializer.Serialize(context.Ticket));
      

      代替:

      token.ProtectedTicket = context.SerializeTicket();
      

      对于 ReceiveAsync 方法:

      Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer serializer = new Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer();
      context.SetTicket(serializer.Deserialize(System.Text.Encoding.Default.GetBytes(refreshToken.ProtectedTicket)));
      

      代替:

      context.DeserializeTicket(refreshToken.ProtectedTicket);
      

      请参考这个Qestion和这个Answer 谢谢lincxGiraffe

      【讨论】:

        猜你喜欢
        • 2014-05-19
        • 2015-06-10
        • 1970-01-01
        • 1970-01-01
        • 2020-04-06
        • 2015-06-25
        • 2018-09-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多