easy logins for ruby web applications

125
François Marier – @fmarier Easy logins for Ruby web applications

Upload: francois-marier

Post on 08-May-2015

304 views

Category:

Technology


0 download

DESCRIPTION

Users hate picking and having to remember them. Developers hate dealing with and storing them. Why are we still using passwords again? Surely there is a better way to log into websites. This talk will introduce the technology behind Persona and the BrowserID protocol. Mozilla intends to solve the password problem on the web with a federated cross-browser system that is intensely focused on user experience and privacy. We may not be able to get rid of all passwords, after all, you probably don’t want to be subjected to a fingerprint check before leaving a comment on someone’s blog, but we can eliminate site-specific passwords and replace them with something better: a decentralized system that’s under the control of users, not a for-profit gatekeeper. It’s just four easy steps to add it to your Ruby site/app from scratch and there are already plugins for Devise, Omniauth, Rails, Sinatra, and Warden.

TRANSCRIPT

Page 1: Easy logins for Ruby web applications

François Marier – @fmarier

Easy logins for Rubyweb applications

Page 2: Easy logins for Ruby web applications
Page 3: Easy logins for Ruby web applications
Page 4: Easy logins for Ruby web applications
Page 5: Easy logins for Ruby web applications
Page 6: Easy logins for Ruby web applications
Page 7: Easy logins for Ruby web applications
Page 8: Easy logins for Ruby web applications
Page 9: Easy logins for Ruby web applications
Page 10: Easy logins for Ruby web applications
Page 11: Easy logins for Ruby web applications
Page 12: Easy logins for Ruby web applications

problem #1:

passwords are hard to secure

Page 13: Easy logins for Ruby web applications

bcrypt / scrypt / pbkdf2

per-user salt

site secret

password & lockout policies

secure recovery

Page 14: Easy logins for Ruby web applications

bcrypt / scrypt / pbkdf2

per-user salt

site secret

password & lockout policies

secure recovery

Page 15: Easy logins for Ruby web applications

bcrypt / scrypt / pbkdf2

per-user salt

site secret

password & lockout policies

secure recovery

Page 16: Easy logins for Ruby web applications

bcrypt / scrypt / pbkdf2

per-user salt

site secret

password & lockout policies

secure recovery

Page 17: Easy logins for Ruby web applications

bcrypt / scrypt / pbkdf2

per-user salt

site secret

password & lockout policies

secure recovery

Page 18: Easy logins for Ruby web applications

bcrypt / scrypt / pbkdf2

per-user salt

site secret

password & lockout policies

secure recovery

20132013

passwordpassword

guidelines

guidelines

Page 19: Easy logins for Ruby web applications

passwords are hard to secure

they are a liability

Page 20: Easy logins for Ruby web applications

ALTER TABLE userDROP COLUMN password;

Page 21: Easy logins for Ruby web applications

problem #2:

passwords are hard to remember

Page 22: Easy logins for Ruby web applications

pick an easy password

Page 23: Easy logins for Ruby web applications

pick an easy password

use it everywhere

Page 24: Easy logins for Ruby web applications

passwords are hard to remember

they need to be reset

Page 25: Easy logins for Ruby web applications
Page 26: Easy logins for Ruby web applications

controlemail

account

controlall

accounts=

Page 27: Easy logins for Ruby web applications
Page 28: Easy logins for Ruby web applications

“People want a littledating before marriage.”

Eric Vishria – Rockmelt

Page 29: Easy logins for Ruby web applications
Page 30: Easy logins for Ruby web applications

decentralised

Page 31: Easy logins for Ruby web applications

myid.com/u/francois

Page 32: Easy logins for Ruby web applications
Page 33: Easy logins for Ruby web applications
Page 34: Easy logins for Ruby web applications

privacy®

Page 35: Easy logins for Ruby web applications

existing login systemsare not good enough

Page 36: Easy logins for Ruby web applications

ideal web-wide identity system

Page 37: Easy logins for Ruby web applications

ideal web-wide identity system

Page 38: Easy logins for Ruby web applications

ideal web-wide identity system

Page 39: Easy logins for Ruby web applications

ideal web-wide identity system

Page 40: Easy logins for Ruby web applications

what if it were a standardpart of the web browser?

Page 41: Easy logins for Ruby web applications
Page 42: Easy logins for Ruby web applications

how does it work?

Page 45: Easy logins for Ruby web applications

getting a proof of email ownership

Page 46: Easy logins for Ruby web applications

authenticate?

Page 47: Easy logins for Ruby web applications

authenticate?

public key

