道歉并提前感谢您提出这个问题!我还是SO的新手.
我一直在使用MVC5,EF6和VS 2013开发Web应用程序.
一旦发布,我花了一些时间升级到RC位.感谢所有伟大的帖子:例如.解耦Microsoft.AspNet.Identity.*并将asp.net MVC从5.0.0-beta2更新到5.0.0-rc1!
在我无限的智慧中,我决定转向@Hao Kung在这里发布的RTM位:我如何能够及早访问即将到来的Asp.Net Identity变化?.我认为当我们最终收到RTM版本时,我会省去麻烦并且不会太落后.
这可能是一场噩梦,或者我只是完全遗漏了某些东西(或两者兼而有之),因为我无法弄清楚曾经使用RC1的基本任务.
虽然我似乎是通过控制器登录用户(Asp.Net Identity RTM版本中的Microsoft.AspNet.Identity.Owin.AuthenticationManager在哪里?)...我的WindowsIdentity始终为空,在我调用SignIn后未经过身份验证.正确填充了user和claimIdentity对象.
这是我调用的操作方法(为了完整性将属性移动到局部变量):
[HttpPost, AllowAnonymous, ValidateAntiForgeryToken]
public virtual async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid) {
var userManager = new UserManager<EtdsUser>(new UserStore<EtdsUser>(new EtdsContext()));
var user = userManager.Find(model.UserName, model.Password);
if (user != null) {
var authenticationManager = HttpContext.GetOwinContext().Authentication;
authenticationManager.SignOut(new[] {DefaultAuthenticationTypes.ApplicationCookie, DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.ExternalBearer});
var claimsIdentity = await userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
authenticationManager.SignIn(new AuthenticationProperties { IsPersistent = model.RememberMe}, claimsIdentity);
return RedirectToLocal(returnUrl);
}
}
ModelState.AddModelError("", "The …Run Code Online (Sandbox Code Playgroud) 我正在使用ASP.NET MVC 5.1与Owin和声明身份验证.
用户更改其电子邮件后,我需要更新用户声明,所以我尝试在控制器中:
ClaimsIdentity identity = (ClaimsIdentity)User.Identity;
Claim claim = identity.FindFirst(ClaimTypes.Email);
identity.RemoveClaim(claim);
identity.AddClaim(new Claim(ClaimTypes.Email, newEmail));
IOwinContext context = new OwinContext();
context.Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
context.Authentication.SignIn(identity);
Run Code Online (Sandbox Code Playgroud)
索赔已更改,但当我刷新页面时,电子邮件声明再次原始...
似乎cookie没有更新.知道我做错了什么吗?
是否有可能从身份中获取"IsPersistent"的值,所以当我再次签名时,我将获得相同的值?
谢谢,
米格尔
在WIF之前,Application_PostAcquireRequestState是创建自定义标识的好地方,但需要大量框架来确保您正在进行的每种类型的身份验证都已正确映射.通过自定义标识,我的意思是继承自Identity的类,例如下面的SomeIdentity,这样我们就可以拥有一个特定的属性,我们可能需要所有经过身份验证的用户拥有.
PostAcquirerequestState仍然可用,但是有很多新方法可以挂钩进行身份验证.此外,支持多种身份验证方法时,旧方法变得复杂.
我想知道在WIF中是否有比下面更好的方法来实现这一点.主要是我想将处理映射声明的代码分离出来.这个想法是代码对于其他身份验证类型/提供者而言是不同的,因为它检索该属性值的方式可能不是来自诸如SAML的声明,而是来自其他地方的其他类型的身份验证方法.我Kentor.AuthServices目前正在使用SAML支持.虽然可能有不同的代码用于根据提供程序映射这些值,但最终结果是已创建SomeIdentity实例并且将设置SomeProperty和其他属性.这样,应用程序的其余部分总是可以依赖/假设已经处理过.
我的MVC项目想出了一个AccountController即有ExternalLoginCallback其隐含的可能是,当外部认证结束一个良好的钩的名字(这对我SAML是"外部"认证).但是,在SAML身份验证期间/之后的任何时候似乎都没有受到攻击.
可能答案是我们仍然需要以旧方式将它们拼凑在一起,但我希望WIF有一些更好的框架钩子来使这更容易.
public sealed class SomeIdentity : Identity
{
...
// Some custom properties
public string SomeProperty { get;set;}
}
protected void Application_PostAcquireRequestState(object sender, EventArgs e)
{
...
identity = new SomeIdentity(id, userId);
// map a claim to a specific property
identity.SomeProperty = ...Claims[IdpSomePropertyKey];
///...
GenericPrincipal newPrincipal = new GenericPrincipal(identity , null);
HttpContext.Current.User = newPrincipal;
System.Threading.Thread.CurrentPrincipal = newPrincipal;
}
Run Code Online (Sandbox Code Playgroud)
现在我正在使用WIF,我应该在哪里放置特定于特定身份验证类型的代码(即Kentor.AuthServices SAML)来创建自定义SomeIdentity?
我的想法是,SomeIdentity将是我的应用程序中随处使用的标识类,但是填充它的属性的代码将需要专门针对每种身份验证类型编写,例如使用SAML来提取声明并使用它们的值来设置proeprties.即它是映射发生的地方.
我无法让ASP Identity按需刷新存储在cookie中的身份.
在Startup.Auth.cs文件中,cookie设置为重新生成,如下所示:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<QuizSparkUserManager, QuizSparkUser, int>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentityCallback: ((manager, user) => manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)),
getUserIdCallback: ((claimsIdentity) => int.Parse(claimsIdentity.GetUserId())))
}
});
Run Code Online (Sandbox Code Playgroud)
但是我无法弄清楚如何刷新User.Identity代码中的内容,即在我需要刷新时强制刷新身份cookie.
我希望能够以编程方式使用重新生成身份回调,这可能吗?
我的问题与此类似:如何使用Asp.Net Identity 2将用户添加到角色后使.AspNet.ApplicationCookie无效?
但是我想刷新而不是使cookie无效.
编辑
在查看链接的问题后,我尝试了以下(没有完整的错误处理):
IOwinContext context = Request.GetOwinContext();
QuizSparkSignInManager manager = context.Get<QuizSparkSignInManager>();
ClaimsIdentity newIdentity = manager.CreateUserIdentity(manager.UserManager.FindById(User.Identity.GetUserId<int>()));
AuthenticateResult authenticationContext =
await context.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ApplicationCookie);
if (authenticationContext != null)
{
context.Authentication.AuthenticationResponseGrant = new AuthenticationResponseGrant(
newIdentity, authenticationContext.Properties);
}
bool …Run Code Online (Sandbox Code Playgroud)