Saya perlu mengirim permintaan otorisasi menggunakan autentikasi dasar. Saya telah berhasil menerapkan ini menggunakan jquery. Namun ketika saya mendapatkan error 401, popup browser auth dasar dibuka dan callback error ajax jquery tidak dipanggil.
Saya perlu mengirim permintaan otorisasi menggunakan autentikasi dasar. Saya telah berhasil menerapkan ini menggunakan jquery. Namun ketika saya mendapatkan error 401, popup browser auth dasar dibuka dan callback error ajax jquery tidak dipanggil.
Jawaban:
Saya juga menghadapi masalah ini baru-baru ini. Karena Anda tidak dapat mengubah perilaku default browser untuk menampilkan munculan dalam kasus 401
( otentikasi dasar atau intisari ), ada dua cara untuk memperbaikinya:
401
. Kembalikan 200
kode sebagai gantinya dan tangani ini di klien jQuery Anda.Ubah metode yang Anda gunakan untuk otorisasi menjadi nilai khusus di header Anda. Browser akan menampilkan popup untuk Basic dan Intisari . Anda harus mengubah ini pada klien dan server.
headers : {
"Authorization" : "BasicCustom"
}
Silakan lihat ini juga untuk contoh penggunaan jQuery dengan Basic Auth.
<security:http-basic/>
Anda tidak perlu mendefinisikan basicAuthenticationFilter
tetapi harus mendefinisikannya sebagai <security:http-basic entry-point-ref="myBasicAuthenticationEntryPoint"/>
.
401
dan WWW-Authenticate:Bearer WWW-Authenticate:NTLM WWW-Authenticate:Negotiate
Apakah Anda tahu mengapa itu terjadi
Kembalikan kode status 400 generik, dan kemudian proses sisi klien tersebut.
Atau Anda dapat menyimpan 401, dan tidak mengembalikan header WWW-Authenticate, yang sebenarnya merupakan respons browser dengan popup otentikasi. Jika header WWW-Authenticate hilang, browser tidak akan meminta kredensial.
res.removeHeader('www-authenticate'); // prevents browser from popping up a basic auth window.
Anda dapat menyembunyikan munculan autentikasi dasar dengan url permintaan yang terlihat seperti ini:
https://username:password@example.com/admin/...
Jika Anda mendapatkan kesalahan 401 (nama pengguna atau kata sandi salah) itu akan ditangani dengan benar dengan panggilan balik kesalahan jquery. Ini dapat menyebabkan beberapa masalah keamanan (dalam kasus protokol http, bukan https), tetapi berfungsi.
UPD: Dukungan solusi ini akan dihapus di Chrome 59
https://user:pass@host/
di M59 sekitar Juni 2017. Lihat entri blog chromestatus ini untuk info lebih lanjut.
Seperti yang ditunjukkan orang lain, satu-satunya cara untuk mengubah perilaku browser adalah memastikan respons tidak berisi kode status 401 atau jika ya, tidak menyertakan WWW-Authenticate: Basic
header. Karena mengubah kode status sangat tidak semantik dan tidak diinginkan, pendekatan yang baik adalah dengan menghapus WWW-Authenticate
header. Jika Anda tidak dapat atau tidak ingin mengubah aplikasi server web Anda, Anda selalu dapat melayani atau mem-proxy-nya melalui Apache (jika Anda belum menggunakan Apache).
Berikut adalah konfigurasi bagi Apache untuk menulis ulang respons untuk menghapus header WWW-Authenticate IFF yang berisi permintaan berisi header X-Requested-With: XMLHttpRequest
(yang disetel secara default oleh kerangka kerja Javascript utama seperti JQuery / AngularJS, dll ...) DAN respons berisi header WWW-Authenticate: Basic
.
Diuji pada Apache 2.4 (tidak yakin apakah berfungsi dengan 2.2). Ini bergantung pada mod_headers
modul yang dipasang. (Di Debian / Ubuntu, sudo a2enmod headers
dan mulai ulang 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;
Gunakan X-Requested-With: XMLHttpRequest dengan header permintaan Anda. Jadi header respons tidak akan berisi WWW-Authenticate: Basic.
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', ("Basic "
.concat(btoa(key))));
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
},
Jika Anda menggunakan Server IIS, Anda dapat mengatur IIS URL Rewriting (v2) untuk menulis ulang WWW-Authentication
header ke None
pada URL yang diminta.
Nilai yang ingin Anda ubah adalah response_www_authenticate
.
Jika Anda membutuhkan info lebih lanjut, tambahkan komentar dan saya akan memposting file web.config.
Jika header WWW-Authenticate dihapus, maka Anda tidak akan mendapatkan caching kredensial dan tidak akan mendapatkan kembali header Otorisasi sesuai permintaan. Itu berarti sekarang Anda harus memasukkan kredensial untuk setiap permintaan baru yang Anda buat.
Atau, jika Anda dapat menyesuaikan respons server, Anda dapat mengembalikan 403 Forbidden.
Browser tidak akan membuka popup otentikasi dan jquery callback akan dipanggil.
Di Safari, Anda dapat menggunakan permintaan sinkron untuk menghindari browser menampilkan popup. Tentu saja, permintaan sinkron hanya boleh digunakan dalam kasus ini untuk memeriksa kredensial pengguna ... Anda dapat menggunakan permintaan tersebut sebelum mengirim permintaan sebenarnya yang dapat menyebabkan pengalaman pengguna yang buruk jika konten (dikirim atau diterima) cukup berat.
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');
Buat / login url, lalu terima parameter "user" dan "password" melalui GET dan tidak memerlukan autentikasi dasar. Di sini, gunakan php, node, java, apapun dan parsing file passwd Anda dan cocokkan parameter (user / pass) terhadapnya. Jika ada kecocokan maka redirect ke http: // user: pass@domain.com/ (ini akan mengatur kredensial pada browser Anda) jika tidak, kirim respon 401 (tanpa header WWW-Authenticate).
Dari sisi belakang dengan Spring Boot, saya telah menggunakan BasicAuthenticationEntryPoint kustom:
@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);
}
}
};
}