从外部身份验证提供程序获取MVC5框架OAuth / OWin身份提供程序的ExtraData

时间:2013-07-30 02:57:00

标签: asp.net-mvc asp.net-mvc-5 owin visual-studio-2013 asp.net-identity

我正在尝试在VS 2013预览中使用新的MVC5框架。

会员身份验证框架已经过彻底检查,并替换为OWin

特别是,我打开了外部身份验证提供程序Google auth。

这很简单。

只需在新默认MVC项目的App_Start目录中的Startup.Auth.cs文件中取消注释这一行:app.UseGoogleAuthentication();

因此,我希望访问来自身份验证提供程序的“额外数据”,例如用户头像的URL以显示在我的应用程序中。

根据针对asp.net成员资格提供程序的旧OAuth实现,有一种方法可以使用此处的ExtraData字典来捕获它:ProviderDetail.ExtraData Property

我找不到关于OAuth和OWin如何协同工作以及如何访问这些额外数据的文档。

任何人都可以启发我吗?

7 个答案:

答案 0 :(得分:17)

最近我必须访问Google个人资料的图片,以下是我如何解决这个问题...

如果您只是在Startup.Auth.cs文件中启用代码app.UseGoogleAuthentication();,那么这还不够,因为在这种情况下Google不会返回有关个人资料图片的任何信息。所有(或者我没有弄清楚如何得到它)。

您真正需要的是使用OAuth2集成而不是默认启用的Open ID。以下是我的表现......

首先,您必须在Google端注册您的应用并获得"客户ID"和"客户秘密"。一旦完成,你可以走得更远(稍后你会需要它)。详细信息如何执行此操作here

app.UseGoogleAuthentication();替换为

    var googleOAuth2AuthenticationOptions = new GoogleOAuth2AuthenticationOptions
    {
        ClientId = "<<CLIENT ID FROM GOOGLE>>",
        ClientSecret = "<<CLIENT SECRET FROM GOOGLE>>",
        CallbackPath = new PathString("/Account/ExternalGoogleLoginCallback"),
        Provider = new GoogleOAuth2AuthenticationProvider() {
            OnAuthenticated = async context =>
            {
                context.Identity.AddClaim(new Claim("picture", context.User.GetValue("picture").ToString()));
                context.Identity.AddClaim(new Claim("profile", context.User.GetValue("profile").ToString()));
            }
        }
    };

    googleOAuth2AuthenticationOptions.Scope.Add("email");

    app.UseGoogleAuthentication(googleOAuth2AuthenticationOptions);

之后,您可以使用该代码以与任何其他属性相同的方式访问个人资料的图片网址

var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
var pictureClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type.Equals("picture"));
var pictureUrl = pictureClaim.Value;

答案 1 :(得分:7)

使用RTW version的asp.net标识,ExternalLoginCallback中的以下代码可以帮我完成。

var externalIdentity = await HttpContext.GetOwinContext().Authentication
    .GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
var displayName = externalIdentity.Name;
var email = externalIdentity.FindFirstValue(ClaimTypes.Email);

答案 2 :(得分:5)

使用Alex Wheat的答案,我想出了一个使用Google身份验证来检索google +个人资料,性别和电子邮件的解决方案。

Startup.Auth.cs:

var googleOptions = new GoogleOAuth2AuthenticationOptions()
{
    ClientId = "<<client id - google>>",
    ClientSecret = "<<secret for your app>>",
    Provider = new GoogleOAuth2AuthenticationProvider()
    {
        OnAuthenticated = context =>
        {
            var userDetail = context.User;
            context.Identity.AddClaim(new Claim(ClaimTypes.Name,context.Identity.FindFirstValue(ClaimTypes.Name)));
            context.Identity.AddClaim(new Claim(ClaimTypes.Email,context.Identity.FindFirstValue(ClaimTypes.Email)));

            var gender = userDetail.Value<string>("gender");
            context.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender));

            var picture = userDetail.Value<string>("picture");
            context.Identity.AddClaim(new Claim("picture", picture));

            return Task.FromResult(0);
        },
    },
};
googleOptions.Scope.Add("https://www.googleapis.com/auth/plus.login");
googleOptions.Scope.Add("https://www.googleapis.com/auth/userinfo.email");

app.UseGoogleAuthentication(googleOptions);

要访问扩展配置文件数据,您应该向请求添加两个范围 - plus.login和userinfo.email。如果您只添加plus.login范围,则无法查看用户的电子邮件。如果您使用ASP.NET MVC5的默认模板进行身份验证,它将仅显示用户的电子邮件,姓名,姓氏和Google +个人资料地址。使用此处显示的方式,您还可以访问用户的图片链接。

context.User属性包含通过网络发送的用户数据的JSON序列化,并提供有用的方法让用户通过其键找到属性。

要了解有关登录范围概念的更多信息,请查看: https://developers.google.com/+/api/oauth#login-scopes

答案 3 :(得分:4)

答案 4 :(得分:4)

以下适合我的Facebook:

StartupAuth.cs:

var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
{
    AppId = "x",
    AppSecret = "y"
};
facebookAuthenticationOptions.Scope.Add("email");
app.UseFacebookAuthentication(facebookAuthenticationOptions);

ExternalLoginCallback方法:

var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
var emailClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email);
var email = emailClaim.Value;

对谷歌来说:

StartupAuth.cs

app.UseGoogleAuthentication();

ExternalLoginCallback方法(与facebook相同):

var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
var emailClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email);
var email = emailClaim.Value;

如果我在这里设置断点:

var email = emailClaim.Value;

我在调试器中看到了facebook和Google的电子邮件地址。

更新:请参阅此帖子,以获得正确完整的解决方案; Getting the email from external providers Google and Facebook during account association step in a default MVC5 app

答案 5 :(得分:3)

所以不幸的是,这不是一件非常简单的事情,您可以这样做的一种方法是挂钩GoogleProvider Authenticated事件并使用头像向声明身份添加自定义声明:

public class MyGoogleProvider : GoogleAuthenticationProvider {
    public override Task Authenticated(GoogleAuthenticatedContext context) {
        context.Identity.AddClaim(new Claim("avatarClaim", "<fetch avatar url here>"));
        return base.Authenticated(context);
    }
}

app.UseGoogleAuthentication(new GoogleAuthenticationOptions() { Provider = new MyGoogleProvider() });

然后在您的AccountController内部,当提取外部身份时,您可以获取此头像声明并将其存储到您的用户对象中以供日后使用。

答案 6 :(得分:0)

Here是AndrewPolland的一个很好的答案。为我工作。他使用新的oauth访问令牌在登录后检索用户信息。 From here Deepak Goswami解释了如何使用此api电话。