以编程方式生成OAuth2令牌,在我的情况下不需要lgoin

时间:2015-11-01 22:03:35

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

我在asp.net WEB API中使用OAuth2。

在我的情况下,用户将仅使用他们的电话号码登录,他们将收到带有验证码的短信。

用户使用此方法使用验证码确认其电话号码:

    [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 .
    }

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

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

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

public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

如果要创建OAuth2令牌,可以使用此静态引用生成令牌:

Startup.OAuthOptions.AccessTokenFormat.Protect(authenticationTicket);

答案 1 :(得分:0)

我想分享我的工作,我从不同的其他帖子收集答案;你可以在这个答案的最后找到链接。

如果有人有评论或想法,请与我们分享。

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

作为Peter Hedberg答案;我们需要在启动类中将OAuthOptions Puplic和static设为:

 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属性之后调用它为null。   将其与本地登录流程进行比较,即DeserializeTicket方法   将context.Ticket属性设置为AuthenticationTicket。所以   现在神秘的是DeserializeTicket在不同方面的表现   这两个流程。将创建数据库中受保护的故障单字符串   在同一个CreateAsync方法中,区别仅在于我调用它   方法在GenerateLocalAccessTokenResponse中手动,与Owin相对   middlware正常调用它...而且SerializeTicket或者   DeserializeTicket抛出错误......

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

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