$30 off During Our Annual Pro Sale. View Details »

Going Password-Free

Eric Mann
February 03, 2017

Going Password-Free

Passwordless authentication via Tozny as presented at SunshinePHP 2017

Eric Mann

February 03, 2017
Tweet

More Decks by Eric Mann

Other Decks in Technology

Transcript

  1. Going Password-Free
    Sunshine PHP 2017

    View Slide

  2. 90

    View Slide

  3. 19

    View Slide

  4. hunter2

    View Slide

  5. View Slide

  6. How can we fix it?
    Password managers help
    Password strength meters (zxcvbn) help
    Two-factor authentication helps
    But why require a password at all?

    View Slide

  7. View Slide

  8. A PHP Example
    Defer to a 3rd party for email & validation
    Use the SlimPHP framework for quick bootstrapping
    Allow either password or password-less authentication

    View Slide

  9. Authentication Provider
    Free developer preview
    Powers both link-based and
    push-based auth
    Supports PHP (and other langs)

    View Slide

  10. Endpoints
    $app->get('/', function($request, $response, $args) {

    // Render index view

    return $this->renderer->render($response, 'index.phtml', $args);

    });
    $app->get('/register', function($request, $response, $args) {

    // Render registration view

    return $this->renderer->render($response, ‘register.phtml', $args);

    });
    $app->get('/authenticated', function($request, $response, $args) {

    // Render protected view

    return $this->renderer->render($response, ‘authenticated.phtml', $args);

    });

    View Slide

  11. Endpoints
    $app->get('/authenticated', function($request, $response, $args) {

    if ( 

    ! isset( $_SESSION['username'] ) || 

    ! $this->users->get( $_SESSION['username'] ) 

    ) {

    return $response->withRedirect('/?error=notloggedin');

    }


    // Render protected view

    return $this->renderer->render($response, ‘authenticated.phtml', $args);

    });

    View Slide

  12. Endpoints
    $app->any('/login', function($request, $response, $args) {

    return $response->withRedirect('/?error=invalidlogin');

    });
    $app->get('/logout', function($request, $response, $args) {

    session_destroy();


    return $response->withRedirect('/?loggedout');

    });

    View Slide

  13. View Slide

  14. Middleware
    class PasswordAuth {

    private $c;


    public function __construct($cont) {$this->c = $cont;}


    public function __invoke($req, $res, $next) {

    $user = $req->getParam(‘username’);

    $pass = $req->getParam(‘password’);


    if (empty($u) || empty($p)) return $res = $next($req, res);


    if ($this->c->validAuth($user, $pass)) {

    $_SESSION[‘username’] = $user;

    return $res = $res->withRedirect(‘/authenticated’);

    }

    return $res = $res->withRedirect(‘/?error=invalidlogin’);

    }

    }

    View Slide

  15. Endpoints
    $app->any('/login', function($request, $response, $args) {

    return $response->withRedirect('/?error=invalidlogin');

    })->add(new PasswordAuth($container));

    View Slide

  16. Endpoints
    $app->any('/login', function($request, $response, $args) {

    if($request->getParam(‘magiclink’) && $request->getParam(‘username’)) {

    $user = $this->users->get($request->getParam(‘username’));

    $sent = sendMagicLink($user->email);


    if(‘ok’ === $sent[‘return’])

    return $response->withRedirect(‘/?message=checkemail’);

    }

    return $response->withRedirect('/?error=invalidlogin');

    })->add(new PasswordAuth($container));

    View Slide

  17. Middleware
    class MagicLinkAuth {

    private $c;


    public function __construct($cont) {$this->c = $cont;}


    public function __invoke($req, $res, $next) {

    $toznyo = $req->getParam(‘toznyo’);

    $toznyr = $req->getParam(‘toznyr’);


    if (empty($toznyo) || empty($toznyr)) {

    $res = $next($req, res);

    } else {

    if ($this->c->validLink($toznyo, $toznyr) {

    $user = $this->c->users->getUserFromLink($toznyo);

    $_SESSION[‘username’] = $user->username;

    $res = $res->withRedirect(‘/authenticated’);

    }

    }

    return $res;

    }

    }

    View Slide

  18. Endpoints
    $app->any('/login', function($request, $response, $args) {

    return $response->withRedirect('/?error=invalidlogin');

    })->add(new PasswordAuth($container))->add(new MagicLinkAuth($container));

    View Slide

  19. What just happened?
    Registered users can authenticate with their password
    Registered users can request a secure, one-time login link sent to their
    inbox
    The application doesn’t care which way the users authenticate

    View Slide

  20. How does this benefit us?
    One less password for users to remember
    More flexible authentication schemes for existing users
    The middleware stack could be further extended to support TOTP/HOTP/
    U2F/etc

    View Slide

  21. What are the risks?
    Your users’ accounts are only as secure as their email

    View Slide

  22. Questions?

    View Slide

  23. Thank You!
    Eric Mann - @ericmann - http://eam.me/10v - https://tozny.com

    View Slide