我试图在不使用用户名/密码组合的情况下在web api中登录用户。我可以访问用户的User对象,但需要"将它们记录在"并将访问令牌返回给客户端应用程序,以便后续请求。
我尝试了以下的变体,但没有运气,UserManager
对象在我第一次调用GenerateUserIdentityAsync
后立即处理,导致cookiesIdentity
失败并且它警告我,我的演员OAuthGrantResourceOwnerContextCredentials
是"可疑类型转换或检查"但是代码永远不会到达那条线;这就是我尝试过的,它是从GrantResourceOwnerCredentials
类的ApplicationOAuthProvider
方法中获取和修改的。顺便提一下,我的令牌终点与通常的username
,password
和grant_type
请求完美配合。
var user = // Super secret way of getting the user....;
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
// UserManager is not null at this point
var oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
OAuthDefaults.AuthenticationType);
// UserManager is null at this point and so throws exception
var cookiesIdentity = await user.GenerateUserIdentityAsync(UserManager,
CookieAuthenticationDefaults.AuthenticationType);
var properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
var ticket = new AuthenticationTicket(oAuthIdentity, properties);
((OAuthGrantResourceOwnerCredentialsContext)HttpContext.Current.GetOwinContext().Request.Context)
.Validated(ticket);
HttpContext.Current.GetOwinContext().Request.Context.Authentication.SignIn(cookiesIdentity);
本质上,我想要做的就是为用户返回一个访问令牌,我没有用户名和密码,但有一个"秘密"我想使用而不是用户名密码。有办法吗?
答案 0 :(得分:4)
好的,经过多次挖掘,我发现this article帮助我整理了这个代码,它就像一个魅力:
var user = // Super secret method of getting the user
var tokenExpiration = TimeSpan.FromDays(1);
ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, user.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.OAuthOptions.AccessTokenFormat.Protect(ticket);
JObject tokenResponse = new JObject(
new JProperty("userName", user.UserName),
new JProperty("access_token", accessToken),
new JProperty("token_type", "bearer"),
new JProperty("expires_in", tokenExpiration.TotalSeconds.ToString()),
new JProperty(".issued",
ticket.Properties.IssuedUtc.GetValueOrDefault().DateTime.ToUniversalTime()),
new JProperty(".expires",
ticket.Properties.ExpiresUtc.GetValueOrDefault().DateTime.ToUniversalTime()));
return tokenResponse;