Necko:nsIAuthPrompt2: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
(update per final changes)
 
(4 intermediate revisions by the same user not shown)
Line 16: Line 16:
  /**
  /**
  * A object that hold authentication information. The caller of
  * A object that hold authentication information. The caller of
  * promptUsernameAndPassword or promptPasswordAsync provides an object
  * nsIAuthPrompt2::promptUsernameAndPassword or
  * implementing this interface; the prompt implementation can then read the
* nsIAuthPrompt2::promptPasswordAsync provides an object implementing this
* values here to prefill the dialog. After the user entered the authentication
  * interface; the prompt implementation can then read the values here to prefill
* information, it should set the attributes of this object to indicate to the
* the dialog. After the user entered the authentication information, it should
* caller what was entered by the user.
* set the attributes of this object to indicate to the caller what was entered
* by the user.
  */
  */
  [scriptable, uuid(0d73639c-2a92-4518-9f92-28f71fea5f20)]
  [scriptable, uuid(0d73639c-2a92-4518-9f92-28f71fea5f20)]
Line 50: Line 51:
   * for user jsmith at server intranet".
   * for user jsmith at server intranet".
   *
   *
   * This flag is mutually exclusive with NEED_DOMAIN.
   * This flag is mutually exclusive with #NEED_DOMAIN.
   */
   */
   const PRUint32 ONLY_PASSWORD = 8;
   const PRUint32 ONLY_PASSWORD = 8;
Line 59: Line 60:
   * above.
   * above.
   *
   *
   * It is possible that neither AUTH_HOST nor AUTH_PROXY are set.
   * It is possible that neither #AUTH_HOST nor #AUTH_PROXY are set.
   *
   *
   * Implementations should ignore flags they don't understand; especially, they
   * Implementations should ignore flags they don't understand; especially, they
Line 65: Line 66:
   */
   */
   readonly attribute unsigned long flags;
   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;


   /**
   /**
Line 72: Line 88:
   * the user.
   * the user.
   */
   */
   attribute AString userName;
   attribute AString username;


   /**
   /**
Line 87: Line 103:
   * On return, this parameter should contain the domain entered by
   * On return, this parameter should contain the domain entered by
   * the user.
   * the user.
   * This attribute is only used if flags include AUTH_DOMAIN.
   * This attribute is only used if flags include #NEED_DOMAIN.
   */
   */
   attribute AString domain;
   attribute AString domain;
Line 94: Line 110:
  /**
  /**
  * Interface for callback methods for the asynchronous nsIAuthPrompt2 method.
  * Interface for callback methods for the asynchronous nsIAuthPrompt2 method.
  * Callers MUST call exactly one method if promptPasswordAsync returns
  * Callers MUST call exactly one method if nsIAuthPrompt2::promptPasswordAsync
  * successfully. They MUST NOT call any method on this interface before
  * returns successfully. They MUST NOT call any method on this interface before
  * promptPasswordAsync returns.
  * promptPasswordAsync returns.
  */
  */
Line 127: Line 143:
   void onAuthCancelled(in nsISupports aContext, in boolean userCancel);
   void onAuthCancelled(in nsISupports aContext, in boolean userCancel);
  };
  };


  /**
  /**
Line 161: Line 178:
   * @param aChannel
   * @param aChannel
   *        The channel that requires authentication.
   *        The channel that requires authentication.
  * @param passwordRealm
  *        The server-supplied realm for the password. This is a
  *        human-readable string like "Secret files".
   * @param level
   * @param level
   *        One of the level constants from above. See there for descriptions
   *        One of the level constants from above. See there for descriptions
Line 182: Line 196:
   *        return value of false.
   *        return value of false.
   */
   */
   boolean promptUsernameAndPassword(in nsIChannel aChannel,
   boolean promptAuth(in nsIChannel aChannel,
                                    in AString passwordRealm,
                    in PRUint32 level,
                                    in PRUint32 level,
                    in nsIAuthInformation authInfo);
                                    in nsIAuthInformation authInfo);


   /**
   /**
   * Asynchronously prompt the user for a username and password.
   * Asynchronously prompt the user for a username and password.
   * This has largely the same semantics as promptUsernameAndPassword,
   * This has largely the same semantics as promptUsernameAndPassword(),
   * but must return immediately after calling and return the entered
   * but must return immediately after calling and return the entered
   * data in a callback.
   * data in a callback.
   *
   *
   * If the user closes the dialog using a cancel button or similar,
   * If the user closes the dialog using a cancel button or similar,
   * the callback's onAuthCancelled method must be called.
   * the callback's nsIAuthPromptCallback::onAuthCancelled method must be
   * Calling cancel on the returned object SHOULD close the dialog
  * called.
   * and MUST call onAuthCancelled on the provided callback.
   * 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
   * @throw NS_ERROR_NOT_IMPLEMENTED
   *        Asynchronous authentication prompts are not supported;
   *        Asynchronous authentication prompts are not supported;
   *        the caller should fall back to promptUsernameAndPassword
   *        the caller should fall back to promptUsernameAndPassword().
   */
   */
   nsICancelable promptPasswordAsync(in nsIChannel aChannel,
   nsICancelable asyncPromptAuth(in nsIChannel aChannel,
                                    in nsIAuthPromptCallback aCallback,
                                in nsIAuthPromptCallback aCallback,
                                    in nsISupports aContext,
                                in nsISupports aContext,
                                    in AString passwordRealm,
                                in PRUint32 level,
                                    in PRUint32 level,
                                in nsIAuthInformation authInfo);
                                    in nsIAuthInformation authInfo);
  };
  };




Line 219: Line 234:
* Use nsIRequest instead of nsIChannel?
* Use nsIRequest instead of nsIChannel?
** SOCKS authentication on a raw socket might be a use case
** 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.
* 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
** It would fix this error: ../../../../../mozilla/netwerk/base/public/nsIAuthPrompt2.idl:106: Error: [domstring], [utf8string], [cstring], [astring] types cannot be used as inout parameters
Line 225: Line 241:
* what's "LEVEL_SECURE"?
* what's "LEVEL_SECURE"?
* maybe nsIAuthInformation could have a parameter filled on return for how long to allow caching of auth info
* maybe nsIAuthInformation could have a parameter filled on return for how long to allow caching of auth info
* Wallet/Satchel want to add a checkbox to the dialog for saving PW info


== Reasonings ==
== Reasonings ==
Line 236: Line 251:
These want to add a checkbox to the dialog. I propose an interface like this:
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.
  * This interface allows creating auth prompts that have a specific parent.
*/
  */
[scriptable, uuid(...)]
[scriptable, uuid(...)]
interface nsIAuthPrompt2Factory
interface nsIPromptFactory
{
{
   /**
   /**
   * Returns an object implementing nsIAuthPrompt2 that creates dialogs
   * Returns an object implementing the specified interface that creates
   * parented to aParent.
   * prompts parented to aParent.
   */
   */
   nsIAuthPrompt2 getAuthPrompt2(in nsIDOMWindow 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.
This allows more flexibility than the current interface that wraps an nsIPrompt.


For actually adding the checkbox, nsIPromptService2 will need a method like promptUsernameAndPassword2Checkbox.
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:

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)