Page 48: Easy logins for Ruby web applications

authenticate?

public key

signed public key

Page 49: Easy logins for Ruby web applications

you have a signed statement from yourprovider that you own your email address

Page 50: Easy logins for Ruby web applications
Page 51: Easy logins for Ruby web applications

logging into a 3rd party site

Page 52: Easy logins for Ruby web applications

Valid for: 2 minutes

wikipedia.org

assertion

Page 53: Easy logins for Ruby web applications

Valid for: 2 minutes

wikipedia.org

check audience

assertion

Page 54: Easy logins for Ruby web applications

Valid for: 2 minutes

wikipedia.org

check audiencecheck expiry

assertion

Page 55: Easy logins for Ruby web applications

Valid for: 2 minutes

wikipedia.org

check audiencecheck expirycheck signature

assertion

Page 56: Easy logins for Ruby web applications

assertion

Valid for: 2 minutes

wikipedia.org

public key

Page 57: Easy logins for Ruby web applications

assertion

Valid for: 2 minutes

wikipedia.org

Page 58: Easy logins for Ruby web applications

assertion

session cookie

Page 59: Easy logins for Ruby web applications

demo #1:

http://www.voo.st/http://www.debuggex.com

[email protected]

Page 60: Easy logins for Ruby web applications

Persona is already adecentralised system

Page 61: Easy logins for Ruby web applications

decentralisation is the answer, but it's not

a product adoption strategy

Page 62: Easy logins for Ruby web applications

we can't wait for all domainsto adopt Persona

Page 63: Easy logins for Ruby web applications

we can't wait for all domainsto adopt Persona

solution: a temporarycentralised fallback

Page 64: Easy logins for Ruby web applications

demo #2:

http://sloblog.io/

[email protected]

Page 65: Easy logins for Ruby web applications

Persona already workswith all email domains

Page 66: Easy logins for Ruby web applications

identity bridging

Page 67: Easy logins for Ruby web applications

demo #3:

http://www.reasonwell.com/

[email protected]

Page 68: Easy logins for Ruby web applications
Page 69: Easy logins for Ruby web applications
Page 70: Easy logins for Ruby web applications
Page 71: Easy logins for Ruby web applications

Persona supportsall modern browsers

>= 8

Page 72: Easy logins for Ruby web applications

Persona is decentralised,simple and cross-browser

Page 73: Easy logins for Ruby web applications

it's simple for users, but is it also

simple for developers?

Page 74: Easy logins for Ruby web applications
Page 75: Easy logins for Ruby web applications

<script src=”https://login.persona.org/include.js”></script></body></html>

Page 76: Easy logins for Ruby web applications

navigator.id.watch({ loggedInEmail: “[email protected]”, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { // do something } ); }, onlogout: function () { window.location = '/logout'; }});

Page 77: Easy logins for Ruby web applications

navigator.id.watch({ loggedInUser: “[email protected]”, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { // do something } ); }, onlogout: function () { window.location = '/logout'; }});

Page 78: Easy logins for Ruby web applications

navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { // do something } ); }, onlogout: function () { window.location = '/logout'; }});

Page 79: Easy logins for Ruby web applications

navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { // do something } ); }, onlogout: function () { window.location = '/logout'; }});

Page 80: Easy logins for Ruby web applications

navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { window.location = '/'; } ); }, onlogout: function () { window.location = '/logout'; }});

Page 81: Easy logins for Ruby web applications
Page 82: Easy logins for Ruby web applications

navigator.id.request()

Page 83: Easy logins for Ruby web applications
Page 84: Easy logins for Ruby web applications
Page 85: Easy logins for Ruby web applications
Page 86: Easy logins for Ruby web applications

navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { window.location = '/'; } ); }, onlogout: function () { window.location = '/logout'; }});

Page 87: Easy logins for Ruby web applications

