gpt4 book ai didi

asp.net - 如何访问 Microsoft.Owin.Security.xyz OnAuthenticated 上下文 AddClaims 值?

转载 作者:行者123 更新时间:2023-11-30 05:16:00 26 4
gpt4 key购买 nike

我正在尝试检索作为 OnAuthenticated 上下文返回并添加为以下示例声明的用户属性:How to access Facebook private information by using ASP.NET Identity (OWIN)?

我可以看到我期望的数据在登录时返回,并作为 Claim 添加到 Starup.Auth.cs 中。但是,当我在帐户 Controller 中时,出现在 UserManager 或 UserStore 中的唯一声明是由 LOCAL AUTHORITY 发布的。找不到针对 Facebook(或其他外部提供商)的声明。添加到上下文的声明在哪里结束? (我使用的是 VS2013 RTM。)

此处链接了 Azure 上的完整源代码和实时站点:https://github.com/johndpalm/IdentityUserPropertiesSample/tree/VS2013rtm

这是我在 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);

捕获外部登录属性的另一种方法是为访问 token 添加一个声明并使用属性填充它:

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);
}
}
};

注意 - 此示例不起作用:尽管传递带有属性的单个声明会很好。外部 cookie 似乎注意到了 claims 属性。稍后从身份中检索属性时,这些属性为空。

最佳答案

我能够使用 MVC 5 RTM 模板、OWIN 和 ASP.NET 身份位创建一个工作示例。您可以在此处找到完整的源代码和指向实时工作示例的链接:https://github.com/johndpalm/IdentityUserPropertiesSample

这是对我有用的:

在 Startup.ConfigureAuth (StartupAuth.cs) 中创建一个新的(在此处插入提供商名称)AuthenticationOptions 对象,将客户端 ID、客户端密码和一个新的 AuthenticationProvider 传递给它。您将使用 lambda 表达式向 OnAuthenticated 方法传递一些代码,以将声明添加到包含您从 context.Identity 中提取的值的身份。

启动.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 身份验证提供程序使用此处使用的代码。如果您将相同的代码与 Microsoft 帐户提供程序(或我使用 MS 帐户代码作为模型创建的 Foursquare provider)一起使用,则无法登录。如果您只选择 access_token 参数,它工作正常。似乎某些参数破坏了登录过程。 ( An issue has been opened on katanaproject.codeplex.com if progress on this is of interest to you. ) 如果找到原因,我会更新。除了验证我可以获得 access_token 之外,我没有对 Twitter 或 Google 做太多事情。

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”开头的声明,因为它似乎会破坏登录。

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);
}
}
}

最后,我想显示任何不是来自 LOCAL AUTHORITY 的值。我创建了一个局部 View _ExternalUserPropertiesListPartial出现在 /Account/Manage page 上.我从 AuthenticationManager.User.Claims 中获取之前存储的声明,然后将其传递给 View 。

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

@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>
}

同样,工作示例和完整代码在 GitHub 上:https://github.com/johndpalm/IdentityUserPropertiesSample

如有任何反馈、更正或改进,我们将不胜感激。

关于asp.net - 如何访问 Microsoft.Owin.Security.xyz OnAuthenticated 上下文 AddClaims 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19456008/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com