在我的当前应用程序中,我使用Owin + Aspnet身份以及Microsoft提供程序来处理身份验证。
到目前为止,除了我试图检索远程令牌以将其存储在我的数据库之外,一切都很好。
我在网上找到了一些文档,上面写着在saveBootstrapContext中启用“web.config”,所以我做到了:
<system.identityModel>
<identityConfiguration saveBootstrapContext="true">
<securityTokenHandlers>
<securityTokenHandlerConfiguration saveBootstrapContext="true"></securityTokenHandlerConfiguration>
</securityTokenHandlers>
</identityConfiguration>
</system.identityModel>我只在identityConfiguration上尝试,然后只在securityTokenHandlerConfiguration上尝试,然后两者在一起,但是结果总是一样的。在下面的代码中,externalData.ExternalIdentity.BootstrapContext始终为空。
SignIn方法在中间件调用的"ExternalLoginCallback“方法中被调用。
using System.IdentityModel.Tokens;
using System.Security.Claims;
using System.Web;
// custom namespaces redacted
using Microsoft.AspNet.Identity;
using Microsoft.Owin.Security;
public class AuthManager : IAuthManager
{
private readonly IUserBusinessLogic userBusinessLogic;
public AuthManager(IUserBusinessLogic userBusinessLogic)
{
this.userBusinessLogic = userBusinessLogic;
}
public void SignIn()
{
IAuthenticationManager manager = HttpContext.Current.GetOwinContext().Authentication;
var externalData = manager.GetExternalLoginInfo();
UserDto user = this.userBusinessLogic.GetUser(externalData.Login.LoginProvider, externalData.Login.ProviderKey);
var token = ((BootstrapContext)externalData.ExternalIdentity.BootstrapContext).Token;
if (user == null)
{
user = this.userBusinessLogic.AddUser(new UserDto(), externalData.Login.LoginProvider, externalData.Login.ProviderKey, token);
}
user.Token = token;
var claims = new Claim[]
{
new Claim(ClaimTypes.NameIdentifier, user.ID.ToString()),
new Claim(ClaimTypes.UserData, UserData.FromUserDto(user).ToString())
};
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
var properties = new AuthenticationProperties
{
AllowRefresh = true,
IsPersistent = true
};
manager.SignIn(properties, identity);
}这里的其他一些帖子是这样说的:尝试重新启动IIS、重新启动机器、清空浏览器cookie和重新启动浏览器。我都试过了,但还是一无所获。如果我模拟令牌字符串,其他一切都能正常工作。
现在我显然遗漏了一些东西,但是我在网上找不到任何清晰的文档。
任何帮助都是非常感谢的。
谢谢。
发布于 2015-06-25 16:29:13
有时没有任何帮助是最好的帮助,因为我被迫越挖越深,最终找到解决方案。
正当的前提是,我当时完全混乱,我混合了三种不同的技术,而没有理解所有的含义。
我的例子在web.config中使用了WIF配置,但是代码端使用的是OWIN顶部的Aspnet (根本不使用web.config )。
一旦我理清了自己的想法,我就意识到以下几点:
DefaultAuthenticationTypes静态类,它提供了一些字符串常量。为了简单起见,我保留了它,但我也可以删除它。因此,我的重构代码(和工作代码)如下所示。首先,要使MS auth与令牌一起工作,在Startup.cs中使用中间件配置。
app.UseMicrosoftAccountAuthentication(new MicrosoftAccountAuthenticationOptions
{
ClientId = "myClientId",
ClientSecret = "myClientSecret",
Provider = new MicrosoftAccountAuthenticationProvider
{
OnAuthenticated = context =>
{
// here's the token
context.Identity.AddClaim(new System.Security.Claims.Claim("AccessToken", context.AccessToken));
context.Identity.AddClaim(new System.Security.Claims.Claim("FirstName", context.FirstName));
context.Identity.AddClaim(new System.Security.Claims.Claim("LastName", context.LastName));
return Task.FromResult(true);
}
}
});然后,重新检查SignIn方法:
public void SignIn()
{
IAuthenticationManager manager = HttpContext.Current.GetOwinContext().Authentication;
var externalData = manager.GetExternalLoginInfo();
UserDto user = this.userBusinessLogic.GetUser(externalData.Login.LoginProvider, externalData.Login.ProviderKey);
if (user == null)
{
user = this.userBusinessLogic.AddUser(
new UserDto
{
FirstName = externalData.ExternalIdentity.Claims.Single(c => c.Type == "FirstName").Value,
LastName = externalData.ExternalIdentity.Claims.Single(c => c.Type == "LastName").Value
},
externalData.Login.LoginProvider,
externalData.Login.ProviderKey,
// here's the token claim that I set in the middleware configuration
externalData.ExternalIdentity.Claims.Single(c => c.Type == "AccessToken").Value);
}
var claims = new Claim[]
{
new Claim(ClaimTypes.NameIdentifier, user.ID.ToString()),
new Claim(ClaimTypes.UserData, UserData.FromUserDto(user).ToString()),
new Claim("AccessToken", user.Token),
new Claim("FirstName", user.FirstName),
new Claim("LastName", user.LastName)
};
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
var properties = new AuthenticationProperties
{
AllowRefresh = true,
IsPersistent = true
};
manager.SignIn(properties, identity);
}也许这对我来说是很困难的,但是无论如何,我在这里发布我的解决方案,希望它能避免一些头痛和一些天的咒骂一些同事开发人员。
快乐编码^^
https://stackoverflow.com/questions/30939552
复制相似问题