Bug 282547 - [XHR] Login dialog with wrong XMLHttpRequest authentication. r=bz

This commit is contained in:
Andrea Marchesini 2012-10-07 07:40:10 -04:00
parent 0e8bef661b
commit 348e42f142
4 changed files with 210 additions and 0 deletions

View File

@ -281,6 +281,70 @@ nsMultipartProxyListener::OnDataAvailable(nsIRequest *aRequest,
count); count);
} }
//-----------------------------------------------------------------------------
// XMLHttpRequestAuthPrompt
//-----------------------------------------------------------------------------
class XMLHttpRequestAuthPrompt : public nsIAuthPrompt
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIAUTHPROMPT
XMLHttpRequestAuthPrompt();
virtual ~XMLHttpRequestAuthPrompt();
};
NS_IMPL_ISUPPORTS1(XMLHttpRequestAuthPrompt, nsIAuthPrompt)
XMLHttpRequestAuthPrompt::XMLHttpRequestAuthPrompt()
{
MOZ_COUNT_CTOR(XMLHttpRequestAuthPrompt);
}
XMLHttpRequestAuthPrompt::~XMLHttpRequestAuthPrompt()
{
MOZ_COUNT_DTOR(XMLHttpRequestAuthPrompt);
}
NS_IMETHODIMP
XMLHttpRequestAuthPrompt::Prompt(const PRUnichar* aDialogTitle,
const PRUnichar* aText,
const PRUnichar* aPasswordRealm,
uint32_t aSavePassword,
const PRUnichar* aDefaultText,
PRUnichar** aResult,
bool* aRetval)
{
*aRetval = false;
return NS_OK;
}
NS_IMETHODIMP
XMLHttpRequestAuthPrompt::PromptUsernameAndPassword(const PRUnichar* aDialogTitle,
const PRUnichar* aDialogText,
const PRUnichar* aPasswordRealm,
uint32_t aSavePassword,
PRUnichar** aUser,
PRUnichar** aPwd,
bool* aRetval)
{
*aRetval = false;
return NS_OK;
}
NS_IMETHODIMP
XMLHttpRequestAuthPrompt::PromptPassword(const PRUnichar* aDialogTitle,
const PRUnichar* aText,
const PRUnichar* aPasswordRealm,
uint32_t aSavePassword,
PRUnichar** aPwd,
bool* aRetval)
{
*aRetval = false;
return NS_OK;
}
///////////////////////////////////////////// /////////////////////////////////////////////
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget) NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget)
@ -3751,6 +3815,57 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
} }
else if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)) || else if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)) ||
aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) { aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) {
nsCOMPtr<nsIURI> uri;
rv = mChannel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
// Verify that it's ok to prompt for credentials here, per spec
// http://xhr.spec.whatwg.org/#the-send%28%29-method
bool showPrompt = true;
// If authentication fails, XMLHttpRequest origin and
// the request URL are same origin, ...
if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
showPrompt = false;
}
// ... Authorization is not in the list of author request headers, ...
if (showPrompt) {
for (uint32_t i = 0, len = mModifiedRequestHeaders.Length(); i < len; ++i) {
if (mModifiedRequestHeaders[i].header.
LowerCaseEqualsLiteral("authorization")) {
showPrompt = false;
break;
}
}
}
// ... request username is null, and request password is null,
if (showPrompt) {
nsCString username;
rv = uri->GetUsername(username);
NS_ENSURE_SUCCESS(rv, rv);
nsCString password;
rv = uri->GetPassword(password);
NS_ENSURE_SUCCESS(rv, rv);
if (!username.IsEmpty() || !password.IsEmpty()) {
showPrompt = false;
}
}
// ... user agents should prompt the end user for their username and password.
if (!showPrompt) {
nsRefPtr<XMLHttpRequestAuthPrompt> prompt = new XMLHttpRequestAuthPrompt();
if (!prompt)
return NS_ERROR_OUT_OF_MEMORY;
return prompt->QueryInterface(aIID, aResult);
}
nsCOMPtr<nsIPromptFactory> wwatch = nsCOMPtr<nsIPromptFactory> wwatch =
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);

View File

@ -264,6 +264,8 @@ MOCHITEST_FILES_A = \
test_bug744830.html \ test_bug744830.html \
file_bug782342.txt \ file_bug782342.txt \
test_bug782342.html \ test_bug782342.html \
test_bug282547.html \
bug282547.sjs \
$(NULL) $(NULL)
MOCHITEST_FILES_B = \ MOCHITEST_FILES_B = \

View File

@ -0,0 +1,5 @@
function handleRequest(request, response)
{
response.setStatusLine(null, 401, "Unauthorized");
response.setHeader("WWW-Authenticate", "basic realm=\"restricted\"", false);
}

View File

@ -0,0 +1,88 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=282547
-->
<head>
<title>Test for Bug 282547</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=282547">Mozilla Bug 282547</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<script class="testbody" type="text/javascript">
function xhr_userpass_sync() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'bug282547.sjs', false, 'username', 'password');
xhr.send(null);
ok(xhr.status == 401, "Status 401");
runTests();
}
function xhr_userpass_async() {
xhr = new XMLHttpRequest();
xhr.open('GET', 'bug282547.sjs', true, 'username', 'password');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
ok(xhr.status == 401, "Status 401");
runTests();
}
}
xhr.send(null);
}
function xhr_auth_header_sync() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'bug282547.sjs', false);
xhr.setRequestHeader("Authorization", "42");
xhr.send(null);
ok(xhr.status == 401, "Status 401");
runTests();
}
function xhr_auth_header_async() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'bug282547.sjs', true);
xhr.setRequestHeader("Authorization", "42");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
ok(xhr.status == 401, "Status 401");
runTests();
}
}
xhr.send(null);
}
var tests = [ xhr_userpass_sync,
xhr_userpass_async,
xhr_auth_header_sync,
xhr_auth_header_async ];
function runTests() {
if (!tests.length) {
SimpleTest.finish();
return;
}
var test = tests.shift();
test();
}
runTests();
SimpleTest.waitForExplicitFinish();
</script>
</body>
</html>