WebAPI获取没有用户名和密码的访问令牌

时间:2017-07-17 11:24:09

标签: asp.net-web-api

我试图在不使用用户名/密码组合的情况下在web api中登录用户。我可以访问用户的User对象,但需要"将它们记录在"并将访问令牌返回给客户端应用程序,以便后续请求。

我尝试了以下的变体,但没有运气,UserManager对象在我第一次调用GenerateUserIdentityAsync后立即处理,导致cookiesIdentity失败并且它警告我,我的演员OAuthGrantResourceOwnerContextCredentials是"可疑类型转换或检查"但是代码永远不会到达那条线;这就是我尝试过的,它是从GrantResourceOwnerCredentials类的ApplicationOAuthProvider方法中获取和修改的。顺便提一下,我的令牌终点与通常的usernamepasswordgrant_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);

本质上,我想要做的就是为用户返回一个访问令牌,我没有用户名和密码,但有一个"秘密"我想使用而不是用户名密码。有办法吗?

1 个答案:

答案 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;