Necko:nsIAuthPrompt2: Difference between revisions
mNo edit summary |
(update per final changes) |
||
(22 intermediate revisions by the same user not shown) | |||
Line 12: | Line 12: | ||
The nsIAuthPrompt2 is what necko calls stuff on; nsIPromptService2 is what embeddors would implement. | The nsIAuthPrompt2 is what necko calls stuff on; nsIPromptService2 is what embeddors would implement. | ||
This suggestion is based on https://bugzilla.mozilla.org/attachment.cgi?id=163161 but slightly modified. | This suggestion is based on https://bugzilla.mozilla.org/attachment.cgi?id=163161 but slightly modified, and async calls added. | ||
/** | |||
* A object that hold authentication information. The caller of | |||
* nsIAuthPrompt2::promptUsernameAndPassword or | |||
* nsIAuthPrompt2::promptPasswordAsync provides an object implementing this | |||
* interface; the prompt implementation can then read the values here to prefill | |||
* the dialog. After the user entered the authentication information, it should | |||
* set the attributes of this object to indicate to the caller what was entered | |||
* by the user. | |||
*/ | |||
[scriptable, uuid(0d73639c-2a92-4518-9f92-28f71fea5f20)] | |||
interface nsIAuthInformation : nsISupports | |||
{ | |||
/** @name Flags */ | |||
/* @{ */ | |||
/** | |||
* This dialog belongs to a network host. | |||
*/ | |||
const PRUint32 AUTH_HOST = 1; | |||
/** | |||
* This dialog belongs to a proxy. | |||
*/ | |||
const PRUint32 AUTH_PROXY = 2; | |||
/** | |||
* This dialog needs domain information. The user interface should show a | |||
* domain field, prefilled with the domain attribute's value. | |||
*/ | |||
const PRUint32 NEED_DOMAIN = 4; | |||
/** | |||
* This dialog only asks for password information. The implementation SHOULD | |||
* NOT show a username field. It MUST NOT modify the user attribute, | |||
* although it should show its initial value to the user in some form. For | |||
* example, a paragraph in the dialog might say "Please enter your password | |||
* for user jsmith at server intranet". | |||
* | |||
* This flag is mutually exclusive with #NEED_DOMAIN. | |||
*/ | |||
const PRUint32 ONLY_PASSWORD = 8; | |||
/* @} */ | |||
/** | |||
* Flags describing this dialog. A bitwise OR of the flag values | |||
* above. | |||
* | |||
* It is possible that neither #AUTH_HOST nor #AUTH_PROXY are set. | |||
* | |||
* Implementations should ignore flags they don't understand; especially, they | |||
* should not throw an exception because of an unsupported flag. | |||
*/ | |||
readonly attribute unsigned long flags; | |||
/** | |||
* The server-supplied realm of the authentication as defined in RFC 2617. | |||
* Can be the empty string if the protocol does not support realms. | |||
* Otherwise, this is a human-readable string like "Secret files". | |||
*/ | |||
readonly attribute AString realm; | |||
/** | |||
* The authentication scheme used for this request, if applicable. If the | |||
* protocol for this authentication does not support schemes, this will be | |||
* the empty string. Otherwise, this will be a string such as "basic" or | |||
* "digest". This string will always be in lowercase. | |||
*/ | |||
readonly attribute AUTF8String authenticationScheme; | |||
/** | |||
* The initial value should be used to prefill the dialog. | |||
* Implementations should not show the password in clear. | |||
* On return, this parameter should contain the username entered by | |||
* the user. | |||
*/ | |||
attribute AString username; | |||
/** | |||
* The initial value should be used to prefill the dialog or show it | |||
* in some other way to the user. | |||
* On return, this parameter should contain the username entered by | |||
* the user. | |||
*/ | |||
attribute AString password; | |||
/** | |||
* The initial value should be used to prefill the dialog or show it | |||
* in some other way to the user. | |||
* On return, this parameter should contain the domain entered by | |||
* the user. | |||
* This attribute is only used if flags include #NEED_DOMAIN. | |||
*/ | |||
attribute AString domain; | |||
}; | |||
/** | |||
* Interface for callback methods for the asynchronous nsIAuthPrompt2 method. | |||
* Callers MUST call exactly one method if nsIAuthPrompt2::promptPasswordAsync | |||
* returns successfully. They MUST NOT call any method on this interface before | |||
* promptPasswordAsync returns. | |||
*/ | |||
[scriptable, uuid(bdc387d7-2d29-4cac-92f1-dd75d786631d)] | |||
interface nsIAuthPromptCallback : nsISupports | |||
{ | |||
/** | |||
* Authentication information is available. | |||
* | |||
* @param aContext | |||
* The context as passed to promptPasswordAsync | |||
* @param aAuthInfo | |||
* Authentication information. Must be the same object that was passed | |||
* to promptPasswordAsync. | |||
* | |||
* @note Any exceptions thrown from this method should be ignored. | |||
*/ | |||
void onAuthAvailable(in nsISupports aContext, | |||
in nsIAuthInformation aAuthInfo); | |||
/** | |||
* Notification that the prompt was cancelled. | |||
* | |||
* @param aContext | |||
* The context that was passed to promptPasswordAsync. | |||
* @param userCancel | |||
* If false, this prompt was cancelled by calling the | |||
* the cancel method on the nsICancelable; otherwise, | |||
* it was cancelled by the user. | |||
*/ | |||
void onAuthCancelled(in nsISupports aContext, in boolean userCancel); | |||
}; | |||
/** | |||
* An interface allowing to prompt for a username and password. This interface | |||
* is usually acquired using getInterface on notification callbacks or similar. | |||
* It can be used to prompt users for authentication information, either | |||
* synchronously or asynchronously. | |||
*/ | |||
[scriptable, uuid(447fc780-1d28-412a-91a1-466d48129c65)] | |||
interface nsIAuthPrompt2 : nsISupports | interface nsIAuthPrompt2 : nsISupports | ||
{ | { | ||
/** @name Security Levels */ | |||
/* @{ */ | |||
/** | |||
* The password will be sent unencrypted. No security provided. | |||
*/ | |||
const PRUint32 LEVEL_NONE = 0; | |||
/** | |||
* Password will be sent encrypted, but the connection is otherwise | |||
* insecure. | |||
*/ | |||
const PRUint32 LEVEL_PW_ENCRYPTED = 1; | |||
/** | |||
* The connection, both for password and data, is secure. | |||
*/ | |||
const PRUint32 LEVEL_SECURE = 2; | |||
/* @} */ | |||
/** | |||
* Requests a username and a password. Implementations will commonly show a | |||
* dialog with a username and password field, depending on flags also a | |||
* domain field. | |||
* | |||
* @param aChannel | |||
* The channel that requires authentication. | |||
* @param level | |||
* One of the level constants from above. See there for descriptions | |||
* of the levels. | |||
* @param authInfo | |||
* Authentication information object. The implementation should fill in | |||
* this object with the information entered by the user before | |||
* returning. | |||
* | |||
* @retval true | |||
* Authentication can proceed using the values in the authInfo | |||
* object. | |||
* @retval false | |||
* Authentication should be cancelled, usually because the user did | |||
* not provide username/password. | |||
* | |||
* @note Exceptions thrown from this function will be treated like a | |||
* return value of false. | |||
*/ | |||
boolean promptAuth(in nsIChannel aChannel, | |||
in PRUint32 level, | |||
in nsIAuthInformation authInfo); | |||
/** | |||
* Asynchronously prompt the user for a username and password. | |||
* This has largely the same semantics as promptUsernameAndPassword(), | |||
* but must return immediately after calling and return the entered | |||
* data in a callback. | |||
* | |||
* If the user closes the dialog using a cancel button or similar, | |||
* the callback's nsIAuthPromptCallback::onAuthCancelled method must be | |||
* called. | |||
* Calling nsICancelable::cancel on the returned object SHOULD close the | |||
* dialog and MUST call nsIAuthPromptCallback::onAuthCancelled on the provided | |||
* callback. | |||
* | |||
* @throw NS_ERROR_NOT_IMPLEMENTED | |||
* Asynchronous authentication prompts are not supported; | |||
* the caller should fall back to promptUsernameAndPassword(). | |||
*/ | |||
nsICancelable asyncPromptAuth(in nsIChannel aChannel, | |||
in nsIAuthPromptCallback aCallback, | |||
in nsISupports aContext, | |||
in PRUint32 level, | |||
in nsIAuthInformation authInfo); | |||
}; | |||
Issues | == Issues == | ||
* NSS/PSM wants to prompt for passwords as well, and has no nsIChannel available | * NSS/PSM wants to prompt for passwords as well, and has no nsIChannel available | ||
** http://lxr.mozilla.org/seamonkey/source/security/manager/ssl/src/nsNSSCallbacks.cpp#188 | ** http://lxr.mozilla.org/seamonkey/source/security/manager/ssl/src/nsNSSCallbacks.cpp#188 | ||
** Make aChannel an nsISupports, which can also be a certificate or certificate store or whatever? | ** Make aChannel an nsISupports, which can also be a certificate or certificate store or whatever? | ||
* | ** However, after thinking more about this, I don't think it makes sense for this interface to be used by PSM. PSM has no use for a user or a domain, the "levels" here are not useful for it, and dialogs for certificate stores will probably look quite different. It should have its own interface. | ||
** | * Use nsIRequest instead of nsIChannel? | ||
** SOCKS authentication on a raw socket might be a use case | |||
** But nsIRequest has no obvious place to get something remotely URI-like | |||
* The parameter lists are quite long; group some of the info together on an object? This object could be passed to both functions. | |||
** It would fix this error: ../../../../../mozilla/netwerk/base/public/nsIAuthPrompt2.idl:106: Error: [domstring], [utf8string], [cstring], [astring] types cannot be used as inout parameters | |||
** switched to that in the interfaces above | |||
* mention threads in the docs | |||
* what's "LEVEL_SECURE"? | |||
* maybe nsIAuthInformation could have a parameter filled on return for how long to allow caching of auth info | |||
== Reasonings == | |||
This lists some reasons for why some parts of the interface look like they do | |||
* nsIChannel as opposed to nsIURI allows inspecting the securityInfo of the channel to determine the quality of the SSL encryption | |||
* Added authenticationScheme (RFC 2617 wording) to nsIAuthInformation to provide more information to the impl (they can always ignore the field if they don't care). this will be basic, digest, etc. | |||
** The level is still useful, for SSL and for not requiring the impl to understand all possible schemes, and also for non-HTTP protocols | |||
= Wallet/Satchel = | |||
These want to add a checkbox to the dialog. I propose an interface like this: | |||
/** | |||
* This interface allows creating auth prompts that have a specific parent. | |||
*/ | |||
[scriptable, uuid(...)] | |||
interface nsIPromptFactory | |||
{ | |||
/** | |||
* Returns an object implementing the specified interface that creates | |||
* prompts parented to aParent. | |||
*/ | |||
void getPrompt(in nsIDOMWindow aParent, in nsIIDRef iid, | |||
[iid_is(iid),retval] out nsQIResult result); | |||
}; | |||
This allows more flexibility than the current interface that wraps an nsIPrompt. | |||
For actually adding the checkbox, nsIPromptService2 will need a method like promptUsernameAndPassword2Checkbox (I decided on naming it promptAuth) |
Latest revision as of 21:34, 26 August 2006
https://bugzilla.mozilla.org/show_bug.cgi?id=265780
This page describes new and improved authentication interfaces for necko. There are various downsides of the current ones, including:
- Necko must use localized strings
- Embeddors don't get sufficient information
- etc, see https://bugzilla.mozilla.org/showdependencytree.cgi?id=265780
The interfaces in question are nsIAuthPrompt and nsIPromptService; possibly nsIPrompt as well.
I'll suggest an nsIAuthPrompt2 interface below. Its methods will have counterparts in nsIPromptService2; they will have the same signature but an additional window argument.
The nsIAuthPrompt2 is what necko calls stuff on; nsIPromptService2 is what embeddors would implement.
This suggestion is based on https://bugzilla.mozilla.org/attachment.cgi?id=163161 but slightly modified, and async calls added.
/** * A object that hold authentication information. The caller of * nsIAuthPrompt2::promptUsernameAndPassword or * nsIAuthPrompt2::promptPasswordAsync provides an object implementing this * interface; the prompt implementation can then read the values here to prefill * the dialog. After the user entered the authentication information, it should * set the attributes of this object to indicate to the caller what was entered * by the user. */ [scriptable, uuid(0d73639c-2a92-4518-9f92-28f71fea5f20)] interface nsIAuthInformation : nsISupports { /** @name Flags */ /* @{ */ /** * This dialog belongs to a network host. */ const PRUint32 AUTH_HOST = 1;
/** * This dialog belongs to a proxy. */ const PRUint32 AUTH_PROXY = 2;
/** * This dialog needs domain information. The user interface should show a * domain field, prefilled with the domain attribute's value. */ const PRUint32 NEED_DOMAIN = 4;
/** * This dialog only asks for password information. The implementation SHOULD * NOT show a username field. It MUST NOT modify the user attribute, * although it should show its initial value to the user in some form. For * example, a paragraph in the dialog might say "Please enter your password * for user jsmith at server intranet". * * This flag is mutually exclusive with #NEED_DOMAIN. */ const PRUint32 ONLY_PASSWORD = 8; /* @} */
/** * Flags describing this dialog. A bitwise OR of the flag values * above. * * It is possible that neither #AUTH_HOST nor #AUTH_PROXY are set. * * Implementations should ignore flags they don't understand; especially, they * should not throw an exception because of an unsupported flag. */ readonly attribute unsigned long flags;
/** * The server-supplied realm of the authentication as defined in RFC 2617. * Can be the empty string if the protocol does not support realms. * Otherwise, this is a human-readable string like "Secret files". */ readonly attribute AString realm;
/** * The authentication scheme used for this request, if applicable. If the * protocol for this authentication does not support schemes, this will be * the empty string. Otherwise, this will be a string such as "basic" or * "digest". This string will always be in lowercase. */ readonly attribute AUTF8String authenticationScheme;
/** * The initial value should be used to prefill the dialog. * Implementations should not show the password in clear. * On return, this parameter should contain the username entered by * the user. */ attribute AString username;
/** * The initial value should be used to prefill the dialog or show it * in some other way to the user. * On return, this parameter should contain the username entered by * the user. */ attribute AString password;
/** * The initial value should be used to prefill the dialog or show it * in some other way to the user. * On return, this parameter should contain the domain entered by * the user. * This attribute is only used if flags include #NEED_DOMAIN. */ attribute AString domain; };
/** * Interface for callback methods for the asynchronous nsIAuthPrompt2 method. * Callers MUST call exactly one method if nsIAuthPrompt2::promptPasswordAsync * returns successfully. They MUST NOT call any method on this interface before * promptPasswordAsync returns. */ [scriptable, uuid(bdc387d7-2d29-4cac-92f1-dd75d786631d)] interface nsIAuthPromptCallback : nsISupports { /** * Authentication information is available. * * @param aContext * The context as passed to promptPasswordAsync * @param aAuthInfo * Authentication information. Must be the same object that was passed * to promptPasswordAsync. * * @note Any exceptions thrown from this method should be ignored. */ void onAuthAvailable(in nsISupports aContext, in nsIAuthInformation aAuthInfo);
/** * Notification that the prompt was cancelled. * * @param aContext * The context that was passed to promptPasswordAsync. * @param userCancel * If false, this prompt was cancelled by calling the * the cancel method on the nsICancelable; otherwise, * it was cancelled by the user. */ void onAuthCancelled(in nsISupports aContext, in boolean userCancel); };
/** * An interface allowing to prompt for a username and password. This interface * is usually acquired using getInterface on notification callbacks or similar. * It can be used to prompt users for authentication information, either * synchronously or asynchronously. */ [scriptable, uuid(447fc780-1d28-412a-91a1-466d48129c65)] interface nsIAuthPrompt2 : nsISupports { /** @name Security Levels */ /* @{ */ /** * The password will be sent unencrypted. No security provided. */ const PRUint32 LEVEL_NONE = 0; /** * Password will be sent encrypted, but the connection is otherwise * insecure. */ const PRUint32 LEVEL_PW_ENCRYPTED = 1; /** * The connection, both for password and data, is secure. */ const PRUint32 LEVEL_SECURE = 2; /* @} */
/** * Requests a username and a password. Implementations will commonly show a * dialog with a username and password field, depending on flags also a * domain field. * * @param aChannel * The channel that requires authentication. * @param level * One of the level constants from above. See there for descriptions * of the levels. * @param authInfo * Authentication information object. The implementation should fill in * this object with the information entered by the user before * returning. * * @retval true * Authentication can proceed using the values in the authInfo * object. * @retval false * Authentication should be cancelled, usually because the user did * not provide username/password. * * @note Exceptions thrown from this function will be treated like a * return value of false. */ boolean promptAuth(in nsIChannel aChannel, in PRUint32 level, in nsIAuthInformation authInfo);
/** * Asynchronously prompt the user for a username and password. * This has largely the same semantics as promptUsernameAndPassword(), * but must return immediately after calling and return the entered * data in a callback. * * If the user closes the dialog using a cancel button or similar, * the callback's nsIAuthPromptCallback::onAuthCancelled method must be * called. * Calling nsICancelable::cancel on the returned object SHOULD close the * dialog and MUST call nsIAuthPromptCallback::onAuthCancelled on the provided * callback. * * @throw NS_ERROR_NOT_IMPLEMENTED * Asynchronous authentication prompts are not supported; * the caller should fall back to promptUsernameAndPassword(). */ nsICancelable asyncPromptAuth(in nsIChannel aChannel, in nsIAuthPromptCallback aCallback, in nsISupports aContext, in PRUint32 level, in nsIAuthInformation authInfo); };
Issues
- NSS/PSM wants to prompt for passwords as well, and has no nsIChannel available
- http://lxr.mozilla.org/seamonkey/source/security/manager/ssl/src/nsNSSCallbacks.cpp#188
- Make aChannel an nsISupports, which can also be a certificate or certificate store or whatever?
- However, after thinking more about this, I don't think it makes sense for this interface to be used by PSM. PSM has no use for a user or a domain, the "levels" here are not useful for it, and dialogs for certificate stores will probably look quite different. It should have its own interface.
- Use nsIRequest instead of nsIChannel?
- SOCKS authentication on a raw socket might be a use case
- But nsIRequest has no obvious place to get something remotely URI-like
- The parameter lists are quite long; group some of the info together on an object? This object could be passed to both functions.
- It would fix this error: ../../../../../mozilla/netwerk/base/public/nsIAuthPrompt2.idl:106: Error: [domstring], [utf8string], [cstring], [astring] types cannot be used as inout parameters
- switched to that in the interfaces above
- mention threads in the docs
- what's "LEVEL_SECURE"?
- maybe nsIAuthInformation could have a parameter filled on return for how long to allow caching of auth info
Reasonings
This lists some reasons for why some parts of the interface look like they do
- nsIChannel as opposed to nsIURI allows inspecting the securityInfo of the channel to determine the quality of the SSL encryption
- Added authenticationScheme (RFC 2617 wording) to nsIAuthInformation to provide more information to the impl (they can always ignore the field if they don't care). this will be basic, digest, etc.
- The level is still useful, for SSL and for not requiring the impl to understand all possible schemes, and also for non-HTTP protocols
Wallet/Satchel
These want to add a checkbox to the dialog. I propose an interface like this:
/** * This interface allows creating auth prompts that have a specific parent. */ [scriptable, uuid(...)] interface nsIPromptFactory { /** * Returns an object implementing the specified interface that creates * prompts parented to aParent. */ void getPrompt(in nsIDOMWindow aParent, in nsIIDRef iid, [iid_is(iid),retval] out nsQIResult result); };
This allows more flexibility than the current interface that wraps an nsIPrompt.
For actually adding the checkbox, nsIPromptService2 will need a method like promptUsernameAndPassword2Checkbox (I decided on naming it promptAuth)