5

私はidentityServer4のドキュメントを読んでおり、ログインプロバイダとしてMicrosoft Office 365を使用するように設定しました。ユーザーがログインしたとき、私は彼が私のアプリがstartup.csASP.NET ID(IdentityServer4を使用)外部リソースoauthアクセストークンを取得

app.UseMicrosoftAccountAuthentication(new MicrosoftAccountOptions 
{ 
    AuthenticationScheme = "Microsoft", 
    DisplayName = "Microsoft", 
    SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme, 

    ClientId = "CLIENT ID", 
    ClientSecret = "CLIENT SECRET", 
    CallbackPath = new PathString("/signin-microsoft"), 
    Events = new OAuthEvents 
    { 
     OnCreatingTicket = context => 
     { 
      redisCache.Set("AccessToken", context.AccessToken.GetBytes(), new DistributedCacheEntryOptions 
      { 
       AbsoluteExpiration = DateTimeOffset.UtcNow.AddDays(3) 
      }); 
      return Task.FromResult(context); 
     } 
    } 
    Scope = 
    { 
     "Calendars.Read", 
     "Calendars.Read.Shared", 
    }, 
    SaveTokens = true 
}); 
にgraph.microsoft.com

のウェブフックAPIを使用して自分のカレンダーイベントにコードを購読できるようにすることができ、ボタンを作りたいです

しかし、これは明らかに実行可能な道ではありません。私はテストの目的でこれを行い、必要な購読のPoCを作成しました。

今、私は、この外部アクセストークンを取得できるようにするidentityServerと通信するためにスマートな方法があるかどうかを知りたいので、ログインしたユーザーの代わりにmicrosoft apiを使用できますか?

また、このOAuthEventから直接Microsoft AccessTokenを取得し、ログインしたユーザーにリンクされたデータベースに直接格納する唯一の方法はありますか?

私の機能のほとんどは第三者からのデータに基づいているので、これは本当に必要です。

答えて

8

私はついにこの問題を解決しました。私はASP.Net IdentityIdentityServer4の両方を使用している新しいプロジェクトを作成しました。これはどちらもASP.Net Coreの上に構築されています。

問題は、外部ログインプロセスで使用されたフローを完全に認識していないことでした。

あなたは両方のシステムからのボイラープレートを使用する場合は、次のような方法が存在することになるAccountControllerを持っています:

// 
// GET: /Account/ExternalLoginCallback 
[HttpGet] 
[AllowAnonymous] 
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null) 
{ 
    if (remoteError != null) 
    { 
     ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}"); 
     return View(nameof(Login)); 
    } 
    var info = await _signInManager.GetExternalLoginInfoAsync(); 
    if (info == null) 
    { 
     return RedirectToAction(nameof(Login)); 
    } 

    // Sign in the user with this external login provider if the user already has a login. 
    var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false); 
    if (result.Succeeded) 
    { 
     await _signInManager.UpdateExternalAuthenticationTokensAsync(info); 

     _logger.LogInformation(5, "User logged in with {Name} provider.", info.LoginProvider); 
     return RedirectToLocal(returnUrl); 
    } 
    if (result.RequiresTwoFactor) 
    { 
     return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl }); 
    } 
    if (result.IsLockedOut) 
    { 
     return View("Lockout"); 
    } 
    else 
    { 
     // If the user does not have an account, then ask the user to create an account. 
     ViewData["ReturnUrl"] = returnUrl; 
     ViewData["LoginProvider"] = info.LoginProvider; 
     var email = info.Principal.FindFirstValue(ClaimTypes.Email); 
     return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = email }); 
    } 
} 

が、ここで重要な部分である:

await _signInManager.UpdateExternalAuthenticationTokensAsync(info);

この外部資格情報をASP.Net identityに関連付けられたデータベーステーブルに保存します。テーブルAspNetUserTokensには、 access_token,expires_attoken_typeという3つのエントリがあります。

これらは私たちが興味を持っているトークンで、私たちのアプリケーションのどこか他の場所にユーザーの資格情報にアクセスするために使用できます。

var externalAccessToken = await _userManager.GetAuthenticationTokenAsync(User, "Microsoft", "access_token");

そして、我々は、我々が使用できるDBからのフェッチのユーザーのためにそれらを取得するために:

var user = _userManager.Users.SingleOrDefault(x => x.Id == "myId"); 
if (user == null) 
    return; 

var claimsPrincipal = await _signInManager.CreateUserPrincipalAsync(user); 
var externalAccessToken = await _userManager.GetAuthenticationTokenAsync(claimsPrincipal, "Microsoft", "access_token"); 
+0

こんにちはクリスチャンログインしているユーザーのコンテキストでこれらのトークンを取得するために

1つのasp.netプロジェクトですべての部品を使用しているのですか、IdentityServerの別のエンドポイントを使用していますか? –

+0

@AmrElsehemy私は別のプロジェクトでIDサーバーをホストしています。私たちはマイクロサービスを利用しており、他のAPIはAccessトークン検証ミドルウェアを通じてIDサーバーと通信しています。希望があなたの質問に答えることを望みます。 –

+0

別の質問ありがとう、同じエンドポイントまたは外部のものでホストされているIDサーバーがありますが、それは使用する方が良いでしょうか? –

関連する問題