Services/OpenId

From MozillaWiki
Jump to: navigation, search

This page discusses the implementation of an OpenID service.

Glossary

  • OP: OpenId Provider. e.g. http://openid.ziade.org
  • RP: Relying Party, the website that does an OpenID request
  • FI: Firefox Identity Plugin

Flow

  • FI detects forms that offer OpenID and inject a "Sign in using your Firefox Identity" in it so the user can use it to sign in.
  • Clicking on the button initiates the process by sending the user's id to the RP
  • the RP calls the OP "associate" API
  • the RP calls the OP "checkid_setup" API
  • FI intercepts the "checkid_setup" call and injects an Authentication header
  • The OP redirects to the RP

Demo

You can try the current implementation by installing the custom account manager add-on here: http://ziade.org/account-manager-0.0.13-dev.xpi

This will work with my server at http://openid.ziade.org. The server uses a dummy authentication backend so it will always successfully authenticates you.

Once the add-on is installed, you can try connecting to websites that support openid.

Sites successfuly tested so far:

The Identity Server

The server is a full OpenID 2.0 server that will authenticate the user against his Sync account.

The user identifier is: https://server/user-email

Where user-email is the user email used for Sync. The server will internally convert the email to a base32 hash to find the user.

Mine is currently: http://openid.ziade.org/tarek@mozilla.com

The other difference from a regular OpenId server is that authorizing EPs is done automatically in case the Sync Password is provided in an Authorization header, on the checkid_setup call. In that case, the server verifies the password and automatically adds the site, then performs the usual redirect.

If the add-on is deactivated for any reason, the user will still be able to use our openid provider, but will have to manually authorize sites through a screen that will display a "continue" button (after he has logged into our OP).


OpenID APIs

A user is identified by his e-mail.


GET or POST https://server/

 Performs an OpenId operation. Depending on the openid_mode 
 request parameter value, the server will perform a different process.
 
 * associate: creates an association with the EP.
 * check_authentication: checks that a given site is authorized
 * checkid_setup: checks if an EP owns the Claimed Identifier.
 * checkid_immediate: XXX points to checkid_setup for now
 
 See the OpenID doc for more details.

GET https://server/user_email

 Discovery page for the user. Returns:
 
 * a Yadis page for clients that accept "application/xrds+xml"
 * an HTML page for other clients. If the user is logged in, and display his own page, he will get his list of active handles w/. associated sites.

Implementation details

The server prototype is here: http://bitbucket.org/tarek/server-openid

  • The server is implemented using server-core, for the authentication APIs
  • storage
    • Users are stored in LDAP for Mozilla, but people can use alternative back-ends
    • Association handles and Site tokens are stored in Redis, but people can use alternative back-ends
  • The server uses the same node assignment library than Sync to associate a user to a server
  • A new multi-value field is added in the LDAP User object: service-enabled
    • to enable OpenID for the user, an OpenID value is added
    • The Sync value is used to enable/disable Sync.
    • The account-enabled field is kept for a global de-activation of a user
  • Node assignment can be done on the first OpenID activation if Sync is disabled or not used yet.

The client prototype is here: http://hg.mozilla.org/labs/weave-identity/summary

See also, Account Manager specs: https://wiki.mozilla.org/Labs/Weave/Identity/Account_Manager/Spec/3

Performances

App profile:

  • CPU intensive application (crypto)
  • All storage in RAM (Redis)
  • Storage: handles + sites associated w/ a handle

RAM Formula:

  • HANDLE_SIZE = maxsize(handle) + maxsize(secret) + 10 * avgsize(url)
  • HANDLE_SIZE = 40 + 32 + 10 * 150 = 1572 octets
  • USER_DATA = 1572 * 10 = 15 ko

On a server w/ 8 gig for Redis, there's room for half a million USER_DATA.

An openid transaction is on average two requests:

  • smart mode: association + checkid_setup
  • dumb mode: checkid_setup + check_authentication

So a 8 gig. server can handle 250k transactions per hour when the RAM is full: 70 transactions/seconds.

Draft on quotas:

  • Max TTL for a handle: 3600 seconds.
  • Max number of sites / handle : 10
  • Max number of handles per user: 10

XXX: bench a server to see how much transactions/seconds it can handle. (cpu work)

Impact on Sync

  • If a user tries to create a new account in Firefox Sync via the wizard but already has OpenID activated
    • we tell the user that there's an existing account and redirect him to the regular user authentication screen.
    • we add Sync in service-enabled in LDAP on the first sync
  • If a user deletes his Sync account
    • we remove Sync from service-enabled but don't remove the LDAP user
  • If a user tries to create a new account in the OpenID UI, and already has Sync activated, we warn that an account exists for that e-mail and propose to the user to activate OpenID through the user account management panel

Impact on Mozilla websites

  • We need to implement OpenID support in all of them.
  • XXX

Privacy concerns

XXX

  • We store authorized sites in RAM. If someone breaks the server he could get them. One way to avoid this is to hash them. But that's more CPU work