ブラウザの認証ダイアログを抑制するにはどうすればよいですか?


85

私のWebアプリケーションには、AJAX呼び出しを介して認証資格情報を送信するログインページがあります。ユーザーが正しいユーザー名とパスワードを入力すれば、すべて問題ありませんが、そうでない場合は、次のようになります。

  1. Webサーバーは、要求に整形式のAuthorizationヘッダーが含まれていても、ヘッダー内の資格情報が正常に認証されていないと判断します。
  2. Webサーバーは401ステータスコードを返し、サポートされている認証タイプを一覧表示する1つ以上のWWW-Authenticateヘッダーを含みます。
  3. ブラウザは、XMLHttpRequestオブジェクトに対する私の呼び出しへの応答が401であり、応答にWWW-Authenticateヘッダーが含まれていることを検出します。次に、ユーザー名とパスワードの入力を求める認証ダイアログが表示されます。

これは、ステップ3まではすべて問題ありません。ダイアログをポップアップさせたくないので、AJAXコールバック関数で401応答を処理したいと思います。(たとえば、ログインページにエラーメッセージを表示することによって。)もちろん、ユーザーにユーザー名とパスワードを再入力してもらいたいのですが、ブラウザーの醜いデフォルトではなく、フレンドリーで安心できるログインフォームを表示してもらいたいです。認証ダイアログ。

ちなみに、私はサーバーを制御できないため、カスタムステータスコード(つまり、401以外のもの)を返すようにすることはできません。

認証ダイアログを非表示にする方法はありますか?特に、Firefox 2以降で[認証が必要]ダイアログを非表示にできますか?IE 6以降で[[ホスト]に接続]ダイアログを抑制する方法はありますか?



著者からの追加情報の編集(9月18日):
ブラウザーの認証ダイアログがポップアップする際の本当の問題は、ユーザーに十分な情報が提供されないことです。

ユーザーは、ログインページのフォームからユーザー名とパスワードを入力したばかりで、両方を正しく入力したと考えており、送信ボタンをクリックするか、Enterキーを押しました。彼の期待は、次のページに移動するか、情報を間違って入力したため、再試行する必要があると言われることです。ただし、代わりに予期しないダイアログボックスが表示されます。

ダイアログには、彼はただ事実の確認になりませんでしたユーザ名とパスワードを入力します。問題があったこと、そして彼が再試行する必要があることを明確に述べていません。代わりに、ダイアログボックスは、「サイトは次のように言っています: ' [レルム] ' 」のような不可解な情報をユーザーに表示します。ここで、[レルム]は、プログラマーだけが愛することができる短いレルム名です。

Webブラウザーの設計者は注意します。ダイアログ自体が単によりユーザーフレンドリーである場合、認証ダイアログを抑制する方法を誰も尋ねません。全体私がログインフォームをしていた理由は、私たちの製品管理チームは間違いなくブラウザの認証ダイアログがひどいことを考慮することです。


1
答えは、良い答えはないということです。Marijnによって提案されたハックは、可能な限り近いものです。もちろん、可能であれば、サーバーとJavaScriptによって理解されるが、ブラウザーによっては理解されないカスタム認証を使用することもできます。
dgvid 2009

私は同じ問題を抱えており、stackoverflow(私のブログではありません)のコメントでこのリンクを見つけました:loudvchar.blogspot.ca/2010/11/…お役に立てば幸いです。
gies0r 2013年

回答:


17

これは不可能だと思います。ブラウザのHTTPクライアント実装を使用すると、常にそのダイアログがポップアップ表示されます。2つのハックが思い浮かびます。

  1. たぶんFlashはこれを別の方法で処理するので(私はまだ試していません)、Flashムービーでリクエストを行うと役立つかもしれません。

  2. 自分のサーバーでアクセスしているサービスの「プロキシ」を設定し、認証ヘッダーを少し変更して、ブラウザがそれらを認識しないようにすることができます。


