зеркало из https://github.com/mozilla/gecko-dev.git
Bug 890908 - Move Negotiate auth off main thread. r=mayhemer
--HG-- extra : rebase_source : ca85ad4bb099845b45a276823fe1abca68d384eb
This commit is contained in:
Родитель
d75d9bf8c4
Коммит
f1cd3790fc
|
@ -40,6 +40,10 @@
|
|||
#include "mozilla/Snprintf.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIHttpAuthenticatorCallback.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsICancelable.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -51,6 +55,7 @@ static const char kNegotiateAuthAllowNonFqdn[] = "network.negotiate-auth.allow-n
|
|||
static const char kNegotiateAuthSSPI[] = "network.auth.use-sspi";
|
||||
|
||||
#define kNegotiateLen (sizeof(kNegotiate)-1)
|
||||
#define DEFAULT_THREAD_TIMEOUT_MS 30000
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -184,7 +189,260 @@ nsHttpNegotiateAuth::ChallengeReceived(nsIHttpAuthenticableChannel *authChannel,
|
|||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsHttpNegotiateAuth, nsIHttpAuthenticator)
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
//
|
||||
// GetNextTokenCompleteEvent
|
||||
//
|
||||
// This event is fired on main thread when async call of
|
||||
// nsHttpNegotiateAuth::GenerateCredentials is finished. During the Run()
|
||||
// method the nsIHttpAuthenticatorCallback::OnCredsAvailable is called with
|
||||
// obtained credentials, flags and NS_OK when successful, otherwise
|
||||
// NS_ERROR_FAILURE is returned as a result of failed operation.
|
||||
//
|
||||
class GetNextTokenCompleteEvent final : public nsIRunnable,
|
||||
public nsICancelable
|
||||
{
|
||||
virtual ~GetNextTokenCompleteEvent()
|
||||
{
|
||||
if (mCreds) {
|
||||
free(mCreds);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
explicit GetNextTokenCompleteEvent(nsIHttpAuthenticatorCallback* aCallback)
|
||||
: mCallback(aCallback)
|
||||
, mCreds(nullptr)
|
||||
, mCancelled(false)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DispatchSuccess(char *aCreds,
|
||||
uint32_t aFlags,
|
||||
already_AddRefed<nsISupports> aSessionState,
|
||||
already_AddRefed<nsISupports> aContinuationState)
|
||||
{
|
||||
// Called from worker thread
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
mCreds = aCreds;
|
||||
mFlags = aFlags;
|
||||
mResult = NS_OK;
|
||||
mSessionState = aSessionState;
|
||||
mContinuationState = aContinuationState;
|
||||
return NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DispatchError(already_AddRefed<nsISupports> aSessionState,
|
||||
already_AddRefed<nsISupports> aContinuationState)
|
||||
{
|
||||
// Called from worker thread
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
mResult = NS_ERROR_FAILURE;
|
||||
mSessionState = aSessionState;
|
||||
mContinuationState = aContinuationState;
|
||||
return NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Run() override
|
||||
{
|
||||
// Runs on main thread
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mCancelled) {
|
||||
nsCOMPtr<nsIHttpAuthenticatorCallback> callback;
|
||||
callback.swap(mCallback);
|
||||
callback->OnCredsGenerated(mCreds, mFlags, mResult, mSessionState, mContinuationState);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Cancel(nsresult aReason) override
|
||||
{
|
||||
// Supposed to be called from main thread
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mCancelled = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIHttpAuthenticatorCallback> mCallback;
|
||||
char *mCreds; // This class owns it, freed in destructor
|
||||
uint32_t mFlags;
|
||||
nsresult mResult;
|
||||
bool mCancelled;
|
||||
nsCOMPtr<nsISupports> mSessionState;
|
||||
nsCOMPtr<nsISupports> mContinuationState;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(GetNextTokenCompleteEvent, nsIRunnable, nsICancelable)
|
||||
|
||||
//
|
||||
// GetNextTokenRunnable
|
||||
//
|
||||
// This runnable is created by GenerateCredentialsAsync and it runs
|
||||
// in nsHttpNegotiateAuth::mNegotiateThread and calling GenerateCredentials.
|
||||
//
|
||||
class GetNextTokenRunnable final : public mozilla::Runnable
|
||||
{
|
||||
virtual ~GetNextTokenRunnable() {}
|
||||
public:
|
||||
GetNextTokenRunnable(nsIHttpAuthenticableChannel *authChannel,
|
||||
const char *challenge,
|
||||
bool isProxyAuth,
|
||||
const char16_t *domain,
|
||||
const char16_t *username,
|
||||
const char16_t *password,
|
||||
nsISupports *sessionState,
|
||||
nsISupports *continuationState,
|
||||
GetNextTokenCompleteEvent *aCompleteEvent
|
||||
)
|
||||
: mAuthChannel(authChannel)
|
||||
, mChallenge(challenge)
|
||||
, mIsProxyAuth(isProxyAuth)
|
||||
, mDomain(domain)
|
||||
, mUsername(username)
|
||||
, mPassword(password)
|
||||
, mSessionState(sessionState)
|
||||
, mContinuationState(continuationState)
|
||||
, mCompleteEvent(aCompleteEvent)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Run() override
|
||||
{
|
||||
// Runs on worker thread
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
char *creds;
|
||||
uint32_t flags;
|
||||
nsresult rv = ObtainCredentialsAndFlags(&creds, &flags);
|
||||
|
||||
// Passing session and continuation state this way to not touch
|
||||
// referencing of the object that may not be thread safe.
|
||||
// Not having a thread safe referencing doesn't mean the object
|
||||
// cannot be used on multiple threads (one example is nsAuthSSPI.)
|
||||
// This ensures state objects will be destroyed on the main thread
|
||||
// when not changed by GenerateCredentials.
|
||||
if (NS_FAILED(rv)) {
|
||||
return mCompleteEvent->DispatchError(mSessionState.forget(),
|
||||
mContinuationState.forget());
|
||||
}
|
||||
|
||||
return mCompleteEvent->DispatchSuccess(creds, flags,
|
||||
mSessionState.forget(),
|
||||
mContinuationState.forget());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ObtainCredentialsAndFlags(char **aCreds, uint32_t *aFlags)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Use negotiate service to call GenerateCredentials outside of main thread
|
||||
nsAutoCString contractId;
|
||||
contractId.Assign(NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX);
|
||||
contractId.Append("negotiate");
|
||||
nsCOMPtr<nsIHttpAuthenticator> authenticator =
|
||||
do_GetService(contractId.get(), &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsISupports *sessionState = mSessionState;
|
||||
nsISupports *continuationState = mContinuationState;
|
||||
// The continuationState is for the sake of completeness propagated
|
||||
// to the caller (despite it is not changed in any GenerateCredentials
|
||||
// implementation).
|
||||
//
|
||||
// The only implementation that use sessionState is the
|
||||
// nsHttpDigestAuth::GenerateCredentials. Since there's no reason
|
||||
// to implement nsHttpDigestAuth::GenerateCredentialsAsync
|
||||
// because digest auth does not block the main thread, we won't
|
||||
// propagate changes to sessionState to the caller because of
|
||||
// the change is too complicated on the caller side.
|
||||
//
|
||||
// Should any of the session or continuation states change inside
|
||||
// this method, they must be threadsafe.
|
||||
rv = authenticator->GenerateCredentials(mAuthChannel,
|
||||
mChallenge.get(),
|
||||
mIsProxyAuth,
|
||||
mDomain.get(),
|
||||
mUsername.get(),
|
||||
mPassword.get(),
|
||||
&sessionState,
|
||||
&continuationState,
|
||||
aFlags,
|
||||
aCreds);
|
||||
if (mSessionState != sessionState) {
|
||||
mSessionState = sessionState;
|
||||
}
|
||||
if (mContinuationState != continuationState) {
|
||||
mContinuationState = continuationState;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
private:
|
||||
nsCOMPtr<nsIHttpAuthenticableChannel> mAuthChannel;
|
||||
nsCString mChallenge;
|
||||
bool mIsProxyAuth;
|
||||
nsString mDomain;
|
||||
nsString mUsername;
|
||||
nsString mPassword;
|
||||
nsCOMPtr<nsISupports> mSessionState;
|
||||
nsCOMPtr<nsISupports> mContinuationState;
|
||||
RefPtr<GetNextTokenCompleteEvent> mCompleteEvent;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpNegotiateAuth::GenerateCredentialsAsync(nsIHttpAuthenticableChannel *authChannel,
|
||||
nsIHttpAuthenticatorCallback* aCallback,
|
||||
const char *challenge,
|
||||
bool isProxyAuth,
|
||||
const char16_t *domain,
|
||||
const char16_t *username,
|
||||
const char16_t *password,
|
||||
nsISupports *sessionState,
|
||||
nsISupports *continuationState,
|
||||
nsICancelable **aCancelable)
|
||||
{
|
||||
NS_ENSURE_ARG(aCallback);
|
||||
NS_ENSURE_ARG_POINTER(aCancelable);
|
||||
|
||||
RefPtr<GetNextTokenCompleteEvent> cancelEvent =
|
||||
new GetNextTokenCompleteEvent(aCallback);
|
||||
|
||||
|
||||
nsCOMPtr<nsIRunnable> getNextTokenRunnable =
|
||||
new GetNextTokenRunnable(authChannel,
|
||||
challenge,
|
||||
isProxyAuth,
|
||||
domain,
|
||||
username,
|
||||
password,
|
||||
sessionState,
|
||||
continuationState,
|
||||
cancelEvent);
|
||||
cancelEvent.forget(aCancelable);
|
||||
|
||||
nsresult rv;
|
||||
if (!mNegotiateThread) {
|
||||
mNegotiateThread =
|
||||
new mozilla::LazyIdleThread(DEFAULT_THREAD_TIMEOUT_MS,
|
||||
NS_LITERAL_CSTRING("NegotiateAuth"));
|
||||
NS_ENSURE_TRUE(mNegotiateThread, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
rv = mNegotiateThread->Dispatch(getNextTokenRunnable, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// GenerateCredentials
|
||||
//
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsSubstring.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/LazyIdleThread.h"
|
||||
|
||||
// The nsHttpNegotiateAuth class provides responses for the GSS-API Negotiate method
|
||||
// as specified by Microsoft in draft-brezak-spnego-http-04.txt
|
||||
|
@ -17,7 +18,7 @@
|
|||
class nsHttpNegotiateAuth final : public nsIHttpAuthenticator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIHTTPAUTHENTICATOR
|
||||
|
||||
private:
|
||||
|
@ -37,5 +38,7 @@ private:
|
|||
int32_t port,
|
||||
const char *baseStart,
|
||||
const char *baseEnd);
|
||||
// Thread for GenerateCredentialsAsync
|
||||
RefPtr<mozilla::LazyIdleThread> mNegotiateThread;
|
||||
};
|
||||
#endif /* nsHttpNegotiateAuth_h__ */
|
||||
|
|
|
@ -48,6 +48,7 @@ XPIDL_SOURCES += [
|
|||
'nsIFileURL.idl',
|
||||
'nsIForcePendingChannel.idl',
|
||||
'nsIFormPOSTActionChannel.idl',
|
||||
'nsIHttpAuthenticatorCallback.idl',
|
||||
'nsIHttpPushListener.idl',
|
||||
'nsIIncrementalDownload.idl',
|
||||
'nsIIncrementalStreamLoader.idl',
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(d989cb03-e446-4086-b9e6-46842cb97bd5)]
|
||||
interface nsIHttpAuthenticatorCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
* Authentication data for a header is available.
|
||||
*
|
||||
* @param aCreds
|
||||
* Credentials which were obtained asynchonously.
|
||||
* @param aFlags
|
||||
* Flags set by asynchronous call.
|
||||
* @param aResult
|
||||
* Result status of credentials generation
|
||||
* @param aSessionState
|
||||
* Modified session state to be passed to caller
|
||||
* @param aContinuationState
|
||||
* Modified continuation state to be passed to caller
|
||||
*/
|
||||
void onCredsGenerated(in string aCreds,
|
||||
in unsigned long aFlags,
|
||||
in nsresult aResult,
|
||||
in nsISupports aSessionsState,
|
||||
in nsISupports aContinuationState);
|
||||
|
||||
};
|
||||
|
|
@ -49,6 +49,20 @@ nsHttpBasicAuth::ChallengeReceived(nsIHttpAuthenticableChannel *authChannel,
|
|||
*identityInvalid = true;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsHttpBasicAuth::GenerateCredentialsAsync(nsIHttpAuthenticableChannel *authChannel,
|
||||
nsIHttpAuthenticatorCallback* aCallback,
|
||||
const char *challenge,
|
||||
bool isProxyAuth,
|
||||
const char16_t *domain,
|
||||
const char16_t *username,
|
||||
const char16_t *password,
|
||||
nsISupports *sessionState,
|
||||
nsISupports *continuationState,
|
||||
nsICancelable **aCancellable)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpBasicAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
|
||||
|
|
|
@ -278,6 +278,11 @@ nsHttpChannelAuthProvider::Cancel(nsresult status)
|
|||
mAsyncPromptAuthCancelable->Cancel(status);
|
||||
mAsyncPromptAuthCancelable = nullptr;
|
||||
}
|
||||
|
||||
if (mGenerateCredentialsCancelable) {
|
||||
mGenerateCredentialsCancelable->Cancel(status);
|
||||
mGenerateCredentialsCancelable = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -291,6 +296,11 @@ nsHttpChannelAuthProvider::Disconnect(nsresult status)
|
|||
mAsyncPromptAuthCancelable = nullptr;
|
||||
}
|
||||
|
||||
if (mGenerateCredentialsCancelable) {
|
||||
mGenerateCredentialsCancelable->Cancel(status);
|
||||
mGenerateCredentialsCancelable = nullptr;
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(mProxyAuthContinuationState);
|
||||
NS_IF_RELEASE(mAuthContinuationState);
|
||||
|
||||
|
@ -366,11 +376,6 @@ nsHttpChannelAuthProvider::GenCredsAndSetEntry(nsIHttpAuthenticator *auth,
|
|||
char **result)
|
||||
{
|
||||
nsresult rv;
|
||||
uint32_t authFlags;
|
||||
|
||||
rv = auth->GetAuthFlags(&authFlags);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsISupports *ss = sessionState;
|
||||
|
||||
// set informations that depend on whether
|
||||
|
@ -384,6 +389,22 @@ nsHttpChannelAuthProvider::GenCredsAndSetEntry(nsIHttpAuthenticator *auth,
|
|||
continuationState = &mAuthContinuationState;
|
||||
}
|
||||
|
||||
rv = auth->GenerateCredentialsAsync(mAuthChannel,
|
||||
this,
|
||||
challenge,
|
||||
proxyAuth,
|
||||
ident.Domain(),
|
||||
ident.User(),
|
||||
ident.Password(),
|
||||
ss,
|
||||
*continuationState,
|
||||
getter_AddRefs(mGenerateCredentialsCancelable));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Calling generate credentials async, results will be dispatched to the
|
||||
// main thread by calling OnCredsGenerated method
|
||||
return NS_ERROR_IN_PROGRESS;
|
||||
}
|
||||
|
||||
uint32_t generateFlags;
|
||||
rv = auth->GenerateCredentials(mAuthChannel,
|
||||
challenge,
|
||||
|
@ -404,6 +425,29 @@ nsHttpChannelAuthProvider::GenCredsAndSetEntry(nsIHttpAuthenticator *auth,
|
|||
LOG(("generated creds: %s\n", *result));
|
||||
#endif
|
||||
|
||||
return UpdateCache(auth, scheme, host, port, directory, realm,
|
||||
challenge, ident, *result, generateFlags, sessionState);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpChannelAuthProvider::UpdateCache(nsIHttpAuthenticator *auth,
|
||||
const char *scheme,
|
||||
const char *host,
|
||||
int32_t port,
|
||||
const char *directory,
|
||||
const char *realm,
|
||||
const char *challenge,
|
||||
const nsHttpAuthIdentity &ident,
|
||||
const char *creds,
|
||||
uint32_t generateFlags,
|
||||
nsISupports *sessionState)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
uint32_t authFlags;
|
||||
rv = auth->GetAuthFlags(&authFlags);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// find out if this authenticator allows reuse of credentials and/or
|
||||
// challenge.
|
||||
bool saveCreds =
|
||||
|
@ -421,6 +465,7 @@ nsHttpChannelAuthProvider::GenCredsAndSetEntry(nsIHttpAuthenticator *auth,
|
|||
nsAutoCString suffix;
|
||||
GetOriginAttributesSuffix(chan, suffix);
|
||||
|
||||
|
||||
// create a cache entry. we do this even though we don't yet know that
|
||||
// these credentials are valid b/c we need to avoid prompting the user
|
||||
// more than once in case the credentials are valid.
|
||||
|
@ -428,12 +473,13 @@ nsHttpChannelAuthProvider::GenCredsAndSetEntry(nsIHttpAuthenticator *auth,
|
|||
// if the credentials are not reusable, then we don't bother sticking
|
||||
// them in the auth cache.
|
||||
rv = authCache->SetAuthEntry(scheme, host, port, directory, realm,
|
||||
saveCreds ? *result : nullptr,
|
||||
saveCreds ? creds : nullptr,
|
||||
saveChallenge ? challenge : nullptr,
|
||||
suffix,
|
||||
saveIdentity ? &ident : nullptr,
|
||||
sessionState);
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1271,6 +1317,63 @@ NS_IMETHODIMP nsHttpChannelAuthProvider::OnAuthCancelled(nsISupports *aContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHttpChannelAuthProvider::OnCredsGenerated(const char *aGeneratedCreds,
|
||||
uint32_t aFlags,
|
||||
nsresult aResult,
|
||||
nsISupports* aSessionState,
|
||||
nsISupports* aContinuationState)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// When channel is closed, do not proceed
|
||||
if (!mAuthChannel) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mGenerateCredentialsCancelable = nullptr;
|
||||
|
||||
if (NS_FAILED(aResult)) {
|
||||
return OnAuthCancelled(nullptr, true);
|
||||
}
|
||||
|
||||
// We want to update m(Proxy)AuthContinuationState in case it was changed by
|
||||
// nsHttpNegotiateAuth::GenerateCredentials
|
||||
nsCOMPtr<nsISupports> contState(aContinuationState);
|
||||
if (mProxyAuth) {
|
||||
contState.swap(mProxyAuthContinuationState);
|
||||
} else {
|
||||
contState.swap(mAuthContinuationState);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHttpAuthenticator> auth;
|
||||
nsAutoCString unused;
|
||||
rv = GetAuthenticator(mCurrentChallenge.get(), unused, getter_AddRefs(auth));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
const char *host;
|
||||
int32_t port;
|
||||
nsHttpAuthIdentity *ident;
|
||||
nsAutoCString directory, scheme;
|
||||
nsISupports **unusedContinuationState;
|
||||
|
||||
// Get realm from challenge
|
||||
nsAutoCString realm;
|
||||
ParseRealm(mCurrentChallenge.get(), realm);
|
||||
|
||||
rv = GetAuthorizationMembers(mProxyAuth, scheme, host, port,
|
||||
directory, ident, unusedContinuationState);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
UpdateCache(auth, scheme.get(), host, port, directory.get(), realm.get(),
|
||||
mCurrentChallenge.get(), *ident, aGeneratedCreds, aFlags, aSessionState);
|
||||
mCurrentChallenge.Truncate();
|
||||
|
||||
ContinueOnAuthAvailable(nsDependentCString(aGeneratedCreds));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpChannelAuthProvider::ContinueOnAuthAvailable(const nsCSubstring& creds)
|
||||
{
|
||||
|
@ -1505,7 +1608,7 @@ nsHttpChannelAuthProvider::GetCurrentPath(nsACString &path)
|
|||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsHttpChannelAuthProvider, nsICancelable,
|
||||
nsIHttpChannelAuthProvider, nsIAuthPromptCallback)
|
||||
nsIHttpChannelAuthProvider, nsIAuthPromptCallback, nsIHttpAuthenticatorCallback)
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -9,11 +9,13 @@
|
|||
|
||||
#include "nsIHttpChannelAuthProvider.h"
|
||||
#include "nsIAuthPromptCallback.h"
|
||||
#include "nsIHttpAuthenticatorCallback.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsHttpAuthCache.h"
|
||||
#include "nsProxyInfo.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsICancelableRunnable.h"
|
||||
|
||||
class nsIHttpAuthenticableChannel;
|
||||
class nsIHttpAuthenticator;
|
||||
|
@ -25,12 +27,14 @@ class nsHttpHandler;
|
|||
|
||||
class nsHttpChannelAuthProvider : public nsIHttpChannelAuthProvider
|
||||
, public nsIAuthPromptCallback
|
||||
, public nsIHttpAuthenticatorCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICANCELABLE
|
||||
NS_DECL_NSIHTTPCHANNELAUTHPROVIDER
|
||||
NS_DECL_NSIAUTHPROMPTCALLBACK
|
||||
NS_DECL_NSIHTTPAUTHENTICATORCALLBACK
|
||||
|
||||
nsHttpChannelAuthProvider();
|
||||
static void InitializePrefs();
|
||||
|
@ -117,6 +121,19 @@ private:
|
|||
// For more details look at the bug 647010.
|
||||
bool BlockPrompt();
|
||||
|
||||
// Store credentials to the cache when appropriate aFlags are set.
|
||||
nsresult UpdateCache(nsIHttpAuthenticator *aAuth,
|
||||
const char *aScheme,
|
||||
const char *aHost,
|
||||
int32_t aPort,
|
||||
const char *aDirectory,
|
||||
const char *aRealm,
|
||||
const char *aChallenge,
|
||||
const nsHttpAuthIdentity &aIdent,
|
||||
const char *aCreds,
|
||||
uint32_t aGenerateFlags,
|
||||
nsISupports *aSessionState);
|
||||
|
||||
private:
|
||||
nsIHttpAuthenticableChannel *mAuthChannel; // weak ref
|
||||
|
||||
|
@ -164,6 +181,7 @@ private:
|
|||
// authentication credentials dialogs for sub-resources and cross-origin
|
||||
// sub-resources.
|
||||
static uint32_t sAuthAllowPref;
|
||||
nsCOMPtr<nsICancelable> mGenerateCredentialsCancelable;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -158,6 +158,22 @@ nsHttpDigestAuth::ChallengeReceived(nsIHttpAuthenticableChannel *authChannel,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpDigestAuth::GenerateCredentialsAsync(nsIHttpAuthenticableChannel *authChannel,
|
||||
nsIHttpAuthenticatorCallback* aCallback,
|
||||
const char *challenge,
|
||||
bool isProxyAuth,
|
||||
const char16_t *domain,
|
||||
const char16_t *username,
|
||||
const char16_t *password,
|
||||
nsISupports *sessionState,
|
||||
nsISupports *continuationState,
|
||||
nsICancelable **aCancellable)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpDigestAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
|
||||
const char *challenge,
|
||||
|
|
|
@ -332,6 +332,21 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHttpAuthenticableChannel *channel,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpNTLMAuth::GenerateCredentialsAsync(nsIHttpAuthenticableChannel *authChannel,
|
||||
nsIHttpAuthenticatorCallback* aCallback,
|
||||
const char *challenge,
|
||||
bool isProxyAuth,
|
||||
const char16_t *domain,
|
||||
const char16_t *username,
|
||||
const char16_t *password,
|
||||
nsISupports *sessionState,
|
||||
nsISupports *continuationState,
|
||||
nsICancelable **aCancellable)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpNTLMAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
|
||||
const char *challenge,
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIHttpAuthenticableChannel;
|
||||
interface nsIHttpAuthenticatorCallback;
|
||||
interface nsICancelable;
|
||||
|
||||
/**
|
||||
* nsIHttpAuthenticator
|
||||
|
@ -18,7 +20,7 @@ interface nsIHttpAuthenticableChannel;
|
|||
* where <auth-scheme> is the lower-cased value of the authentication scheme
|
||||
* found in the server challenge per the rules of RFC 2617.
|
||||
*/
|
||||
[scriptable, uuid(16784db0-fcb1-4352-b0c9-6a3a67e3cf79)]
|
||||
[scriptable, uuid(fef7db8a-a4e2-49d1-9685-19ed7e309b7d)]
|
||||
interface nsIHttpAuthenticator : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -52,6 +54,54 @@ interface nsIHttpAuthenticator : nsISupports
|
|||
inout nsISupports aContinuationState,
|
||||
out boolean aInvalidatesIdentity);
|
||||
|
||||
/**
|
||||
* Called to generate the authentication credentials for a particular
|
||||
* server/proxy challenge asynchronously. Credentials will be sent back
|
||||
* to the server via an Authorization/Proxy-Authorization header.
|
||||
*
|
||||
* @param aChannel
|
||||
* the http channel requesting credentials
|
||||
* @param aCallback
|
||||
* callback function to be called when credentials are available
|
||||
* @param aChallenge
|
||||
* the challenge from the WWW-Authenticate/Proxy-Authenticate
|
||||
* server response header. (possibly from the auth cache.)
|
||||
* @param aProxyAuth
|
||||
* flag indicating whether or not aChallenge is from a proxy.
|
||||
* @param aDomain
|
||||
* string containing the domain name (if appropriate)
|
||||
* @param aUser
|
||||
* string containing the user name
|
||||
* @param aPassword
|
||||
* string containing the password
|
||||
* @param aSessionState
|
||||
* state stored along side the user's identity in the auth cache
|
||||
* for the lifetime of the browser session. if a new auth cache
|
||||
* entry is created for this challenge, then this parameter will
|
||||
* be null. on return, the result will be stored in the new auth
|
||||
* cache entry. this parameter is non-null when an auth cache entry
|
||||
* is being reused. currently modification of session state is not
|
||||
* communicated to caller, thus caching credentials obtained by
|
||||
* asynchronous way is not supported.
|
||||
* @param aContinuationState
|
||||
* state held by the channel between consecutive calls to
|
||||
* generateCredentials, assuming multiple calls are required
|
||||
* to authenticate. this state is held for at most the lifetime of
|
||||
* the channel.
|
||||
* @pram aCancel
|
||||
* returns cancellable runnable object which caller can use to cancel
|
||||
* calling aCallback when finished.
|
||||
*/
|
||||
void generateCredentialsAsync(in nsIHttpAuthenticableChannel aChannel,
|
||||
in nsIHttpAuthenticatorCallback aCallback,
|
||||
in string aChallenge,
|
||||
in boolean aProxyAuth,
|
||||
in wstring aDomain,
|
||||
in wstring aUser,
|
||||
in wstring aPassword,
|
||||
in nsISupports aSessionState,
|
||||
in nsISupports aContinuationState,
|
||||
out nsICancelable aCancel);
|
||||
/**
|
||||
* Called to generate the authentication credentials for a particular
|
||||
* server/proxy challenge. This is the value that will be sent back
|
||||
|
|
Загрузка…
Ссылка в новой задаче