4

請告訴我什麼是錯誤的。向Startup.Auth.cs中的MicrosoftAccountAuthenticationOptions添加範圍「wl.emails」會導致問題

public void ConfigureAuth(IAppBuilder app) 
    { 
     var mo = new MicrosoftAccountAuthenticationOptions(); 
     mo.ClientId = "xxxxxxxxxxxxxxxxx"; 
     mo.ClientSecret = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"; 
     mo.Scope.Add("wl.basic"); // No effect if this commented out 
     mo.Scope.Add("wl.emails"); 

     // IF I COMMENT NEXT TWO PROPERTIES, USER IS AUTHENTICATED, BUT THE DB IS NOT 
     // UPDATED. LEAVE THEM AND THE REDIRECT FROM MSLIVE ENDS ON LOGIN PAGE 

     mo.SignInAsAuthenticationType = "External"; 
     mo.Provider = new MicrosoftAccountAuthenticationProvider() 
     { 
      OnAuthenticated = (context) => 
       { 
     // Set breakpoint here to see the context.Identity.Claims HAS CLAIMS DESIRED. 
     // SO IT APPEARS TO ME Nothing to do here but verify they exist in the debugger. 
     //(context.Identity.Claims).Items ARE: 
     //{http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier: xxxxxxxxx} 
     //{http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name: yyyy yyyyy} 
     //{urn:microsoftaccount:id: xxxxxxxx} 
     //{urn:microsoftaccount:name: yyyy yyyyy} 
     //{http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress: [email protected]} 
       return Task.FromResult(0); 
       } 
     }; 
     // Enable the application to use a cookie to store information for the signed in user 
     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
      LoginPath = new PathString("/Account/Login") 
     }); 
     // Use a cookie to temporarily store information about a user logging in with a third party login provider 
     app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 

     app.UseMicrosoftAccountAuthentication(mo); 
    } 

一個合理的預期斷言,framwework將透明地處理增加了一個適用範圍爲默認*AuthenticationOptions。隨後,關於MVC5模板,開發人can extract and persist Claims的代碼爲ExternalLoginConfirmation。另一個合理的預期是,框架將把傳入的標準ClaimTypes轉換爲框架公開的ClaimsIdentity中的權利要求。

我很高興源代碼可用​​,我會檢查它來解決這個問題;缺乏迴應。 Katana作爲文檔和框架的最後祝願正在成熟。有沒有一種方法可以幫助開發者找到配置問題?

回答

0

我會同意你的,如果我們都沒有達到相同的推理邏輯磚牆.... 我認爲這是一個獨立的Owin安全上下文,而Web應用程序運行在一個單獨的上下文你必須'種子'網絡之一。所以我所推斷的是:在

Startup.Auth.cs

var microsoftOptions = 
      new Microsoft.Owin.Security.MicrosoftAccount.MicrosoftAccountAuthenticationOptions 
      { 
       CallbackPath = new Microsoft.Owin.PathString("/Callbacks/External"),//register at oAuth provider 
       ClientId = "xxxx", 
       ClientSecret = "yyyyyyyyyyyyyyyyy", 
       Provider = new Microsoft.Owin.Security.MicrosoftAccount.MicrosoftAccountAuthenticationProvider 
       { 
        OnAuthenticated = (context) => 
         { 
          context.Identity.AddClaim(new Claim(providerKey, context.Identity.AuthenticationType)); 
          context.Identity.AddClaim(new Claim(ClaimTypes.Name, context.Identity.FindFirstValue(ClaimTypes.Name))); 
          return System.Threading.Tasks.Task.FromResult(0); 
         } 
       } 
      }; 
     microsoftOptions.Scope.Add("wl.basic"); 
     microsoftOptions.Scope.Add("wl.emails"); 
     app.UseMicrosoftAccountAuthentication(microsoftOptions); 

和的AccountController

[AllowAnonymous] 
    public async Task<ActionResult> oAuthCallback(string returnUrl) 
    { 
     var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); 
     if (loginInfo == null) 
     { 
      if (User.Identity.IsAuthenticated) 
       return RedirectToAction("Index", "Manage"); 
      else 
       return RedirectToAction("Login"); 
     } 

     var currentUser = await UserManager.FindAsync(loginInfo.Login); 
     if (currentUser != null) 
     { 
      await StoreExternalTokensOnLocalContext(currentUser); 
     } 
     //.... rest as same as per AspNet Sample project. 
    } 


    private async Task StoreExternalTokensOnLocalContext(ApplicationUser user) 
    { 
     if (user == null) 
      return; 

     var externalIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); 
     if (externalIdentity != null) 
     { 
      // Retrieve the existing claims for the user and add the FacebookAccessTokenClaim 
      var currentClaims = await UserManager.GetClaimsAsync(user.Id); 
      //var providerClaim = externalIdentity.FindFirstValue("provider") ?? string.Empty; 
      await StoreClaim("provider", user.Id, externalIdentity); 
      await StoreClaim("FacebookId", user.Id, externalIdentity); 
      await StoreClaim("image", user.Id, externalIdentity); 
      await StoreClaim("link", user.Id, externalIdentity); 
      await StoreClaim(ClaimTypes.Name, user.Id, externalIdentity); 
      await StoreClaim(ClaimTypes.Email, user.Id, externalIdentity); 

      var addedClaims = await UserManager.GetClaimsAsync(user.Id); 
     } 
    } 

    private async Task StoreClaim(string typeName, string userId, ClaimsIdentity externalIdentity) 
    { 
     var providerClaim = externalIdentity.Claims.FirstOrDefault(c => c.Type.Equals(typeName)); 
     if (providerClaim == null) 
      return; 
     var previousClaims = await UserManager.GetClaimsAsync(userId); 
     if (previousClaims.IndexOf(providerClaim) >= 0) 
      return; 
     var idResult = await UserManager.AddClaimAsync(userId, providerClaim); 
    }