eyJhbGciOiJEUzEyOCJ9.eyJwdWJsaWMta2V5Ijp7ImFsZ29yaXRobSI6IkRTIiwieSI6ImNhZDg2ZDgyNWU0MjBkMGI4Njk5MjM4ZDM5ZTFjYjIyOGMyMTk1NWFiMzcwOTQ1YzExNzBhMzM4NjcyNDM0ZDJmNGYxZDg5ZjFkZjMzNmU1ZjZjZjk2YjhiOTlmMjgyNmFjNTYxZmI1YWMyYTc4ZjNhMzBkNGYxNTVhYjc3ZGExYmY3MWU4ZGMzNjQ0MmU2NjQ3MmE5Mjg0N2I2YjFlNDRkMTJlM2IwMjVjOWZmNTFmNDdhMWE5ZWYyMGZhOTVjMTcxZjBkMTYzNGE4ZTY4YTk5NWU3ZjFjY2FiYTJlOTRjYTI3ODE1ZWVkMTcxYjY1YTJmZGQzNTE1NjY3OTI0ZjUiLCJwIjoiZmY2MDA0ODNkYjZhYmZjNWI0NWVhYjc4NTk0YjM1MzNkNTUwZDlmMWJmMmE5OTJhN2E4ZGFhNmRjMzRmODA0NWFkNGU2ZTBjNDI5ZDMzNGVlZWFhZWZkN2UyM2Q0ODEwYmUwMGU0Y2MxNDkyY2JhMzI1YmE4MWZmMmQ1YTViMzA1YThkMTdlYjNiZjRhMDZhMzQ5ZDM5MmUwMGQzMjk3NDRhNTE3OTM4MDM0NGU4MmExOGM0NzkzMzQzOGY4OTFlMjJhZWVmODEyZDY5YzhmNzVlMzI2Y2I3MGVhMDAwYzNmNzc2ZGZkYmQ2MDQ2MzhjMmVmNzE3ZmMyNmQwMmUxNyIsInEiOiJlMjFlMDRmOTExZDFlZDc5OTEwMDhlY2FhYjNiZjc3NTk4NDMwOWMzIiwiZyI6ImM1MmE0YTBmZjNiN2U2MWZkZjE4NjdjZTg0MTM4MzY5YTYxNTRmNGFmYTkyOTY2ZTNjODI3ZTI1Y2ZhNmNmNTA4YjkwZTVkZTQxOWUxMzM3ZTA3YTJlOWUyYTNjZDVkZWE3MDRkMTc1ZjhlYmY2YWYzOTdkNjllMTEwYjk2YWZiMTdjN2EwMzI1OTMyOWU0ODI5YjBkMDNiYmM3ODk2YjE1YjRhZGU1M2UxMzA4NThjYzM0ZDk2MjY5YWE4OTA0MWY0MDkxMzZjNzI0MmEzODg5NWM5ZDViY2NhZDRmMzg5YWYxZDdhNGJkMTM5OGJkMDcyZGZmYTg5NjIzMzM5N2EifSwicHJpbmNpcGFsIjp7ImVtYWlsIjoiZm9vQG1vY2tteWlkLmNvbSJ9LCJpYXQiOjEzNzY1MzY0NjM1MTgsImV4cCI6MTM3NjU0MDA2MzUxOCwiaXNzIjoibW9ja215aWQuY29tIn0.IeUR0_3ayAZkdNSXjF4aaCwSHnHa4X1lzrjX-qkNcPIbXx1hmQQPwg~eyJhbGciOiJEUzEyOCJ9.eyJleHAiOjEzNzY1MzY3MDc2MzUsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3QifQ.NJ8H1qZcWXbXfPJSdgB_mORHQ442ZkY0XYfdQsZZsIjooG7k7qWyVw

Page 88: Easy logins for Ruby web applications

navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { window.location = '/home'; } ); }, onlogout: function () { window.location = '/logout'; }});

Page 89: Easy logins for Ruby web applications

gem install browserid-verifier

Page 90: Easy logins for Ruby web applications

require 'browserid/verifier'

response = verify("http://123done.org", params["assertion"])

Page 91: Easy logins for Ruby web applications

{ status: “okay”,

audience: “http://123done.org”,

expires: 1344849682560,

email: “[email protected]”,

issuer: “login.persona.org”}

Page 92: Easy logins for Ruby web applications

require 'browserid/verifier'

response = verify("http://123done.org", params["assertion"])

if response["status"] == "okay" session[:email] = response["email"]end

Page 93: Easy logins for Ruby web applications

{ status: “failed”,

reason: “assertion has expired”}

Page 94: Easy logins for Ruby web applications

require 'browserid/verifier'

response = verify("http://123done.org", params["assertion"])

if response["status"] == "okay" session[:email] = response["email"]else session[:email] = nilend

Page 95: Easy logins for Ruby web applications
Page 96: Easy logins for Ruby web applications
Page 97: Easy logins for Ruby web applications

navigator.id.logout()

Page 98: Easy logins for Ruby web applications

navigator.id.watch({ loggedInUser: null, onlogin: function (assertion) { $.post('/login', {assertion: assertion}, function (data) { window.location = '/home'; } ); }, onlogout: function () { window.location = '/logout'; }});

