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

时间:2015-02-25 13:38:20

标签: asp.net owin asp.net-identity-2 claims

我正在使用ASP.NET Identity和几个外部登录提供程序,我需要处理以下场景:

1)用户使用外部服务登录(假设它是Facebook), 应用程序从Facebook获取一些信息(姓名,电子邮件,出生日期等...)包含此信息的声明将添加到身份中。

2)我需要将此信息存储在应用程序Db中,以用于以下场景:

  • 管理员浏览注册用户列表

  • 电子邮件订阅服务将使用名字和姓氏

  • ...

问题是用户是否会更新他/她的Facebook个人资料(例如,更改电子邮件地址) - 在这种情况下我需要更新我的Db中的信息(我在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);

AuthController

外部登录回调:

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用户回来后,​​我仍然坚持更新传入的声明值。处理这种情况的真正方法是什么? THX。

1 个答案:

答案 0 :(得分:0)

这有点贵,但是最简单的答案:

只要用户登录,就可以检查相同的信息,并在更改后对其进行更新。由于您没有与Facebook的直接联系,因此您永远无法知道用户何时更改其信息。

除非您在一分钟内有成千上万的系统登录信息,否则这应该是一个好的方法。