GithubHelp home page GithubHelp logo

guitarcade / spring-security-passwordless Goto Github PK

View Code? Open in Web Editor NEW
131.0 7.0 22.0 151 KB

Passwordless authentication example application using Spring Boot and Spring Security

License: Apache License 2.0

Shell 20.78% Batchfile 16.05% Java 51.53% CSS 2.29% HTML 9.34%
springboot springsecurity passwordless-login apache2 java

spring-security-passwordless's Introduction

Introduction

We all have a love/hate relationship with passwords. They protect our most valuable assets but they are so god damn hard to create and remember.

And just to make things even harder for us humans, more and more companies are now enforcing two factor authentication (you know, the little phone pincode thing) to make it even more complicated to login to our accounts.

Despite advances in biometric authentication (fingerprint, face recognition etc.), passwords still remain the most ubiqutous form of authentication.

So what can we do to help our fellow users to access our application in an easier manner but without compromising security?

This is where passwordless login comes in.

How does it work?

If you ever went to a website, realized you forgot your password and then used their "Forgot Password" then you know what passwordless login is.

After you entered your email address on the Reset Password page you were sent a "magic" link with a special code (a.k.a "token") embedded in it which provided you with the ability to reset your password.

That website piggy-backed on your already-password-protected email address to create a secure, one-time-password "magic" link to your account.

Well, if we can do all that in a presumably safe way when the user loses his password why can't we do it whenever a user wants to login? Sure we can.

Oh, and just in case you're wondering some big name (Slack, Medium.com, Twitter) companies are already using this method of authentication.

Alright, let's get down to business then.

The nitty gritty

  1. Create a sign-up/sign-in page. It basically needs only one field: email.
<input type="email" name="email" class="form-control" placeholder="Email address" required autofocus>
  1. Create an endpoint to handle the form submission:
  private final TokenStore tokenStore;
  private final Sender sender;

  @PostMapping("/signin")
  public String signin (@RequestParam("email") String aEmail) {
    
    // verify that the user is in the database.
    // ...
    
    // create a one-time login token
    String token = tokenStore.create(aEmail);
    
    // send the token to the user as a "magic" link
    sender.send(aEmail, token);
    
    return "login_link_sent";
  }
  1. Create an endpoint to authenticate the user based on the "magic" link:
  private final Authenticator authenticator;

  @GetMapping("/signin/{token}")
  public String signin (@RequestParam("uid") String aUid, @PathVariable("token") String aToken) {
    try {
      authenticator.authenticate(aUid, aToken);
      return "redirect:/";
    }
    catch (BadCredentialsException aBadCredentialsException) {
      return "invalid_login_link";
    }
  }

And that's about it.

Securing the "magic" link.

There are few precautions you should take to keep the "magic" link as secure as possible:

  1. When sending the link to the user communicate to your email server over SSL.

  2. Tokens should only be usable once.

  3. Tokens should not be easily guessable. Use a good, cryptographically strong random number generator. e.g:

    SecureRandom random = new SecureRandom();
    byte bytes[] = new byte[TOKEN_BYTE_SIZE];
    random.nextBytes(bytes);
    String token = String.valueOf(Hex.encode(bytes));
  1. Tokens should expire after a reasonable amount of time (say 15 minutes). In this example I use an in-memory TokenStore implementation backed by a SelfExpringHashMap which as its name suggests expires entries after a given amount of time. In a real-world scenario you will most likely use a database to store your generated tokens so your website can run on more than one machine and so these tokens survive a crash. But the principle is the same. You can have a created_at field which stamps the time the token was created so you can determine if it expired or not.

Running the demo

  1. Clone the repo:
git clone https://github.com/creactiviti/spring-security-passwordless.git
  1. Build
mvn clean spring-boot:run -Dspring.mail.host=<SMTP HOST> -Dspring.mail.username=<SMTP USERNAME> -Dspring.mail.password=<SMTP PASSWORD> -Dpasswordless.email.from=<SENDER EMAIL ADDRESS>
  1. Sign-in

Go to http://localhost:8080/signin

License

Apache License version 2.0.

spring-security-passwordless's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.