Jed Parsons, Engineer, Mozilla
jparsons@mozilla.com
@drainmice
DevCon5, San Francisco, 29 Nov 2012
Presentation Source: https://github.com/jedp/introducing-persona
Mozilla Persona is a decentralized and secure authentication system for the web that simplifies the problem of authentication for users as well as for developers.
This presentation will discuss the problems in security and privacy that Persona seeks to remedy, describe how the system works, and show how you can use it to make your login experience easier for your users and simpler for you.
- Make Identity Simple
- Make Identity Unbroken
Or:
- Make Identity Awesome
- Make Identity Good
- Go to site
- Click login
- You have to register, first
- Choose a unique username
- Try to make up a password, dealing with random bulls**t rules
- Suppress the urge to smash something
- Security Questions!!?? WTF???
- Enter an email address
- Retrieve email to complete registration
- Go back to site and login
- Return to the site
- Identify Yourself by your Email Address
- Retrieve your email to reset your password
- People use the same crummy passwords
- People have to reset their passwords all the time (this should tell us that there's something broken about passwords)
- People open new accounts and let the old ones rot
- Memorizable vs Safe passwords - conflicting instructions from "experts"
- People use "1Password" solutions
- People just give up. Leave the door unlocked and hope for the best.
- Security gets worse, time gets wasted, kittens die
Source: http://xato.net/passwords/more-top-worst-passwords/
- Centralized authority
- One stop
Sounds good!
- You overshare your life. They track everything you do.
- What if service goes down? Site becomes irrelevant?
- Lock-in and brittleness for developers
Sounds not so good :-/
On login or signup:
- Provide an email address
To complete signup:
- Retrieve email and click the link
To reset your password:
- Retrieve email and click the link
Hmm...
First time flow:
- Click login
- Enter an email address
- Authenticate with your email provider
- Done
Second time flow:
- Click login, if you're not automatically logged in
- Select an email address
- Done
- People know them
- They make sense: name@place
- Natural for capturing contexts: me@work, me@home, etc.
- Not limited to a single identity
- Provide developers a direct means of contacting users
- Most sites want email anyway; one less step for signup
- There are no passwords
- Storing passwords is a liability
- Conversion rate
- No lock-in; Email addresses are universal
You can't run a FB-only login system without alienating a significant chunk of most audiences. ... Now that Persona and FB auth are on equal footings, we have yet to have anyone complain about the signup process.
Source: http://news.ycombinator.com/item?id=4599881
A complete Persona-based auth system is a question of hours, not days.
Source: http://news.ycombinator.com/item?id=4232505
Done!
Phone call with: http://everfi.com/ and Anson County School District
That was actually simpler than I thought it would be.
Sean Moffatt of Joomla!, writing a Persona plugin for the Joomla! CMS.
-
Email is identity.
Users identify. No new infrastructure. No lock-in
-
Decentralized
Privacy-protecting. Anyone can play. IdPs authenticate as they like.
-
Ownership-based authority
No passwords.
-
Forward compatible
Until native support, bootstrapped with html5 shim and Mozilla Persona IdP fallback.
A Walk Through The Protocol with Joan, Francine, and Fluffball.
For more details:
If this makes your eyes glaze over, until the next three slides are passed, you can visit:
-
Francine is our User
-
Fluffball runs the Identity Provider,
fluffball.com
-
Joan runs
HatsByJoan.com
, the Relying Party
Plot: Francine wants to login to HatsByJoan.com
as francine@fluffball.com
.
If she can convince Joan of her identity, Joan will let her buy hats.
- Francine wants to login to RP
HatsByJoan.com
asfrancine@fluffball.com
- Francine must prove she is actually
francine@fluffball.com
- Francine goes to her IdP,
fluffball.com
- IdP asks Francine to authenticate
- IdP then asks Francine to generate a public and private key
- Francine sends the public key to the IdP
- IdP makes a JWT with email address, public key, and expiry date
- IdP signs the JWT with its own private key
- IdP returns this signed certificate to Francine
- Francine stores this as proof of her
francine@fluffball.com
identity - Francine stores the private key she generated along with the certificate
- Francine makes a JWT containing her email, Joan's address, and a short expiry
- Francine signs this JWT with her private key
- This is a signed assertion of identity
- She pins a copy of her
fluffball.com
certificate to her assertion - This is a backed assertion (backed by the certificate)
- Francine hands the backed assertion to Joan
- Joan transmits the assertion down to her servers for handling
- On the server, she checks both expiry dates
- Joan extracts the hostname from Fluffball's email address (
fluffball.com
) - Joan asks IdP
fluffball.com
for its public key - Joan uses the key to verify the signature on the certificate
- With Francine's public key from the cert, Joan verifies the assertion signature
- She now knows that Francine is indeed
francine@fluffball.com
- She opens the doors to her shop and offers to sell Francine a hat
In your web page:
<script src="https://login.persona.org/include.js"></script>
We recommend you not host the include.js
file yourself.
We're still in Beta, and things might still change.
navigator.id.watch({
loggedInUser: #{ theUserYouBelieveIsLoggedIn },
onlogin: function(assertion) {
$.post('/login',
{assertion: assertion},
function(data) { window.location = '/home' });
},
onlogout: function() {
$.post('/logout',
function() { window.location = '/logout' });
}
});
$('#login').click(function() {
navigator.id.request();
});
$('#logout').click(function() {
navigator.id.logout();
});
var body = qs.stringify({
assertion: assertion,
audience: YOUR_SITE
});
var options = {
uri: 'https://verifier.login.persona.org/verify',
headers: {
'content-type': 'application/x-www-form-urlencoded',
'content-length': body.length
}
};
request.post(options, function(err, res, body) {
if (err) return callback(err);
return callback(null, JSON.parse(body));
});
The verifier will return JSON like so:
{
"status": "okay",
"email": "francine@fluffball.com",
"audience": "https://shoesbyjoan.com",
"expires": 1354217396705,
"issuer": "fluffball.com"
}
If the assertion was not good, the status
will not be okay
.
https://developer.mozilla.org/en-US/docs/Persona/Security_Considerations
- Verify assertions on your server
- Specify the
audience
parameter to the verifier - Use HTTP libraries that verify SSL certs
- Implement CSRF (Cross-Site Request Forgery) protection
- Implement CSP (Content Security Policy)
https://lists.mozilla.org/listinfo/dev-identity
#identity on irc.mozilla.org
https://developer.mozilla.org/en-US/docs/Persona
https://developer.mozilla.org/en-US/docs/persona/branding
https://wiki.mozilla.org/Identity/MobileSDK
https://hacks.mozilla.org/2012/10/r2d2b2g-an-experimental-prototype-firefox-os-test-environment/