在我们的项目中,我们有一个基于ASP.NET Identity框架的用户管理系统。 当用户通过提供电子邮件,用户名和密码进行注册时,一切正常。我们能够在继承“ApiController”的每个控制器中获取方法中的用户ID。 但是,现在我们正在尝试实施外部登录提供商,而我们正在开始使用Facebook。注册顺利进行,用户在我们的数据库中创建,只是在任何其他用户中创建,但没有原因的PasswordHash,并且访问令牌被退回到客户端以进一步授权。
所有这一切都正常工作,但是当涉及到程序员应该能够通过“User.Identity.GetUserId”接收用户ID的部分时,我们遇到了一些问题。 “User.Identity”包含正确的“userName”,但“GetUserId”始终返回“null”。
以下是我们的注册方法,以及访问令牌的生成
[OverrideAuthentication]
[AllowAnonymous]
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[Route("RegisterExternal")]
public async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var verifiedAccessToken = await VerifyExternalAccessToken(model.Provider, model.AccessToken);
if (verifiedAccessToken == null)
{
return BadRequest("Invalid Provider or External Access Token");
}
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
var info = new ExternalLoginInfo()
{
DefaultUserName = model.UserName,
Login = new UserLoginInfo(model.Provider, verifiedAccessToken.user_id)
};
var accessTokenResponse = GenerateLocalAccessTokenResponse(model.UserName, user.Id, model.Provider);
return Ok(accessTokenResponse);
}
catch (Exception e)
{
return null;
}
}
private JObject GenerateLocalAccessTokenResponse(string userName, string userid, string provider)
{
var tokenExpiration = TimeSpan.FromDays(1);
ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Sid, userid));
identity.AddClaim(new Claim(ClaimTypes.Name, 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.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);
JObject tokenResponse = new JObject(
new JProperty("userName", userName),
new JProperty("access_token", accessToken),
new JProperty("token_type", "bearer"),
new JProperty("external_provider", provider),
new JProperty("expires_in", tokenExpiration.TotalSeconds),
new JProperty(".issued", ticket.Properties.IssuedUtc.ToString()),
new JProperty(".expires", ticket.Properties.ExpiresUtc.ToString())
);
return tokenResponse;
}
总而言之,注册的每个部分都按预期工作,当它为外部提供商创建的用户使用访问令牌时,我们无法接收当前用户的用户ID。 / p>
答案 0 :(得分:0)
好吧,如果将来有人需要答案,那是因为“GetUserId”寻找名为“NameIdentifier”的声明,所以更改它,使其工作。