「不可能」が正解のようですが、「プロキシ」ハックでうまくいくと思います。
dgvid 2009

@Stoborあなたが投稿した複製に対して受け入れられた回答は、実際にはその回答としてこの質問にリンクしています。
8bitjunkie 2014

3
@ 7SpecialGems良いキャッチ。私はそれがだまされていることを示唆していませんでした、私は受け入れられた答えの4年後に投稿された特定の答え(WWW-Authenticateのもの)にリンクしました。後から考えると、なぜそれを見たのか、どのようにテストしたのか思い出せません。
Stobor 2014

1
次のコードで不正な401エラーをキャッチしようとしています:$ .ajaxSetup({statusCode:{401:function(){RedirectToLogin();}}}); ただし、IEは常にブラウザの認証ダイアログを表示します。ASP.Net MVC 2でこのダイアログを抑制するにはどうすればよいですか?
PaulP 2015

@PaulPは、前述のように、WWW-Authenticateヘッダーの401ステータスコード応答を削除するプロキシ、またはある種のカスタムサーバー実装が必要です。
モート2015

51

ここで同じ問題が発生し、会社のバックエンドエンジニアは、明らかにグッドプラクティスと見なされる動作を実装しました。URLへの呼び出しが401を返す場合、クライアントがヘッダーを設定している場合X-Requested-With: XMLHttpRequest、サーバーはwww-authenticateヘッダーをその中にドロップします。応答。

副作用は、デフォルトの認証ポップアップが表示されないことです。

API呼び出しに X-Requested-Withヘッダーがに設定されXMLHttpRequest。もしそうなら、このグッドプラクティスに従ってサーバーの動作を変更する以外に何もすることはありません...


3
バックエンドがJava / Springベースの場合、DelegatingAuthenticationEntryPointハンドルがこの動作を自動的に処理します。
Derek Slife 2016年

これありがとう。Deviseを含む多くの図書館がこの振る舞いを採用しています
josephnvu

1
nginxでこれを行う方法はありますか?「URLへの呼び出しが401を返すとき、クライアントがヘッダーX-Requested-With:XMLHttpRequestを設定している場合、サーバーは応答でwww-authenticateヘッダーをドロップします。」
markmnl

18

次の両方の条件が満たされると、ブラウザはログインプロンプトをポップアップします。

  1. HTTPステータスは4xxです
  2. WWW-Authenticate ヘッダーが応答に存在します

HTTP応答を制御できる場合は、 WWW-Authenticateは、応答からヘッダーを、ブラウザーはログインダイアログをポップアップしません。

応答を制御できない場合は、プロキシを設定して、 WWW-Authenticateして、応答からヘッダー。

私の知る限り(間違っている場合は遠慮なく訂正してください)、ブラウザーがWWW-Authenticateヘッダーを受信すると、ログインプロンプトを防ぐ方法はありません。


良い情報。有効なWWW-Authenticateヘッダー値については、stackoverflow.com
a / 1748451/225217

6

この質問とその答えは非常に古いものだと思います。しかし、私はここに行き着きました。おそらく他の人もそうするでしょう。

401を返すWebサービスのコードにアクセスできる場合。この状況では、401ではなく403(禁止)を返すようにサービスを変更するだけです。ブラウザは403に応答して資格情報の入力を求めません。403は特定のリソースに対して許可されていない認証済みユーザーの正しいコード。これがOPの状況のようです。

403のIETFドキュメントから:

アクセスを取得するのに十分ではない有効な資格情報を受信するサーバーは、403(禁止)ステータスコードで応答する必要があります


4

Mozillaでは、XMLHttpRequestオブジェクトを作成するときに、次のスクリプトを使用してこれを実現できます。

xmlHttp=new XMLHttpRequest();
xmlHttp.mozBackgroundRequest = true;
xmlHttp.open("GET",URL,true,USERNAME,PASSWORD);
xmlHttp.send(null);

