ASP.NET Identity: Update external claims after authorization

主宰稳场 提交于 2020-01-01 02:30:06

问题


I am using ASP.NET Identity with several external login providers and I need to handle the following scenario:

1) A user logs in using an external service (let's say it is Facebook), application grabs some info from Facebook (first and last name, email, date of birth, etc...) Claims containing this info are added to the identity.

2) I need to store this info in the application Db, for the following scenarios:

  • Admin browses the list of registered users

  • Email subscription service will use first and last names

  • ...

The question is what about if user will update his/her Facebook profile (e.g., change email address) - in this case I need to update information in my Db too (I store external claims in AspNetUserClaims table). Actually I need to update it every time an external user is authenticated.

Here's the code of how it is saved for the first time:

Extended Claim class:

public class ApplicationUserClaim : IdentityUserClaim<Guid>
{
    public string Issuer { get; set; }
    public string ClaimValueType { get; set; }
}

Startup:

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

External Login callback:

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 { ... });    
}

Creating an user after external login confirmation (omitting other code):

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);
}

This works fine, but I'm stuck with updating incoming claim values after a Facebook user comes back. What is the true way to handle such a situation? Thx.


回答1:


This is a bit costy but the easiest answer:

You can just check the same information whenever the user logs in and update them if changed. Since you have no direct connection to Facebook, you can never know when the users change their information.

This should result be an OK approach unless you have thousands of logins to your system in a minute.



来源:https://stackoverflow.com/questions/28720475/asp-net-identity-update-external-claims-after-authorization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!