繁体   English   中英

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

[英]Get ExtraData from MVC5 framework OAuth/OWin identity provider with external auth provider

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

会员身份验证框架已经过大修,并被OWin取代。

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

这很简单。

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

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

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

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

任何人都可以开导我吗?

最近我不得不访问Google个人资料的图片,以下是我如何解决它...

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

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

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

替换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);

之后,您可以使用该代码以与任何其他属性相同的方式访问配置文件的图片URL

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

使用RTW版本的asp.net身份, ExternalLoginCallback中的以下代码为我做了这个。

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

使用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

以下适合我的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的电子邮件地址。

更新 :请参阅此文章,以获得正确和完整的解决方案; 在默认MVC5应用程序中的帐户关联步骤中从外部提供商Google和Facebook获取电子邮件

所以不幸的是,这不是非常直截了当,你可以这样做的一种方法是挂钩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内部,当提取外部身份时,您可以获取此头像声明并将其存储到您的用户对象中以供稍后使用。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM