ブラウザが基本認証ポップアップを呼び出してJqueryを使用して401エラーを処理するのを防ぐ方法は?


107

基本認証を使用して承認リクエストを送信する必要があります。jqueryを使用してこれを正常に実装しました。ただし、401エラーが発生すると、基本認証ブラウザのポップアップが開き、jquery ajaxエラーコールバックが呼び出されません。


回答:


46

私も最近この問題に直面していました。401基本認証またはダイジェスト認証)の場合にポップアップを表示するブラウザのデフォルトの動作を変更できないため、これを修正するには2つの方法があります。

  • を返さないようにサーバーの応答を変更します401200代わりにコードを返し、jQueryクライアントでこれを処理します。
  • 承認に使用しているメソッドをヘッダーのカスタム値に変更します。ブラウザはBasicおよびDigestのポップアップを表示します。クライアントとサーバーの両方でこれを変更する必要があります。

    headers : {
      "Authorization" : "BasicCustom"
    }

基本認証でjQueryを使用する例については、こちらもご覧ください。


10
WWW-Authenticate:xBasic realm = com.exampleは、クラシックな401ステータスコードとともにそれを実行できます。このブログの記事は、私にヒントを(私はブログの所有者ではないです)を示したloudvchar.blogspot.ca/2010/11/...
PM

2
@PM、ブログの答えは完璧なソリューションです。を使用<security:http-basic/>する場合は、定義する必要はありませんが、として定義する必要basicAuthenticationFilterがあります<security:http-basic entry-point-ref="myBasicAuthenticationEntryPoint"/>
ブレットライアン

クライアントに送信する前に応答をオーバーライドする方法を教えてください。基本認証でjaxrsを使用しています。応答を変更するためにどのクラスをオーバーライドする必要がありますか?
mohammed sameen

何らかの理由でa 401を返すと ポップアップが表示されWWW-Authenticate:Bearer WWW-Authenticate:NTLM WWW-Authenticate:Negotiateますが、その理由はわかりますか
DevEng

34

一般的な400ステータスコードを返し、そのクライアント側を処理します。

または、401を保持し、WWW-Authenticateヘッダーを返さないようにすることもできます。これは、ブラウザーが実際に認証ポップアップで応答しているヘッダーです。WWW-Authenticateヘッダーがない場合、ブラウザーは資格情報を要求しません。


6
@MortenHaraldsenさて、401応答はこの場合に適切な応答です。問題は、ブラウザーがJavaScriptアプリに処理を許可する代わりに、これをネイティブで自動的に処理することです。標準が推奨する適切な応答を返さないことで標準に固執することも、標準が推奨する応答コードを返すことで標準に固執しないことを選択することもできます。選択してください:)
イブラヒーム2015

私のExpressアプリでは、これを1行で修正しました: res.removeHeader('www-authenticate'); // prevents browser from popping up a basic auth window.
gstroup '13

1
@Ibraheem、自分でもっと良いと言うことはできなかったでしょう。標準は、座って話している人々によって作成されたものであり、必ずしも座ってコーディングした人々によって作成されたものではありません。
user2867288

15

次のようなリクエストURLで基本認証ポップアップを抑制できます。

https://username:password@example.com/admin/...

401エラー(ユーザー名またはパスワードの誤り)が発生した場合、jqueryエラーコールバックで正しく処理されます。セキュリティ上の問題が発生する可能性があります(httpsではなくhttpプロトコルの場合)。ただし、問題はありません。

UPD:このソリューションのサポートはChrome 59で削除されます


素晴らしい!!!! 問題が192.168.1.1を試行していて、ルーターがAuthを要求し続けたため、問題を解決しました。
Nadav Lebovitch、2015

どのブラウザでも、開発ツールの下の[ネットワーク]タブに移動すると、ユーザー名とパスワードをプレーンテキストで読むことができます。ただし、動作します。
Bruno Finger

19
これを行わないでください、あなたのウェブサーバーのリクエストログは私にとって今よりはるかに価値があります。無料のユーザー名とパスワードの組み合わせと応答コード!ありがとう
Remco 2016年

しかし、ユーザー名とパスワードが表示されないようにするにはどうすればよいですか
sdx11

3
この認証方法は古くなっており、Chromeでは埋め込み認証情報のサポートがhttps://user:pass@host/2017年6月頃にM59で廃止される予定です。詳しくは、このchromestatusブログの投稿をご覧ください。
Garywoo

13

他の人が指摘したように、ブラウザの動作を変更する唯一の方法は、応答に401ステータスコードが含まれていないか、含まれている場合はWWW-Authenticate: Basicヘッダーが含まれていないことを確認することです。ステータスコードの変更はあまり意味がなく望ましくないため、WWW-Authenticateヘッダーを削除することをお勧めします。Webサーバーアプリケーションを変更できない、または変更したくない場合は、Apacheを介していつでもサービスまたはプロキシを提供できます(まだApacheを使用していない場合)。