2行目はダイアログボックスを防ぎます...


1
これが表示されますは、Firefox 3の下には、Firefox 2これは、DOMのセキュリティエラーになり、NS_ERROR_DOM_SECURITY_ERRコード1000の下に何もしないように
dgvid

2

どのサーバーテクノロジーを使用していますか?認証に使用する特定の製品はありますか?

ブラウザはその仕事をしているだけなので、401ステータスコードを返さないようにサーバー側で変更する必要があると思います。これは、認証が失敗したときにフォームを再度返すカスタム認証フォームを使用して行うことができます。


2

Mozillaランドでは、XMLHttpRequest(docs)のmozBackgroundRequestパラメーターをtrueに設定すると、これらのダイアログが抑制され、リクエストが単に失敗します。ただし、クロスブラウザーのサポートがどれほど優れているかはわかりません(失敗した要求のエラー情報の品質がブラウザー間で非常に優れているかどうかを含みます)。


moz-プレフィックスは、クロスブラウザーのサポートがないことを意味します(他の各ブラウザーで機能する同様のパラメーターが見つからない場合を除く)。
ブリリアン

2

jan.vdberghには真実があります。サーバー側の401を別のステータスコードに変更できる場合、ブラウザはポップアップをキャッチしてペイントしません。別の解決策は、別のカスタムヘッダーのWWW-Authenticateヘッダーを変更することです。別のブラウザがそれをサポートできない理由は信じられません。Firefoxのいくつかのバージョンでは、mozBackgroundRequestを使用してxhrリクエストを実行できますが、他のブラウザでは?? ここに、Chromiumのこの問題との興味深いリンクがあります。


1

私はMVC5とVPNでこれと同じ問題を抱えており、VPNを使用してDMZの外にいるときはいつでも、このブラウザーメッセージに応答する必要があります。.netを使用して、エラーのルーティングを使用して処理します。

<customErrors defaultRedirect="~/Error"  >
  <error statusCode="401" redirect="~/Index"/>
</customErrors>

これまでのところ、ホームコントローラーの下のインデックスアクションがユーザーを検証するため、機能しています。このアクションのビューには、ログオンが失敗した場合に、ディレクトリサービスに渡されたLDAPクエリを使用してユーザーをログインさせるために使用するログインコントロールがあります。

      DirectoryEntry entry = new DirectoryEntry("LDAP://OurDomain");
      DirectorySearcher Dsearch = new DirectorySearcher(entry);
      Dsearch.Filter = "(SAMAccountName=" + UserID + ")";
      Dsearch.PropertiesToLoad.Add("cn");

これはこれまでのところ正常に機能していますが、まだテスト中であり、上記のコードを実行する理由がないため、削除される可能性があることをお知らせする必要があります...テストには現在、2番目のセットのケースを発見する試みが含まれていますコードのはもう役に立ちません。繰り返しになりますが、これは進行中の作業ですが、何らかの助けになるか、アイデアを頭に浮かぶ可能性があるため、今すぐ追加することにしました...すべてのテストが完了したら、最終結果で更新します。


1

Node、Express、Passportを使用していますが、同じ問題に苦労していました。www-authenticateヘッダーを空の文字列に明示的に設定することで機能するようになりました。私の場合、次のようになりました。

(err, req, res, next) => {
  if (err) {
    res._headers['www-authenticate'] = ''
    return res.json(err)
  }
}

それが誰かを助けることを願っています!


0

歌っていないC#の場合は、の代わりにActionAttribute戻り、「飲み込む」基本認証ダイアログが表示されます。400401

public class NoBasicAuthDialogAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);
        filterContext.Result = new HttpStatusCodeResult(400);
    }
}

次のように使用します。

[NoBasicAuthDialogAuthorize(Roles = "A-Team")]
public ActionResult CarType()
{
 // your code goes here
}

これで時間を節約できれば幸いです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.