我在MVC5中使用Aspnet Identity。 Facebook是外部登录。我需要存储Facebook访问令牌供以后使用。我已经阅读了几个关于它的主题,但我仍然有一些问题: 我通过这种方式设置:
为Facebook配置身份验证时,我添加了对Facebook访问令牌的声明:
OnAuthenticated = async context =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
...
}
外部登录完成后,会带有Facebook令牌:
public async Task ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
//The loginInfo object contains the claim i needed (the facebook token)
var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
switch (result)
{
case SignInStatus.Success:
//find user and save the claim to database.
var u = UserManager.Find(loginInfo.Login);
await SaveAccessToken(u, loginInfo.ExternalIdentity);
return RedirectToLocal(returnUrl);
break;
.......
}
}
SaveAccessToken方法只是调用UserManager.AddClaimAsync将包含Facebook访问令牌的声明保存到数据库:
private async Task SaveAccessToken(ApplicationUser user, ClaimsIdentity identity)
{
var userclaims = await UserManager.GetClaimsAsync(user.Id);
foreach (var at in (from claims in identity.Claims
where claims.Type.Equals("FacebookAccessToken")
select new Claim(claims.Type, claims.Value, claims.ValueType, claims.Issuer)).Where(at => !userclaims.Contains((Claim) at)))
{
await UserManager.AddClaimAsync(user.Id, at);
}
}
令牌已成功保存到数据库的AspnetUserClaims表中。但是,登录完成后,站点重定向到其他操作,User对象具有“ApplicationCookie”类型的标识,并且没有任何名为“FacebookAccessToken”的声明。有几个主题说我必须通过覆盖UserManager类的CreateIdentityAsync方法创建标识对象时添加自定义声明。那样:
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public async override Task<ClaimsIdentity> CreateIdentityAsync(ApplicationUser applicationUser, string authenticationType)
{
var identity = await base.CreateIdentityAsync(applicationUser, authenticationType);
identity.AddClaim(new Claim("mycustomclaim", applicationUser.Avatar));
return identity;
}
}
但是,正如我注意到的那样,在执行ExternalSignInAsync时会创建标识。所以在方法CreateIdentityAsync中,我如何获得从ExternalSignInAsync传递的loginInfo对象的声明值。如果我不能,有什么办法,我可以在ExternalSignInAsync成功后添加自定义声明到当前身份吗?
答案 0 :(得分:1)
我已阅读this answer,我可以在登录成功后立即添加声明:
SignInManager.AuthenticationManager.AuthenticationResponseGrant.Identity.AddClaim(new Claim("FacebookAccessToken", loginInfo.ExternalIdentity.Claims.First(c => c.Type.Equals("FacebookAccessToken")).Value));
但不确定此代码在某些情况下是否存在问题。