如何访问Microsoft.Owin.Security.xyz OnAuthenticated背景下AddClaims值? [英] How do I access Microsoft.Owin.Security.xyz OnAuthenticated context AddClaims values?

查看:178
本文介绍了如何访问Microsoft.Owin.Security.xyz OnAuthenticated背景下AddClaims值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想检索返回的OnAuthenticated上下文,并添加如下这个例子索赔用户属性:<一个href=\"http://stackoverflow.com/questions/18942196/how-to-access-facebook-private-information-by-using-asp-net-identity-owin\">How通过访问Facebook的私人信息ASP.NET身份(OWIN)?

I'm trying to retrieve user properties that are returned as the OnAuthenticated context and added as a claims following this example: How to access Facebook private information by using ASP.NET Identity (OWIN)?

我可以看到数据,我希望在登录返回,并正在添加为内Starup.Auth.cs索赔。但是,当我账户控制器内,该的UserManager或UserStore内出现的唯一要求是由地方当局发出的。任何声称可以为Facebook(或其他外部提供商)被发现。在哪里可以加到背景下,要求结束? (我使用VS2013 RTM)。

I can see that data I am expecting is being returned at login and is being added as a Claim within Starup.Auth.cs. But, when I am within the Account Controller, the only claims that appears within the UserManager or UserStore is issued by LOCAL AUTHORITY. No claims can be found for Facebook (or other external providers). Where do the claims added to context end up? (I'm using VS2013 RTM.)

完整的源和链接在这里在Azure上线的站点:<一href=\"https://github.com/johndpalm/IdentityUserPropertiesSample/tree/VS2013rtm\">https://github.com/johndpalm/IdentityUserPropertiesSample/tree/VS2013rtm

Full source and live site on Azure linked here: https://github.com/johndpalm/IdentityUserPropertiesSample/tree/VS2013rtm

下面是我在Startup.Auth.cs:

Here is what I have in Startup.Auth.cs:

var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
{
    AppId = ConfigurationManager.AppSettings.Get("FacebookAppId"),
    AppSecret = ConfigurationManager.AppSettings.Get("FacebookAppSecret"),
    Provider = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationProvider()
    {
        OnAuthenticated = (context) =>
            {
                const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string";
                foreach (var x in context.User)
                {
                    var claimType = string.Format("urn:facebook:{0}", x.Key);
                    string claimValue = x.Value.ToString();
                    if (!context.Identity.HasClaim(claimType, claimValue))
                        context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, XmlSchemaString, "Facebook"));

                }
                context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, XmlSchemaString, "Facebook"));
                return Task.FromResult(0);
            }
    }

};

facebookOptions.Scope.Add("email");

app.UseFacebookAuthentication(facebookOptions);

捕捉外部登录属性的另一种方法是添加一个索赔的访问令牌和特性来填充它:

An alternative way to capture the external login properties would be to add a single claim for the access token and populate it with properties:

const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string";
var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions
{
    AppId = ConfigurationManager.AppSettings.Get("FacebookAppId"),
    AppSecret = ConfigurationManager.AppSettings.Get("FacebookAppSecret"),
    Provider = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationProvider()
    {
        OnAuthenticated = (context) =>
        {
            var claim = new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, XmlSchemaString, "Facebook");
            foreach (var x in context.User)
            {
                string key = string.Format("urn:facebook:{0}", x.Key);
                string value = x.Value.ToString();
                claim.Properties.Add(key, value);
            }

            context.Identity.AddClaim(claim);

            return Task.FromResult(0);
        }
    }
};

请注意 - 此示例不起作用:虽然这将是很好的传递与性能的单一索赔。外部饼干似乎注意兑现债权性质。从身份以后检索它们时的属性是空的。

NOTE - This sample does not work: Though it would be nice to pass a single claim with properties. The external cookie seems to note honor the claims properties. The properties are empty when retrieving them later from the identity.

推荐答案

我能够创建一个工作示例,使用MVC 5 RTM模板,OWIN和ASP.NET身份位。你可以找到完整的源代码,并在此现场工作示例的链接:<一个href=\"https://github.com/johndpalm/IdentityUserPropertiesSample\">https://github.com/johndpalm/IdentityUserPropertiesSample

I was able to create a working example, using MVC 5 RTM templates, OWIN, and ASP.NET Identity bits. You can find the complete source and a link to a live working example here: https://github.com/johndpalm/IdentityUserPropertiesSample

下面是我工作:

(此处插入提供商名称)创建一个新的对象AuthenticationOptions在Startup.ConfigureAuth(StartupAuth.cs),传递客户端ID,客户端密钥和一个新的AuthenticationProvider。您将使用lambda前pression传递OnAuthenticated方法有些code权利要求添加到包含你context.Identity提取值的身份。

Create a new (insert provider name here) AuthenticationOptions object in Startup.ConfigureAuth (StartupAuth.cs), passing it the client id, client secret, and a new AuthenticationProvider. You will use a lambda expression to pass the OnAuthenticated method some code to add Claims to the identity which contain the values you extract from context.Identity.

StartUp.Auth.cs

StartUp.Auth.cs

// Facebook : Create New App
// https://dev.twitter.com/apps
if (ConfigurationManager.AppSettings.Get("FacebookAppId").Length > 0)
{
    var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
    {
        AppId = ConfigurationManager.AppSettings.Get("FacebookAppId"),
        AppSecret = ConfigurationManager.AppSettings.Get("FacebookAppSecret"),
        Provider = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationProvider()
        {
            OnAuthenticated = (context) =>
                {
                    context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, XmlSchemaString, "Facebook"));
                    foreach (var x in context.User)
                    {
                        var claimType = string.Format("urn:facebook:{0}", x.Key);
                        string claimValue = x.Value.ToString();
                        if (!context.Identity.HasClaim(claimType, claimValue))
                            context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, XmlSchemaString, "Facebook"));

                    }
                    return Task.FromResult(0);
                }
        }

    };
    app.UseFacebookAuthentication(facebookOptions);
}

