2014-08-31 60 views
7

我希望有人能幫助我解決這個問題 - 這讓我很生氣! :)MVC 5 OWIN - IsAuthenticated在外部登錄時出錯(QQ連接)

我試圖使用tinysnake的QQ連接提供商通過QQ連接(OAuth 2.0用戶)使用外部登錄:https://github.com/tinysnake/microsoft-owin-security-qq

一切似乎是偉大的去 - 我可以通過我的QQ賬號登錄,然後我得到通過適當的聲明等回到我的ExternalLoginCallBack方法。 我使用這些值通過IAuthenticationManager對用戶進行簽名 - 一切順利。但是 - 當我將用戶重定向到另一個頁面並檢查他是否已登錄時 - 然後我從IsAuthenticated值中得到一個錯誤的值...並且我無法讀取我之前設置的任何聲明。

這可能是一個簡單的解決方法 - 但我看不出它現在:)

一些代碼:

AuthConfig:

public static void ConfigureAuthentication(IAppBuilder app) 
{ 
    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 

    // Normal cookie sign in 
    app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
     LoginPath = new PathString("/Account/Login"), 
     AuthenticationMode = AuthenticationMode.Active 
    }); 

    // QQ CONNECT 
    app.UseQQConnectAuthentication(
     appId: "XXXXXX", 
     appSecret: "XXXXXXXXXXXXXXXXX"); 
} 

的AccountController:

// 
// POST: /Account/ExternalLogin 
[System.Web.Mvc.HttpPost] 
[System.Web.Mvc.AllowAnonymous] 
[ValidateAntiForgeryToken] 
public ActionResult ExternalLogin(string provider, string returnUrl) 
{ 
    // Request a redirect to the external login provider 
    return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl })); 
} 

// 
// GET: /Account/ExternalLoginCallback 
[System.Web.Mvc.AllowAnonymous] 
[HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)] 
public async Task<ActionResult> ExternalLoginCallback(string returnUrl) 
{ 
    var ctx = Request.GetOwinContext(); 
    var result = ctx.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie).Result; 
    var claims = result.Identity.Claims.ToList(); 
    var name = claims.First(i => i.Type == "urn:qqconnect:name"); 

    claims.Add(new Claim(ClaimTypes.AuthenticationMethod, "QQ")); 
    claims.Add(new Claim(ClaimTypes.Name, name.Value)); 

    var ci = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ExternalCookie); 
    ctx.Authentication.SignIn(ci); 

    // DO OTHER STUFF HERE 

    return Redirect("~/"); 
} 

一切似乎進展順利,到目前爲止...

的HomeController:

public ActionResult Index() 
{ 
    var model = new HomeViewModel(); 

    var ctx = Request.GetOwinContext(); 
    if (ctx.Authentication.User.Identity.IsAuthenticated) // <-- THIS RETURNS FALSE 
    { 
     var claimsIdentity = User.Identity as ClaimsIdentity; 
     model.Name = claimsIdentity.FindFirst(ClaimTypes.Name).Value; 
     model.IsAuthenticated = true; 
    } 

    return View(model); 
} 

當我檢查ctx.Authentication.User.Identity.IsAuthenticated,我得到一個錯誤的價值... ...和我也無法檢索任何索賠。

我錯過了什麼嗎?

任何幫助,將不勝感激:)

UPDATE

我得到了我的代碼在我的AccountController做這個工作:

public async Task<ActionResult> ExternalLoginCallback(string returnUrl) 
{ 
    var ctx = Request.GetOwinContext(); 
    var result = ctx.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie).Result; 

    if (result.Identity.IsAuthenticated) 
    { 
     // Signed in successfully 
     var claims = result.Identity.Claims.ToList(); 
     var name = claims.First(i => i.Type == "urn:qqconnect:name"); 

     //claims.Add(new Claim(ClaimTypes.AuthenticationMethod, "QQ")); 
     claims.Add(new Claim(ClaimTypes.Name, name.Value)); 

     var id = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie); 
     var authenticationManager = ctx.Authentication; 
      authenticationManager.SignIn(id); 

    } 

    return Redirect("~/"); 
} 

但我看到它的方式 - 我在這裏」 m使用ApplicationCookie而不是ExternalCookie登錄...或者我完全錯過了某些東西? 這個解決方案適用於我 - 但我想知道這是否是正確的做法?

+1

與此類似的問題,如果有人可以澄清。 – cchamberlain 2014-09-22 22:19:48

回答

1

根據我的理解,您所遇到的情況是預期的。極其簡單化:

  1. 該應用程序獲取外部信息,並使用它來創建一個外部的cookie
  2. 外部cookie發送到您的應用程序,並假設它只是將用於尋找一個臨時cookie添加有關用戶的任何其他本地信息,然後轉換爲本地[應用程序] Cookie

請參閱UseCookieAuthentication vs. UseExternalSignInCookie以獲得更徹底的細分。