Azure ActiveDirectoryに対して認証するASP.NETMVC5アプリがあります。アプリ全体でSSLを有効にしたかったのです。したがって、次のようにグローバルフィルターを活用しました。
public class FilterConfig
{
/// <summary>
/// Registers the global filters.
/// </summary>
/// <param name="filters">The filters.</param>
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new RequireHttpsAttribute());
}
}
この後、プロジェクトのプロパティで[SSLを有効にする]もtrueに設定します。これにより、次のSSLURLが得られました-> https:// localhost:34567 。プロジェクトを更新して、これをIIS「プロジェクトURL」の「サーバー」の下の「Webタブ」の下にある高速パス」に含めました。ただし、サイトを実行すると、次のエラーが発生します。
IDX10311:RequireNonceは 'true'(デフォルト)ですが、validationContext.Nonceはnullです。ナンスは検証できません。ナンスをチェックする必要がない場合は、OpenIdConnectProtocolValidator.RequireNonceを「false」に設定します。
私は認証を持っています。サイトで有効になっています。 Azure ActiveDirectoryを使用しています。
セキュリティコードは次のとおりです。
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri
});
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Audience = audience,
Tenant = tenant,
});
認証。値はweb.configから読み取られており、次のとおりです。
<add key="ida:ClientId" value="<some_guid>" />
<add key="ida:Audience" value="https://localhost:34567/" />
<add key="ida:AADInstance" value="https://login.windows.net/{0}" />
<add key="ida:Tenant" value="Microsoft.onmicrosoft.com" />
<add key="ida:PostLogoutRedirectUri" value="https://localhost:34567/" />
次のエラーメッセージの指示に従って、RequireNonceをfalseに設定してみました。
ProtocolValidator = new OpenIdConnectProtocolValidator
{
RequireNonce = false
}
しかし、これは無効な要求エラーを引き起こしました。
誰かが私に問題がここにあることを理解するのを手伝ってもらえますか? SSLが有効になるまで、すべてがうまく機能しました。
エラーメッセージがOICE_20004で始まる場合、またはIDX10311が含まれている場合は、例外を無視できます。注:自己責任で行ってください。
Notifications = new OpenIdConnectAuthenticationNotifications()
{
RedirectToIdentityProvider = (context) =>
{
// Ensure the URI is picked up dynamically from the request;
string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + context.Request.Uri.PathAndQuery;
context.ProtocolMessage.RedirectUri = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + context.Request.Uri.PathAndQuery;
context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
return Task.FromResult(0);
},
AuthenticationFailed = (context) =>
{
if (context.Exception.Message.StartsWith("OICE_20004") || context.Exception.Message.Contains("IDX10311"))
{
context.SkipToNextMiddleware();
return Task.FromResult(0);
}
return Task.FromResult(0);
},
}
Azure管理ポータルから、対応するActive Directoryの下のアプリケーションに同じサインオンURLと応答があることを確認しますURL。
それらが同じでない場合、このエラーが発生します。
これは、SSLを有効にすると、サインオンURLのみがHTTPS URLに変更され、応答URLは同じHTTPURLのままであるために発生します。
編集:なぜこれが起こっているのかを正確に知りたい場合は読んでください、
Https URLを使用してアプリにアクセスしようとすると、ブラウザーに一意の番号(nonce)でCookieが設定され、認証のためにAzureADにアクセスします。認証後、ブラウザはそのCookieへのアクセスを許可する必要があります。ただし、サインオンURLと返信URLが異なるため、ブラウザーはアプリを認識せず、そのCookieへのアクセスを許可しないため、アプリケーションはこのエラーをスローします。
ログインに成功した後でも、Webアプリケーションで戻るボタンを数回押すと、このエラーを再現できます。次の2つのことを試すことができますか:以下のコードで:
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = mViewWebSite.ClientId,
Authority = mViewWebSite.Authority,
PostLogoutRedirectUri = mViewWebSite.PostLogoutRedirectUri
});
エラーが示唆するように、認証オプションの1つとしてプロトコルバリデーターを追加します。
ProtocolValidator = new Microsoft.IdentityModel.Protocols.OpenIdConnectProtocolValidator(){
RequireNonce = false
}
または通知を追加します。これにより、このエラーをキャッチして、エラーページにリダイレクトできます。私はそれを優雅にするためにそれをします。カタナの人々がそれを修正するまで。
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/Error.aspx?message=" + context.Exception.Message);
return Task.FromResult(0);
}
},
Global.asaxファイルで次の方法を使用してこの問題を回避することができます。少なくとも、これはクライアントに例外を表示しません。 ELMAHを使用して例外をキャッチします。
protected void Application_Error(object sender, EventArgs args)
{
var ex = Server.GetLastError();
if (ex.Message.Contains("IDX10311:"))
{
Server.ClearError();
Response.Redirect("https://www.yoursitename.com");
}
ここでの問題は単純です...これを理解するのに何時間もかかりました。ローカルでテストしていたのでhttpsがなく、Azure ADで最初にアプリを作成したときに真実を伝えるために、テスト中にhttpsであるとは予想していなかったので、プレーンhttp(replyUrlのホームページURL、すべてのジャズをログアウト)にしました。
その後、これを実行した後、無限ループの問題が発生しました多くの人が取得しています。それで私は自分のローカルで証明書をモックすることに決めました、そしてうん、無限のリダイレクトを取り除きましたが、それから別のものを持ってきました "IDX10311:RequireNonce is'true '"
簡単に言えば...すべてのエンドポイントでAzureADアプリをhttpsにします。そしてwallah!
カタナのソースコードを見るのがおそらく最善でしょう。それから、例外タイプがOpenIdConnectProtocolInvalidNonceExceptionであることがわかったので、このように処理します。
if (n.Exception is OpenIdConnectProtocolInvalidNonceException &&
n.OwinContext.Authentication.User.Identity.IsAuthenticated)
{
n.SkipToNextMiddleware();
return;
}
ログイン後に戻るボタンをクリックするページとユーザーをキャッシュするブラウザで、この例外ポップアップが表示されます。
@ zb3b回答 + @ jonmeyer回答 :
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
...
Notifications = new OpenIdConnectAuthenticationNotifications()
{
...
AuthenticationFailed = (context) =>
{
if ((context.Exception is OpenIdConnectProtocolInvalidNonceException) &&
(context.OwinContext.Authentication.User.Identity.IsAuthenticated))
{
context.SkipToNextMiddleware();
return Task.FromResult(0);
}
return Task.FromResult(0);
},
...
}
});
私が遭遇した別のケースを追加するだけです。接続しているネットワークがHTMLコンテンツを変更している可能性があります。
顧客が問題を抱えて電話をかけました:彼はこのエラーを乗り越えることができませんでした。それは彼が以前にログオンしたことがなかった新しいラップトップでした。いくつかの可能な解決策を約1時間試した後、私は彼が接続しているネットワークを確認することにしました。
彼は空港のネットワークに接続されていて、オープンでセキュリティで保護されておらず、VPNサービスを使用していませんでした(いくつかの [〜#〜] seta [〜#〜] がありません)。誰がそのネットワークを運用していたのか、何をしていたのか正確にはわかりませんが、AzureADサービスがナンスの何らかの改ざんを検出したに違いありません。
ユーザーが信頼できるネットワークに接続した瞬間、問題は解決しました。