我正在使用ASP.NET Identity和多个外部登录提供程序,并且需要处理以下情况:
1)用户使用外部服务(比如Facebook)登录,应用程序从Facebook获取一些信息(例如姓氏、名字、电子邮件、出生日期等),将包含这些信息的Claims添加到Identify中。
2)我需要将此信息存储在应用程序数据库中,以便以下情况:
管理员浏览已注册用户列表
电子邮件订阅服务将使用名字和姓氏
- ...
问题是如果用户更新他/她的Facebook个人资料(例如更改电子邮件地址),那么怎么办?这种情况下,我也需要在我的数据库中更新信息(我在AspNetUserClaims表中存储外部声明)。实际上,每次认证外部用户时,我都需要更新它。
以下是首次保存信息的代码:
扩展声明类:
public class ApplicationUserClaim : IdentityUserClaim<Guid>
{
public string Issuer { get; set; }
public string ClaimValueType { get; set; }
}
初创企业:
var facebookOptions = new FacebookAuthenticationOptions {
AppId = "...",
AppSecret = "...",
Provider = new FacebookAuthenticationProvider {
OnAuthenticated = (context) => {
context.Identity.AddClaims(new[] {
new Claim("LastName", context.User["last_name"].ToString(), ClaimValueTypes.String, "Facebook"),
new Claim("FirstName", context.User["first_name"].ToString(), ClaimValueTypes.String, "Facebook"),
//...Other claims
});
}
}
};
facebookOptions.Scope.Add("email");
facebookOptions.Scope.Add("user_birthday");
app.UseFacebookAuthentication(facebookOptions);
认证控制器
外部登录回调:
public ActionResult ExternalLogin(string returnUrl)
{
var loginInfo = authenticationManager.GetExternalLoginInfo();
//No user found - this is the first login with an external service
//Asking to confirm an external account
if(signInStatus == SignInStatus.Failure)
return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { ... });
}
在外部登录确认后创建用户(省略其他代码):public ActionResult ExternalLoginConfirmation(ExternalLoginConfirmationViewModel loginConfirmationViewModel)
{
var loginInfo = authenticationManager.GetExternalLoginInfo();
var user = new ApplicationUser();
user.Logins.Add(new RegisteredUserLogin {
LoginProvider = loginInfo.Login.LoginProvider,
ProviderKey = loginInfo.Login.ProviderKey
});
//Converting Claims added in OnAuthenticated callback to ApplicationClaim objects to store them in Db
foreach(var userInfoClaim in loginInfo.GetUserInfoClaims())
user.Claims.Add(ClaimsHelper.ToUserClaimObject(userInfoClaim));
userManager.Create(user);
}
这个方案很好,但是当Facebook用户回来后,我卡在了更新传入认领值的操作上。处理这种情况的真正方法是什么呢? 谢谢。
谢谢。