LinkedInをプロバイダーとして追加しました。ログインを実装し、LinkedInに問題なく登録しました。ユーザーがプロバイダーページ内からキャンセルする(linkedInログインまたはアプリの承認をキャンセルする)ユースケースでは、IDミドルウェアは未処理の例外をスローするようです。
リクエストの処理中に未処理の例外が発生しました。
例外:user_cancelled_login; Description =ユーザーがLinkedInログインをキャンセルしました
場所が不明例外:リモートログインの処理中にエラーが発生しました。
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()
System.Exception:user_cancelled_login; Description =ユーザーがLinkedInログインをキャンセルしました
例外:リモートログインの処理中にエラーが発生しました。
起動時のプロバイダー設定は、コールバックを定義します。
services.AddAuthentication().AddOAuth("LinkedIn", "LinkedIn", c =>
{
c.ClientId = Configuration["Authentication:LinkedIn:ClientId"];
c.ClientSecret = Configuration["Authentication:LinkedIn:ClientSecret"];
c.Scope.Add("r_basicprofile");
c.Scope.Add("r_emailaddress");
c.CallbackPath = "/signin-linkedin";
....
そして、私が言ったように、ミドルウェアは、ユーザーがLinkedInページ内でキャンセルする場合を除いて、他のすべてのケースを処理しているようです。 LinkedInからの戻りURLは正しいようです。
しかし、ログイン/承認の成功などの他のケースが処理される私のExternalCallbackコントローラーメソッドに到達することはありませんか?
これがサードパーティプロバイダーを持つ他の誰かのために働いているかどうか疑問に思っていますか?
Githubの問題 があり、ここで何が起こっているのかをより詳細に説明しています。なぜ起こっているのか、さらにはこれが発生することを示しています。 「修正」される:
RemoteFailureイベントの処理は正しいことです。ドキュメント/サンプルを更新して、そのイベントの処理方法を示し、少なくともユーザーにより適切なメッセージを表示する必要があります。エラーページのサンプルには、ユーザーが再度ログインを試行できるようにするためのリンクが含まれている可能性があります。
残念ながら、このイベントを非常に一般的な方法で実装することは困難です。これは、各リモート認証プロバイダーがさまざまなタイプの障害に対して独自の動作をするため、非常に便利です。
これの回避策(上記で引用)は、RemoteFailureイベントを処理することです。
services.AddAuthentication().AddOAuth("LinkedIn", "LinkedIn", c => {
// ...
c.Events.OnRemoteFailure = ctx =>
{
// React to the error here. See the notes below.
return Task.CompletedTask;
}
// ...
});
ctx
は RemoteFailureContext のインスタンスであり、何が悪かったのかを説明する Exception
プロパティが含まれています。 ctx
には HttpContext
プロパティも含まれており、このような例外に応じてリダイレクトなどを実行できます。
this に基づいて、Kirk Larkinの回答と同様に、次のことがうまく機能することがわかりました。少し理解が必要だったのは、その後のログイン試行で問題を引き起こすことなく、どこにリダイレクトするかでした。
services.AddAuthentication().AddOAuth("LinkedIn", "LinkedIn", c =>
{
...
c.Events = new OAuthEvents()
{
OnRemoteFailure = (context) =>
{
context.Response.Redirect(context.Properties.GetString("returnUrl"));
context.HandleResponse();
return Task.CompletedTask;
}
};
};