Page 99: Easy logins for Ruby web applications
Page 100: Easy logins for Ruby web applications

1. load javascript library

Page 101: Easy logins for Ruby web applications

1. load javascript library

2. setup login & logout callbacks

Page 102: Easy logins for Ruby web applications

1. load javascript library

2. setup login & logout callbacks

3. add login and logout buttons

Page 103: Easy logins for Ruby web applications

1. load javascript library

2. setup login & logout callbacks

3. add login and logout buttons

4. verify proof of ownership

Page 104: Easy logins for Ruby web applications

1. load javascript library

2. setup login & logout callbacks

3. add login and logout buttons

4. verify proof of ownership

no API keyneeded

Page 105: Easy logins for Ruby web applications

Devise

warden

Page 106: Easy logins for Ruby web applications

one simple request

Page 107: Easy logins for Ruby web applications
Page 108: Easy logins for Ruby web applications

building a new site:default to Persona

Page 109: Easy logins for Ruby web applications

working on an existing site/app:add support for Persona

Page 110: Easy logins for Ruby web applications

before

Page 111: Easy logins for Ruby web applications

after

Page 112: Easy logins for Ruby web applications

after

navigator.id.request()

Page 113: Easy logins for Ruby web applications
Page 114: Easy logins for Ruby web applications

ALTER TABLE userDROP COLUMN password;

Page 115: Easy logins for Ruby web applications

To learn more about Persona:

https://login.persona.org/http://identity.mozilla.com/

https://developer.mozilla.org/docs/Persona/Why_Personahttps://developer.mozilla.org/docs/Persona/Quick_Setup

https://github.com/mozilla/browserid-cookbookhttps://developer.mozilla.org/docs/Persona/Libraries_and_plugins

http://123done.org/https://wiki.mozilla.org/Identity#Get_Involved

@fmarier http://fmarier.org

Page 116: Easy logins for Ruby web applications

identity provider API

https://eyedee.me/.well-known/browserid:

{ "public-key": { "algorithm":"RS", "n":"8606...", "e":"65537" }, "authentication": "/browserid/sign_in.html", "provisioning": "/browserid/provision.html"}

Page 117: Easy logins for Ruby web applications

https://eyedee.me/.well-known/browserid:

{ "public-key": { "algorithm":"RS", "n":"8606...", "e":"65537" }, "authentication": "/browserid/sign_in.html", "provisioning": "/browserid/provision.html"}

identity provider API

Page 118: Easy logins for Ruby web applications

https://eyedee.me/.well-known/browserid:

{ "public-key": { "algorithm":"RS", "n":"8606...", "e":"65537" }, "authentication": "/browserid/sign_in.html", "provisioning": "/browserid/provision.html"}

identity provider API

Page 119: Easy logins for Ruby web applications

https://eyedee.me/.well-known/browserid:

{ "public-key": { "algorithm":"RS", "n":"8606...", "e":"65537" }, "authentication": "/browserid/sign_in.html", "provisioning": "/browserid/provision.html"}

identity provider API

Page 120: Easy logins for Ruby web applications

https://eyedee.me/.well-known/browserid:

{ "public-key": { "algorithm":"RS", "n":"8606...", "e":"65537" }, "authentication": "/browserid/sign_in.html", "provisioning": "/browserid/provision.html"}

identity provider API

Page 121: Easy logins for Ruby web applications

identity provider API

1. check for your /.well-known/browserid

2. try the provisioning endpoint

3. show the authentication page

4. call the provisioning endpoint again

Page 122: Easy logins for Ruby web applications

identity provider API

1. check for your /.well-known/browserid

2. try the provisioning endpoint

3. show the authentication page

4. call the provisioning endpoint again

Page 123: Easy logins for Ruby web applications

identity provider API

1. check for your /.well-known/browserid

2. try the provisioning endpoint

3. show the authentication page

4. call the provisioning endpoint again

Page 124: Easy logins for Ruby web applications

identity provider API

1. check for your /.well-known/browserid

2. try the provisioning endpoint

3. show the authentication page

4. call the provisioning endpoint again

Page 125: Easy logins for Ruby web applications

© 2013 François Marier <[email protected]>This work is licensed under aCreative Commons Attribution-ShareAlike 3.0 New Zealand License.

Top 500 passwords: http://xato.net/passwords/more-top-worst-passwords/

Parchment: https://secure.flickr.com/photos/27613359@N03/6750396225/

Restaurant dinner: https://secure.flickr.com/photos/yourdon/3977084094/

Stop sign: https://secure.flickr.com/photos/artbystevejohnson/6673406227/

Photo credits: