在完成所有登录过程后如何获得ExternalIdentity?

时间:2014-09-15 20:22:23

标签: c# asp.net-mvc

我正在使用MVC 5,我可以使用Google成功登录。

我希望在登录过程后能够访问用户外部身份声明。我想要访问,例如,索赔"图片"来自用户。但是,如果我尝试运行此代码,它始终返回null。 (登录过程除外 - 为mvc模板自动生成代码)

external info is null

我有办法访问外部身份声明吗? (登录后)

2 个答案:

答案 0 :(得分:6)

我发现了如何创建身份。基本上,ExternalSignInAsyncSignInAsync拨打内部电话,拨打CreateUserIdentityAsync

我在ApplicationSignInManager文件中找到了一个班级IdentityConfig,然后我将CreateUserIdentityAsync方法更改为:

public override async Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
{
    var externalIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);

    var localIdentity = await user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);

    foreach (var item in externalIdentity.Claims)
    {
        if (!localIdentity.HasClaim(o => o.Type == item.Type))
            localIdentity.AddClaim(item);
    }

    return localIdentity;
}

因此,每次登录时,我都会在登录用户中声明我的声明+外部声明。从我可以打电话来看:

@HttpContext.Current.GetOwinContext()
    .Authentication.User.FindFirst("urn:google:picture").Value

答案 1 :(得分:2)

您需要存储身份验证令牌,然后使用该令牌查询登录提供商的API以获取所需信息。存储它很容易:

<强> Startup.Auth.cs

const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string";

...

var googlePlusOptions = new GoogleOAuth2AuthenticationOptions
{
    ClientId = "yourclientid",
    ClientSecret = "yourclientsecret",
    Provider = new GoogleOAuth2AuthenticationProvider
    {
        OnAuthenticated = (context) =>
        {
            context.Identity.AddClaim(new System.Security.Claims.Claim("urn:googleplus:access_token", context.AccessToken, XmlSchemaString, "Google"));
            return Task.FromResult(0);
        }
    }
};
app.UseGoogleAuthentication(googlePlusOptions);

然后,在ExternalLoginCallbackExternalLoginConfirm

中创建新用户之后
await SaveAccessToken(user, identity);

使用SaveAccessToken的以下定义(只需将其与控制器中的其他辅助方法一起使用):

private async Task SaveAccessToken(User user, ClaimsIdentity identity)
{
    var userclaims = await UserManager.GetClaimsAsync(user.Id);

    foreach (var at in (
        from claims in identity.Claims
        where claims.Type.EndsWith("access_token")
        select new Claim(claims.Type, claims.Value, claims.ValueType, claims.Issuer)))
    {
        if (!userclaims.Contains(at))
        {
            await UserManager.AddClaimAsync(user.Id, at);
        }
    }
}

现在,您可以随时使用访问令牌,以便在需要时使用。因此,对于Google,要获取个人资料照片,您只需向https://www.googleapis.com/oauth2/v3/userinfo?access_token=[token]发送请求,其中[token]是您保存的声明的价值。