我在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 .
}
我想要的是为该用户生成访问令牌和刷新令牌。
提前感谢您的帮助。
答案 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);