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 ClaimsExternalLoginConfirmation 코드에 넣습니다. 프레임 워크가 들어오는 표준 을 프레임 워크에 의해 노출 된 ClaimsIdentity의 클레임으로 변환한다는 또 다른 합당한 기대가 있습니다.

나는 MicrosoftAccountAutheticationHandler.cs을 사용할 수있어서 매우 기쁩니다. 응답이 없습니다. 문서화와 프레임 워크가 성숙 해짐에 따라 카타나 (Katana)에게 기원합니다. 프레임 워크가 개발자가 설정 문제를 해결하는 데 도움이되는 방법이 있습니까?

답변

0

우리 모두가 논리적 벽돌 벽을 논리적으로 치지 않았다면 동의했을 것입니다 ... 웹 응용 프로그램이 별도의 컨텍스트에서 작동하는 동안 분리 된 Owin 보안 컨텍스트와 관련이 있다고 생각합니다. 그리고 당신은 웹에 '시드'해야합니다. 그래서 제가 추론 한 것은 이것이다 :

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); 

Startup.Auth.cs

및 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); 
    }