基本認証を使用して承認リクエストを送信する必要があります。jqueryを使用してこれを正常に実装しました。ただし、401エラーが発生すると、基本認証ブラウザのポップアップが開き、jquery ajaxエラーコールバックが呼び出されません。
基本認証を使用して承認リクエストを送信する必要があります。jqueryを使用してこれを正常に実装しました。ただし、401エラーが発生すると、基本認証ブラウザのポップアップが開き、jquery ajaxエラーコールバックが呼び出されません。
回答:
私も最近この問題に直面していました。401
(基本認証またはダイジェスト認証)の場合にポップアップを表示するブラウザのデフォルトの動作を変更できないため、これを修正するには2つの方法があります。
401
。200
代わりにコードを返し、jQueryクライアントでこれを処理します。承認に使用しているメソッドをヘッダーのカスタム値に変更します。ブラウザはBasicおよびDigestのポップアップを表示します。クライアントとサーバーの両方でこれを変更する必要があります。
headers : {
"Authorization" : "BasicCustom"
}
基本認証でjQueryを使用する例については、こちらもご覧ください。
<security:http-basic/>
する場合は、定義する必要はありませんが、として定義する必要basicAuthenticationFilter
があります<security:http-basic entry-point-ref="myBasicAuthenticationEntryPoint"/>
。
401
を返すと ポップアップが表示されWWW-Authenticate:Bearer WWW-Authenticate:NTLM WWW-Authenticate:Negotiate
ますが、その理由はわかりますか
一般的な400ステータスコードを返し、そのクライアント側を処理します。
または、401を保持し、WWW-Authenticateヘッダーを返さないようにすることもできます。これは、ブラウザーが実際に認証ポップアップで応答しているヘッダーです。WWW-Authenticateヘッダーがない場合、ブラウザーは資格情報を要求しません。
res.removeHeader('www-authenticate'); // prevents browser from popping up a basic auth window.
次のようなリクエストURLで基本認証ポップアップを抑制できます。
https://username:password@example.com/admin/...
401エラー(ユーザー名またはパスワードの誤り)が発生した場合、jqueryエラーコールバックで正しく処理されます。セキュリティ上の問題が発生する可能性があります(httpsではなくhttpプロトコルの場合)。ただし、問題はありません。
UPD:このソリューションのサポートはChrome 59で削除されます
https://user:pass@host/
2017年6月頃にM59で廃止される予定です。詳しくは、このchromestatusブログの投稿をご覧ください。
他の人が指摘したように、ブラウザの動作を変更する唯一の方法は、応答に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 headers
Apacheを再起動します)
<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>
proxy_hide_header WWW-Authenticate;
X-Requested-With:XMLHttpRequestをリクエストヘッダーと共に使用します。したがって、応答ヘッダーにはWWW-Authenticate:Basicは含まれません。
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', ("Basic "
.concat(btoa(key))));
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
},
IISサーバーを使用している場合は、要求WWW-Authentication
さNone
れたURLのヘッダーをに書き換えるようにIIS URL書き換え(v2)を設定できます。
変更する値はresponse_www_authenticate
です。
さらに情報が必要な場合は、コメントを追加してください。web.configファイルを投稿します。
WWW-Authenticateヘッダーが削除された場合、資格情報のキャッシュが取得されず、リクエストでAuthorizationヘッダーが返されません。つまり、新しいリクエストを生成するたびに認証情報を入力する必要があります。
または、サーバーの応答をカスタマイズできる場合は、403 Forbiddenを返すことができます。
ブラウザーは認証ポップアップを開かず、jqueryコールバックが呼び出されます。
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');
/ login urlを作成します。GETを介して「user」および「password」パラメーターを受け入れ、基本認証を必要としません。ここでは、php、node、javaなどを使用し、passwdファイルを解析して、パラメーター(ユーザー/パス)を照合します。一致する場合は、http:// user:pass@domain.com/にリダイレクトします(これにより、ブラウザーに資格情報が設定されます)ない場合は、401応答(WWW-Authenticateヘッダーなし)を送信します。
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);
}
}
};
}