ASP.NET Identity:授权后更新外部声明

15

我正在使用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用户回来后,我卡在了更新传入认领值的操作上。处理这种情况的真正方法是什么呢? 谢谢。


谢谢。

你解决了这个问题吗?我也在想同样的事情... - Mladen Mihajlovic
我自己也处于同样的情况。当用户返回并使用SignInManager.ExternalLoginSignInAsync()登录时,它会使用你保存到本地帐户的声明填充身份,这是有道理的,但我不确定在后续登录中更新这些声明的正确方法是什么。 - NightWatchman
1个回答

1
这可能有点昂贵,但是最简单的答案是:
每当用户登录时,您只需检查相同的信息并在更改时更新它们。由于您与Facebook没有直接连接,因此您永远不会知道用户何时更改其信息。
除非您的系统每分钟有数千次登录,否则这应该是一个可行的方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接