如何将OnAuthenticated事件中的信息传递给控制器​​和SignIn?

正如我在这里发现的那样 ,我无法打电话

HttpContext.GetOwinContext().Authentication.SignIn(...) 

在FacebookAuthenticationProvider OnAuthenticated事件。 这似乎是一个不同的背景。

我的用户将来自Facebook,这意味着我将需要检索idemail等数据……这些信息可以通过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 

在任何时候,并检索我需要的东西。