请注意:在Facebook的身份验证提供者可以与这里使用的code。如果使用同样的code与Microsoft帐户提供商(或四方提供商我创建使用MS帐户code作为一个模型),它无法登录。如果仅选择的access_token参数,它工作正常。好像一些参数打破了登录过程。 (的问题已经开了katanaproject。codeplex.com如果这种进步是你的兴趣。),如果我找到原因我会及时更新。我没有做太多与Twitter或谷歌超越验证我能得到的access_token。

NOTE: The Facebook auth provider works with the code used here. If you use this same code with the Microsoft Account provider (or Foursquare provider I created using the MS account code as a model), it fails to login. If you select just the access_token parameter, it works fine. Seems like some parameters break the login process. (An issue has been opened on katanaproject.codeplex.com if progress on this is of interest to you.) I'll update if I find the cause. I didn't do much with Twitter or Google beyond verifying that I could get the access_token.

var msaccountOptions = new Microsoft.Owin.Security.MicrosoftAccount.MicrosoftAccountAuthenticationOptions() 
{
    ClientId = ConfigurationManager.AppSettings.Get("MicrosoftClientId"),
    ClientSecret = ConfigurationManager.AppSettings.Get("MicrosoftClientSecret"),
    Provider = new Microsoft.Owin.Security.MicrosoftAccount.MicrosoftAccountAuthenticationProvider()
    {
        OnAuthenticated = (context) =>
            {
                context.Identity.AddClaim(new System.Security.Claims.Claim("urn:microsoftaccount:access_token", context.AccessToken, XmlSchemaString, "Microsoft"));
                return Task.FromResult(0);
            }
    }                   
};

app.UseMicrosoftAccountAuthentication(msaccountOptions);

在的AccountController,我提取使用外部的cookie从的AuthenticationManager的ClaimsIdentity。我然后将其添加到使用该应用程序的cookie创建的标识。我忽略了开头的任何索赔...... schemas.xmlsoap.org/ws/2005/05/identity/claims,因为它似乎打破登录。

In AccountController, I extract the ClaimsIdentity from the AuthenticationManager using the external cookie. I then add it to the identity created using the application cookie. I ignored any claims that starts with "...schemas.xmlsoap.org/ws/2005/05/identity/claims" since it seemed to break the login.

AccountController.cs

AccountController.cs

private async Task SignInAsync(CustomUser user, bool isPersistent)
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
    var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

// Extracted the part that has been changed in SignInAsync for clarity.
    await SetExternalProperties(identity);

    AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

private async Task SetExternalProperties(ClaimsIdentity identity)
{
    // get external claims captured in Startup.ConfigureAuth
    ClaimsIdentity ext = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);

    if (ext != null)
    {
        var ignoreClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims";
        // add external claims to identity
        foreach (var c in ext.Claims)
        {
            if (!c.Type.StartsWith(ignoreClaim))
                if (!identity.HasClaim(c.Type, c.Value))
                    identity.AddClaim(c);
        } 
    }
}

最后,我要显示什么值都没有从当地政府。我创建了一个局部视图<一个href=\"https://github.com/johndpalm/IdentityUserPropertiesSample/blob/master/MySample.MVC/Views/Account/_ExternalUserPropertiesListPartial.cshtml\">_ExternalUserPropertiesListPartial出现在 /帐号/管理页面。我得到的索赔,我从AuthenticationManager.User.Claims然后pviously存储$ P $它传递给视图。

And finally, I want to display whatever values are not from the LOCAL AUTHORITY. I created a partial view _ExternalUserPropertiesListPartial that appears on the /Account/Manage page. I get the claims I previously stored from AuthenticationManager.User.Claims and then pass it to the view.

AccountController.cs

AccountController.cs

[ChildActionOnly]
public ActionResult ExternalUserPropertiesList()
{
    var extList = GetExternalProperties();
    return (ActionResult)PartialView("_ExternalUserPropertiesListPartial", extList);
}

private List<ExtPropertyViewModel> GetExternalProperties()
{
    var claimlist = from claims in AuthenticationManager.User.Claims
                    where claims.Issuer != "LOCAL AUTHORITY"
                    select new ExtPropertyViewModel
                    {
                        Issuer = claims.Issuer,
                        Type = claims.Type,
                        Value = claims.Value
                    };

    return claimlist.ToList<ExtPropertyViewModel>();
}

和刚需彻底,认为:

_ExternalUserPropertiesListPartial.cshtml

_ExternalUserPropertiesListPartial.cshtml

@model IEnumerable<MySample.Models.ExtPropertyViewModel>

@if (Model != null)
{
    <legend>External User Properties</legend>
    <table class="table">
        <tbody>
            @foreach (var claim in Model)
            {
                <tr>
                    <td>@claim.Issuer</td>
                    <td>@claim.Type</td>
                    <td>@claim.Value</td>
                </tr>
            }
        </tbody>
    </table>
}

再次工作的例子,完整code是在GitHub上:<一href=\"https://github.com/johndpalm/IdentityUserPropertiesSample\">https://github.com/johndpalm/IdentityUserPropertiesSample

Again, the working example and complete code is on GitHub: https://github.com/johndpalm/IdentityUserPropertiesSample

和任何反馈,修正或改进将AP preciated。

And any feedback, corrections, or improvements would be appreciated.

这篇关于如何访问Microsoft.Owin.Security.xyz OnAuthenticated背景下AddClaims值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