これは、Apacheがリクエストを含むWWW-AuthenticateヘッダーIFFを削除するために応答を書き換えるための設定ですX-Requested-With: XMLHttpRequest(リクエストに含まれるヘッダー(JQuery / AngularJSなどの主要なJavascriptフレームワークによってデフォルトで設定されています))AND応答にはヘッダーWWW-Authenticate: Basic

Apache 2.4でテスト済み(2.2で動作するかどうかは不明)。これは、mod_headersインストールされるモジュールに依存します。(Debian / Ubuntuでは、sudo a2enmod headersApacheを再起動します)

    <Location />
            # Make sure that if it is an XHR request,
            # we don't send back basic authentication header.
            # This is to prevent the browser from displaying a basic auth login dialog.
            Header unset WWW-Authenticate "expr=req('X-Requested-With') == 'XMLHttpRequest' && resp('WWW-Authenticate') =~ /^Basic/"
    </Location>   

1
Nginxで同じことを行うには、設定proxy_hide_header WWW-Authenticate;
Cuga

7

X-Requested-With:XMLHttpRequestをリクエストヘッダーと共に使用します。したがって、応答ヘッダーにはWWW-Authenticate:Basicは含まれません。

beforeSend: function (xhr) {
                    xhr.setRequestHeader('Authorization', ("Basic "
                        .concat(btoa(key))));
                    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
                },

1
それは私には何の影響もありませんでした。XMLHttpRequestを設定するときにWWW-Authenticateが含まれて送信されないサーバーの種類は何ですか?
Robert Antonucci、2015年

@RobertAntonucciはApache Tomcatです
sedhu

5

IISサーバーを使用している場合は、要求WWW-AuthenticationNoneれたURLのヘッダーをに書き換えるようにIIS URL書き換え(v2)を設定できます。

ガイドはこちら

変更する値はresponse_www_authenticateです。

さらに情報が必要な場合は、コメントを追加してください。web.configファイルを投稿します。


1
これはうまくいきました。IIS 7.5のURL Rewrite v2では、 "response"の部分を "RESPONSE_www_authenticate"と記述する必要があることに注意したい。
Michael Freeman

3

WWW-Authenticateヘッダーが削除された場合、資格情報のキャッシュが取得されず、リクエストでAuthorizationヘッダーが返されません。つまり、新しいリクエストを生成するたびに認証情報を入力する必要があります。


これは非常に重要です。
Tez Wingfield

2

または、サーバーの応答をカスタマイズできる場合は、403 Forbiddenを返すことができます。

ブラウザーは認証ポップアップを開かず、jqueryコールバックが呼び出されます。


5
それはHTTP 1.1仕様に反しています。そこでは「...承認は役に立たず、リクエストは繰り返されるべきではない」と述べられています。
Jukka Dahlbom、2013

1
アクセスが許可されていないリソースに対して認証されている間に403を受信することは有効です。まだ認証されていない場所に401を送信する必要があります。
ブレット・ライアン

1

Safariでは、ブラウザがポップアップを表示しないようにするために同期リクエストを使用できます。もちろん、同期リクエストはこの場合にのみユーザー資格情報をチェックするために使用する必要があります...コンテンツ(送信または受信)が非常に重い場合、実際のリクエストを送信する前にそのようなリクエストを使用できます。

    var xmlhttp=new XMLHttpRequest;
    xmlhttp.withCredentials=true;
    xmlhttp.open("POST",<YOUR UR>,false,username,password);
    xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

他のコンテキストでは、「POST」の代わりに「OPTIONS」を使用することも役立つ場合があります。
Emmanuel Sellier、2018

0

/ login urlを作成します。GETを介して「user」および「password」パラメーターを受け入れ、基本認証を必要としません。ここでは、php、node、javaなどを使用し、passwdファイルを解析して、パラメーター(ユーザー/パス)を照合します。一致する場合は、http:// user:pass@domain.com/にリダイレクトします(これにより、ブラウザーに資格情報が設定されます)ない場合は、401応答(WWW-Authenticateヘッダーなし)を送信します。


中間の攻撃でプレーンテキストの人からユーザー名/パスワードを盗聴しようとする人にとっては、それは非常に素晴らしいことです!
Ajax

0

Spring Bootの裏側から、カスタムBasicAuthenticationEntryPointを使用しました。

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().authorizeRequests()
            ...
            .antMatchers(PUBLIC_AUTH).permitAll()
            .and().httpBasic()
//    https://www.baeldung.com/spring-security-basic-authentication
            .authenticationEntryPoint(authBasicAuthenticationEntryPoint())
            ...

@Bean
public BasicAuthenticationEntryPoint authBasicAuthenticationEntryPoint() {
    return new BasicAuthenticationEntryPoint() {
        {
            setRealmName("pirsApp");
        }

        @Override
        public void commence
                (HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
                throws IOException, ServletException {
            if (request.getRequestURI().equals(PUBLIC_AUTH)) {
                response.sendError(HttpStatus.PRECONDITION_FAILED.value(), "Wrong credentials");
            } else {
                super.commence(request, response, authEx);
            }
        }
    };
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.