如何将OnAuthenticated事件中的信息传递给控制器和SignIn?
正如我在这里发现的那样 ,我无法打电话
HttpContext.GetOwinContext().Authentication.SignIn(...)
在FacebookAuthenticationProvider OnAuthenticated
事件。 这似乎是一个不同的背景。
我的用户将来自Facebook,这意味着我将需要检索id
, email
等数据……这些信息可以通过OnAuthenticated
事件访问,我需要这些信息才能登录。
我需要在我的控制器上访问这些信息……
我在活动中试过这个:
context.OwinContext.Set("FacebookUser", rawUserObjectFromFacebookAsJson);
但是在控制器上如果我尝试检索它,它就是null。
var fbuser = HttpContext.GetOwinContext() .Get("FacebookUser");
所以我的问题是,如何将这些数据传递给控制器,以便我可以登录?
通过查看这个答案并弄清楚我能做什么,我找到了一种方法。
使用Claims
我可以添加从Facebook检索到的所有值并投入到身份声明中。
OnAuthenticated = (context) => { const string XmlSchemaString = "http://www.w3.org/2001/XMLSchema#string"; var rawUserObjectFromFacebookAsJson = context.User; 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); }
然后在我的控制器上,我可以通过使用它获得该身份
ClaimsIdentity identity = await HttpContext.GetOwinContext().Authentication .GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
然后我会采取行动
[AllowAnonymous] public async Task ExternalLoginCallback(string returnUrl) { ClaimsIdentity identity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); var user = new IdentityUser() { Id = identity.GetUserId(), UserName = identity.Name, }; await LoginAsync(user, identity); if (!identity.IsAuthenticated) { return RedirectToAction("Login"); } return RedirectToAction("Index", "Home"); }
和我的LoginAsync方法
private async Task LoginAsync(IdentityUser user, ClaimsIdentity identity) { AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); // I can't just use the identity I got on Facebook // I need to create this one, or else it will not signin properly // The authentication type has to be ApplicationCookie and the property // is readonly, so... var userIdentity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); // now we have to transfer the claims, adding a check to avoid duplicates foreach (var claim in identity.Claims) { if (!userIdentity.HasClaim(c => c.Type == claim.Type)) userIdentity.AddClaim(claim); } // then it will signin successfully AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = true }, userIdentity); }
然后我可以访问
HttpContext.GetOwinContext().Authentication.User.Claims
在任何时候,并检索我需要的东西。
- C#:枚举中的按位运算符(MVC中的自定义授权)
- 如何使用简单的注入器,存储库和上下文 – 首先编码
- 在.NET MVC中,是否有一种简单的方法来检查我是否在主页上?
- MVCvalidation – 使用服务层保持干燥 – 最佳做法是什么?
- 无法使用linq lambda表达式转换’System.Data.Entity.Infrastructure.DbQuery`1 ‘类型的对象
- C#MVC 4:将View中的JavaScript数组传递给Controller
- .NET 4 MVC 2使用注释警告而不是错误进行validation
- 是否可以在ViewModel中重用DataAnnotations?
- asp.NET MVC C#的FastReport演示无法正常工作