In my previous post, I demonstrated how easy it is to go from the most basic Spring Boot app to deploying multiple apps on Heroku and enabling SSO with Stormpath’s ID Site service.
In this post, I will show you how easy it is to enable Google login for your Stormpath enabled applications. While the focus here is using the ID Site service, what follows applies to the use of any of the Stormpath SDKs. That is, you get social logins out-of-the-box with any of Stormpath’s SDKs, just like you get login and registration forms.
If you haven’t already, follow the instructions in the previous post for creating and configuring your Stormpath account.
You can deploy the code used here to your Heroku account using this handy button:
Make sure the application is deployed and working in your Heroku account before continuing, because guess why? No further coding changes are necessary to enable Google Login for your application. It’s all Google and Stormpath ID Site configuration from here!
Enable Google Login
With ID Site you get typical authentication and authorization flows out of the box. You also get single sign-on. Adding in social logins is a snap as well. In this section we will setup your ID Site to allow users to login with Google.
There are no code changes and no new deploys are needed.
There are a ton of options here. The one we care about is APIs & auth -> Credentials:
Click the OAuth Consent Screen tab:
You’ll need to enter a Product Name at a minimum. Make sure you hit the Save button.
Back on the Credentials screen, choose the Add credentials dropdown and select OAuth 2.0 client ID:
Next, you’ll enter in valid origin and callback urls. The origin url is your ID Site. The format of the url is:
https://<tenant name>.id.stormpath.io
In the example I setup, the tenant name is topaz-monkey, so the authorized origin url would be:
https://topaz-monkey.id.stormpath.io
The authorized redirect urls are the same as we set up in your ID Site:
Note: If you used the Heroku deploy button at the top of this post, you will have a Heroku url to your application. You must setup the redirect urls using your Heroku app:
Click the Create button and you will get your client ID and client Secret. That’s the information we need to update the ID Site settings.
Phew! That was a lot of work to get the Google side of things setup. It’s easy from here.
Connect Google Login API to Stormpath ID Site
Jump over to your Stormpath Admin Dashboard and click the Directories tab:
Click the Create Directory button and select Google from the Directory Type dropdown. Plug in the values you just got back from Google for client ID and client Secret, as well as the Google authorized redirect:
Click the Create Directory button.
Now, the last thing before the magic – you need to add in Google as an Account Store for each of your Stormpath Applications that you want to provide Google login for. Click the Applications and select one of your Stormpath Applications. Then, click the Account Stores link on the left:
Click the Add Account Store button and select the Google Account Store you just created:
Click the Create Mappings button.
Now, the magic! Browse back to the web app you setup in your Heroku at the beginning. Click the Click here for a secret message button.
Whadya know – there’s a Google button there!
To recap, with a slightly convoluted Google configuration, and a pretty easy Stormpath Directory configuration, we’ve added in the ability for users to log in with Google. This is with no code changes and no deployments.
When you click the Google button, you get the familiar popup asking for permissions:
Once you grant the requested permissions, you are authorized to access the restricted page and are redirected there. And the same Single Sign-On we set up previously works when you’ve logged in with Google as well.
Wrapping Up
In this follow-up post, you’ve added the ability to login to your Stormpath enabled web applications with Google. You did it all by interacting with Google and Stormpath’s administrative web UIs. No additional coding or even deployment was necessary.
I hope you’ve enjoyed learning about how Stormpath can relieve you of the burden associated with authentication and authorization in your applications. I’d love to hear about your experience in working with the examples in this post.
Feel free to drop a line over to email or to me personally anytime.
It’s been slightly more than a year since we released our Express integration,
and in that time we’ve refined our approach toward web framework integrations.
While Express was our first step in the framework space, we always had a big
vision: enabling Stormpath to seamlessly work with all the great web frameworks
that exist today.
During the last year we’ve listened to your feedback and incorporated it
into the big V2 release of Express-Stormpath. In this post we’ll talk
about what we learned and what is new in the library.
Easy Integration with Angular
Developers want to use Stormpath in their front-end applications. We knew this,
but as soon as we released our Express library we had a torrent of requests for
Express + Angular. This is natural, as Express is the server-franca of most
“full-stack” projects that incorporate a rich client with a data back-end.
Angular is by far the most-requested framework, followed by React. As such we
decided to make Angular our first foray into the space, and we’ve been iterating
our Stormpath Angular SDK since early this year.
The previous version of Express-Stormpath was difficult to integrate with
Angular, but V2 of Express-Stormpath now has full JSON support, making it
incredibly easy to use with Angular. We’ve updated our Stormpath Angular
SDK to be compatible with V2.
Please note that the Stormpath Express SDK will be deprecated in favor of V2
of Express-Stormpath. The Stormpath Express SDK was an MVP of our back-
end support for Angular, but now it’s being merged with Express-Stormpath to
prevent feature duplication. We’ve had many successful migrations in that last
month, please reach out if you have any questions.
Thinking Forward to Future Frameworks
We knew that we wanted to consolidate these libraries, but we also wanted to
think forward: Angular is not the only front-end framework that we’ll be
supporting (hand wave, React!). As we planned this new version, we wanted to
ensure that the design would be generic enough to support many front-end
frameworks. This prompted us to sit down and outline the specifics of how a
front-end library should integrate with our server-side libraries.
From this we developed the Stormpath Framework Spec, a collection of
documents which outline all the specifics of how these libraries should
integrate over HTTP. This spec is framework and language agnostic. As we bring
more libraries and languages online, we want everything to be inter-operable.
All the things! It was a lot of work around the big table, but this was my
favorite part of the project.
Simplified Configuration
The framework spec drove another cleanup: how we define configuration for the
integration. We scoped this a bit larger than just the framework and cleaned up
our SDK client configuration as well. This is now being defined by the
Stormpath SDK Spec.
What does this mean for your Express app? It means that you can turn on all
the common features for a traditional website with a simple option:
{ website: true }
There are many other ways in which you can define the authentication behavior of
your app, please see the Express Configuration Documentation for full
information.
We’ve also added some really great features to the Registration
Configuration, allowing you to define your registration form with a simple
configuration object. We also take custom properties and put them in the custom
data object for you, automatically.
OAuth2 Authentication
We recently added support for the password grant flow into our API. This allows
you to generate OAuth2 access tokens for your users, complete with refresh
tokens. We manage these tokens for you, allowing you to an account’s tokens and
revoke them if needed.
Our Express integration is now leveraging these tokens. When a user logs into
your application, we exchange their login credentials for these tokens and
store them as HTTPS-only cookies in the browser. This effectively gives you
sessions-as-a-service, win!
Same Features, Better Source
We’ve kept the features that you’ve come to love, such as the loginRequired
middleware and the post-registration handlers. Behind the scenes we’ve made the
code much more readable, making it easier to see how the underlying Node SDK is
used. We found that many developers were using the Express-Stormpath source
as a guide for writing their own customized middleware handlers, so we paid
extra attention to the code quality in this release.
We’re Here to Help
As always, we want your Express application to be amazing. We’ve designed this
upgrade to be as painless as possible. Please see the Upgrade Guide for
assistance
Should you need any extra help, we’re always available on support – so hit us up!
In this release, we’ve added some new features to help with authorization and social login. Plus, there are a few more goodies under the hood.
Getting the Newest Release of the .NET SDK
As always, installing the SDK is as easy as:
install-package Stormpath.SDK
If you’re already using the SDK, then this release should be a drop-in upgrade:
update-package Stormpath.SDK
Fine-Grained Permissions with Custom Data
With Stormpath, you can store key-value pairs called custom data on resources like Accounts. This can be used for anything (you decide what’s stored!), but many of our customers find custom data is an easy way to store fine-grained permissions alongside the user accounts themselves.
In this release, it’s simple! You can create an account with custom data easily:
Then, when you authenticate a user account, you can retrieve the stored custom data values and use them to grant or restrict access in your application:
Custom data isn’t just for storing authorization data, though! Another popular use case is storing additional profile data with each user account, saving you the overhead of maintaining a separate database.
123456
// Add profile information to an existing user accounttk421.CustomData.Put("location","Death Star");tk421.CustomData.Put("cellblockNumber",1138);tk421.CustomData.Put("troopType","stormtrooper");tk421.CustomData.Put("alternateEmail","tk421@imperialxchange.com");awaittk421.SaveAsync();
Every resource can store up to 10MB of custom data, and it’s not just limited to user accounts! The .NET SDK supports saving and retrieving custom data for every Stormpath resource that has a linked customData resource. For more information, see the Custom Data documentation.
Role-Based Authorization with Groups
This release also adds support for Stormpath Groups, which make it easy to implement role-based access control.
Creating a group and assigning users to it can be accomplished with a few lines of code:
12345678
// Create a groupIGroupadmins=client.Instantiate<IGroup>();admins.SetName("Administrators");admins.SetDescription("Users who have administrator access");awaitdirectory.CreateGroupAsync(admins);// Assign a userawaitmyUser.AddGroupAsync(admins);
When handling a user request, group membership can be used to grant or restrict access:
If you need even further control, you can also use custom data to store fine-grained permission rules on the accounts, or even on the groups themselves. This makes modeling complex permissions models for your application a cinch.
Easy Facebook, Google, Github, and LinkedIn Login
If you’re building a web application and want to add social login support, rolling your own code to interact with the specific authentication flows for each provider can be a pain. Stormpath abstracts away a lot of that complexity, letting you focus on actually building your application instead.
With this release, we’ve added support for exchanging a token from a social login provider for a Stormpath user account. All you have to do is redirect the user to the appropriate social login page, and capture the callback token that is sent back to you. Then, create a request to Stormpath. For example, for Facebook login:
1234567891011
// accessToken = the callback token provided by Facebookvarrequest=client.Providers().Facebook().Account().SetAccessToken(accessToken).Build();varresult=application.GetAccount(request);// true if this account didn't previously exist in StormpathboolisNewAccount=result.IsNewAccount;// the Stormpath account details, pulled from FacebookIAccountaccount=result.Account;
That’s it! For more information on how social login works in Stormpath, refer to the documentation.
In our forthcoming ASP.NET integration, this process will be even easier, with drop-in support for Facebook, Google, Github, and LinkedIn login buttons.
New Account Email Verification
This release also adds support for verifying that the e-mail address of a new account is valid.
If an account is created in a Stormpath Directory that has the Verification workflow enabled, an e-mail will automatically be sent to the new user with a callback URL that includes an sptoken parameter. This token can be used to verify that the user’s email address is correct.
When your application receives the token, you simply have to send it back to Stormpath:
12
// token = the ?sptoken parameter passed to your applicationIAccountverifiedAccount=awaitclient.VerifyAccountEmailAsync(token);
If the token is valid, the account details are returned and the account is marked as verified in Stormpath. For more information on how the verification flow works, see the documentation.
What’s Next
There’s plenty more to come! Here’s what’s on the roadmap:
At Stormpath, we spend a lot of time designing features to help developers build applications using best practices for authentication, authorization, and user data security.
Now, Stormpath makes it easy for developers to generate OAuth 2.0 access tokens. This new feature gives your applications a way to authorize requests for other applications and micro-services that you own.
Developers often come to us with these questions:
How do I secure my API so only authenticated users can access it?
How do I manage stateless tokens and still control access after a logout or if I need to revoke a token?
How to do I store session information in my application that doesn’t incur state on my server or APIs?
Stormpath OAuth Support allows you to do all these things, and this post will show you how to use this feature , or at least understand of the functionality required for a good token management system. You can also go straight to the deep documentation on how to use Stormpath to manage tokens in our Token Management Guide.
Before we get into the nitty gritty though…
A Crash Course in Token-Based Authentication and Management
Token-based authentication secures an application based on a security token that is generated for the user on authentication. Since HTTP is considered stateless, if your application authenticates a user (one HTTP request), your application won’t know who the user is on the next request. This is why many applications pass some information to tie the request to a user. Traditionally, this information usually requires state to be stored on the server and a session identifier to be stored on the client.
Token-based authentication is all about removing the need to store information on the server while giving extra security to keep the token secure on the client. This helps you as a developer build stateless, scalable applications or services.
Stormpath complies with OAuth 2.0 to provide this functionality.
Why OAuth 2.0?
OAuth 2.0 is an authorization framework. It’s a protocol that defines how to delegate authentication or provide authorization. OAuth 2.0 is prevalent across many mobile and web applications today. If you have ever logged into a website using Facebook or Google, you have used one of OAuth 2.0’s many authorization flows. You can read more about the different OAuth 2.0 authorization flows or grant types in this great article by Randall Degges.
OAuth 2.0 supports many authorization grant types. Among them, Stormpath currently supports:
Password Grant Type that grants the ability to get an Access Token based on a login and password for your application.
Client Credentials Grant Type (which is supported through our API Key Management feature) that grants the ability to exchange an API Key for the Access Token.
Refresh Grant Type that grants the ability to generate another Access Token based on a special Refresh Token.
Managing OAuth 2.0 Access and Refresh Tokens
OAuth 2.0 gives us two types of tokens to manage:
Access Tokens
Refresh Tokens
The Access Token grants access to a protected resource or API. The Access Token that Stormpath generates for accounts on authentication is a JSON Web Token, or JWT. The JWT makes sure that the Access Token is not tampered with on the client and is only valid for a specified duration.
The Refresh Token is a special token used to generate additional Access Tokens. This allows you to have a short-lived Access Token without having to collect credentials from the user every single time you need a new Access Token.
When using OAuth 2.0, the Access Token and Refresh Token are returned in the same response during the token exchange, this is called an Access Token Response.
How to Use Stormpath for Token Management
Now to the fun part, the code!
When building this type of functionality, there are four discrete tasks to handle: generating tokens, validating tokens, refreshing tokens, and revoking tokens.
Before you can manage and validate tokens for authorization, you need to generate a token. Stormpath exposes an OAuth 2.0 endpoint off of your Stormpath Application href, which the SDKs use to generate tokens. Generating a token from your client can either implement it’s own OAuth 2.0 endpoints (meaning it is just a proxy to Stormpath), or you can just collect the credentials from the client and use the SDK.
Generating a token requires that the account exists in Stormpath, is associated with the Stormpath Application generating the token, and provides valid credentials for the account.
varstormpath=require('stormpath');/* * Initialize an API Key to communicate with the Stormpath API. * To get an API Key, follow the steps here: * http://docs.stormpath.com/nodejs/quickstart/#get-an-api-key */varapiKey=newstormpath.ApiKey(process.env['STORMPATH_API_KEY_ID'],process.env['STORMPATH_API_KEY_SECRET']);/* * Get your application href, by visiting the Stormpath Admin * Console, or by following: * http://docs.stormpath.com/nodejs/quickstart/#retrieve-your-application */varapplication_href='https://api.stormpath.com/v1/applications/3QIMlJKKN2hGCYzXXw1t8';//Initialize the Stormpath Client with your API Getvarclient=newstormpath.Client({apiKey:apiKey});varapplication;//Retrieve your applicationclient.getApplication(application_href,function(err,app){application=app;//Create an OAuthAuthenticatorvarauthenticator=newstormpath.OAuthAuthenticator(application);/* * Instruct the authenticator to authenticate using the password grant type * for an account you created in one of your application's account stores. * We are using a hard coded user name and password, you would collect this * from a user in a real life scenario. */authenticator.authenticate({body:{grant_type:'password',username:'tom@stormpath.com',password:'stayawayandromeda'}},function(err,result){console.log(result.accessTokenResponse);//A successful request will result in an accessTokenResponse});});
The access and refresh token expirations are configurable because different applications may have different requirements around how long a token should live. Or, how often the user should need to provide his credentials for using the application (which would be controlled by the refresh token expiration). By default, Stormpath access tokens expire in one hour, and the refresh tokens expire in 60 days.
The access token response has the following structure:
This response tells you exactly when the access token will expire. There is also a stormpath_access_token_href which gives you the location of the access token in Stormpath. This is useful if you need to revoke the token.
The long string of characters that represent the access token and refresh tokens are JSON web tokens, or JWT. The JWT is signed with your API Key Secret used to initialize the client. This is useful if you need to validate the signature locally using a JWT library.
Once your application has the access token, it can be stored on the client and passed on additional requests to your application or API.
How To Validate OAuth Tokens
Once you have generated a token, you usually deliver it back to the client that requested it. The client then stores it and passes the access token property on requests to your application. This is usually done with either a cookie value, or authorization header in HTTP. For example:
Validating the token allows you to authorize the authenticity of the token (by verifying that it hasn’t been tampered with via a digital signature) and get information about who the token belongs to by the claims stored in the token.
Once you receive an access token, there is a couple ways you can validate it. Locally, and using Stormpath. To illustrate what is validated if you do it locally or with Stormpath:
Validation Criteria
Locally
Stormpath
Token hasn’t been tampered with
yes
yes
Token hasn’t expired
yes
yes
Token hasn’t been revoked
no
yes
Account hasn’t been disabled, and hasn’t been deleted
no
yes
Issuer is Stormpath
yes
yes
Issuing application is still enabled, and hasn’t been deleted
no
yes
Account is still in an account store for the issuing application
no
yes
Why is this important? Because the level of validation that each application needs may differ. If you need to validate the state of the account / application or if you need to use token revocation, then using Stormpath to validate the token is the obvious choice. This does require a request to the Stormpath REST API. If you only require that the token has not expired and has not been tampered with, you can validate the token locally and minimize the network request to Stormpath.
/* This sample uses NJWT a Node JWT Library (https://github.com/jwtk/njwt) */varnJwt=require('nJwt');nJwt.verify(token,process.env['STORMPATH_API_KEY_SECRET'],function(err,verifiedJwt){if(err){console.log(err);// Token has expired, has been tampered with, etc}else{console.log(verifiedJwt);// Will contain the header and body}});
How To Refresh OAuth Tokens
Passing access tokens for authorization allows access to resources in your application. But what happens when the access token expires? You could require the user to authenticate again, or use the refresh token.
A refresh token allows you to generate new access tokens for a user without collecting credentials again. It give an elegant way of changing out an access token with a new one without effecting the user experience.
For example, if you generated an access token response with a access token expiration of 30 minutes and a refresh token time of 1 day, you would be able to generate a new access token when the old one expires (every 30 minutes) for 24 hours straight. Once the access token expires after 1 day timer, the refresh token will also expire, and the user will need to login again.
Stormpath gives you the ability to quickly refresh a token if for example it expires.
Revoking tokens is an important feature for managing tokens, especially for a couple different scenarios:
The user has explicitly logged out, and your application needs to revoke their access, requiring authentication again.
The application, device, or client has been compromised and you need to revoke tokens for an account.
Stormpath gives you the ability to quickly revoke the token, just by deleting it. There are a couple ways you can get the access token or refresh token to revoke:
Query the collection of accessTokens or refreshTokens on an account.
Using the stormpath_access_token_href property in the access token response.
Validate the token using the Stormpath API, which will return the access token.
Once you have the token you want to revoke, just delete it:
I am sure every PHP developer has struggled with storing user information on a server to identify the source of a request. Since HTTP is a stateless system, this has been the only way to tell who a user is. Until now! We’ve built Token Authentication directly into the PHP SDK for your applications.
Token based authentication in the PHP SDK removes the need to store information on the server, and allows you to keep tokens secure on the Client. Using Stormpath to generate and verify these tokens for you, access to your web application can be restricted at any time by removing a token from an account.
The Benefits of Token Authentication in PHP
Authentication in PHP is always a pain point for developers. Since PHP is a stateless language, it is up to the developer to decide how to store user information for future requests. Typically, this is done by setting a cookie or some other session variable to keep track, but as we’ve written about before, this can be insecure. Using Token Authenticationin your PHP application lets you allow the user to log in with username and password once, store the access token and refresh token, and then store that on the client. All future requests will be made using the access token to identify the user. This makes your web application much more secure.
The other primary benefit of using Token Authentication for your PHP application is scalability. If you are storing session information about a user on the server, you would have to make sure your user is always hitting the same server for each request. There are some other ways to do this, but the easiest way is to store the access token on the
client side and just sign each request with this.
Configuring OAuth Access and Refresh Tokens
The first thing to do is set up your application to allow for Token Management. A new resource has been added to the PHP SDK for managing your application’s OAuth policies. This resource gives you access to the TTLs for tokens of the application. The values of the TTLs are stored and set as ISO 8601 durations. By default, the application access
token is set to 1 hour (PT1H) and the refresh token is set to 60 days (P60D).
To get the values of the OAuth policy, run the following code:
Now that you have your TTLs setup for your application, you can generate an access token. During the login process, you would make a request to generate an access token for the user. This is now built into the PHP SDK and can be accomplished in just a few lines of code.
This allows you to store the access and refresh tokens on the client side for all future requests.
Verifying OAuth Access Tokens
Verification of the access token is an important part of using Token Authentication. There are two ways to verify the token. The first way is to let Stormpath verify it for you, which is the simplest and most effective way. The second way is to validate it locally. However, there are a few things that you will miss out on by validating it locally.
Verify Access Tokens via Stormpath
In order to let Stormpath verify the access token for you, you only need to request it from the resource.
While you are using your access tokens, there will be a time when you need to refresh them. We’ve also built this into the PHP SDK to make it an easy task to accomplish.
This will return a new access token that you can use for future requests.
Deleting OAuth Access Tokens
So, there comes a time when a user does something where you would want to remove their access. This is one of the powerful functions of using tokens for authentication in PHP. Looking at the old way of doing things, if you needed to remove access to a user, they could still use the system if you are storing a session or cookie. This can cause a headache for you if the user is doing things to hurt your application. With token verification via Stormpath, the user will not be allowed to make the very next request.
That’s it! On the next request they make, you will be able to check the access token and find out they are not allowed into your system. You could even display a fun little message.
Give It a Try
There are great reasons why you would want to use Token Authentication on your next PHP web application. Give the PHP SDK a try for your next project or even integrate it into your existing applications now.
Feel free to drop a line over to Support or to Me personally anytime.
Building command line programs has been a long time passion of mine. There’s
something magical about making a simple, intuitive, and composable CLI. There’s
nothing more beautiful than chaining together a series of CLI programs to solve
a complex problem quickly.
Here at Stormpath, we’ve built our entire product CLI in Python to
create / manage / edit users for your applications, and have
been really happy with the result.
Most of this is thanks to the wonderful docopt library, which provides
automatic CLI argument parsing and makes building complicated CLIs incredibly
simple. And the best part? It works across more than 20 different
programming languages! This means that even if you’re building a new CLI app
in Go, Rust, or something in between, chances are you can use docopt, too!
If you want to know how to structure your next CLI based app to minimize
complexity and maximize awesomeness, keep reading.
An Overview of CLI Tools
For the purposes of this article, we’re going to be building a really simple CLI
called skele that works via subcommands.
There are typically two types of CLI tools that people build: single and
multi-command. A good example of a single command CLI tool would be the
grep command.
This is because the grep tool takes various options, but does only one thing:
match text.
For instance, if I wanted to search a file for my name, I might run the
following command:
1
$ grep 'Randall' some-file.txt
On the other hand, there are CLI tools that operate via sub-commands, and do
many things. These tools are typically harder to build as they have more
complexity.
A good example of sub-command driven CLI tool would be the Heroku CLI tool.
This tool allows you to create new web applications, deploy them live, and
provision resources for these applications — all via sub-commands.
For instance, if I wanted to create a new Heroku application, I might run the
following command:
1
$ heroku applications:create my-new-app
In the example above, applications:create is the name of a sub-command.
If I wanted to later remove my application from Heroku, I could then say:
1
$ heroku applications:destroy my-new-app
See how the one CLI tool can perform different actions? Well, that’s what we’ll
be building today. A CLI tool that is capable of simply running sub-commands
and handling them in a graceful way.
The specific CLI tool I’ve built as reference material for this article is
called skele, and can be found on this Github page.
This tool ships with a single sub-command hello, that just prints some text to
the console. It also includes a manual page, help information, and version
information in a standard UNIX-compliant manner.
So, on with the show!
Structuring a CLI Project in Python
Before we dive into all the specifics regarding how to build good CLI based
applications, let’s first talk about structuring your project properly.
There are an infinite amount of ways to structure Python projects, but for CLI
apps in particular, I like the following approach the best as it is straightforward, and keeps things simple.
Now, I’ll explain how I’ve structured my skele app below, but if you
want to skip ahead and just look at the source code to figure out how things
work, here’s a link to the Github page.
Here’s what the project structure of skele looks like — this is a good base
to work off if you’re designing a new CLI tool from scratch:
As you’ll notice above, I’m pro-actively removing and excluding a lot of
unnecessary files that would otherwise get included in the package.
Whenever you build your Python package, this file will be scanned by the
Python build tool, and these rules will be used to remove or add files in your
package accordingly.
In particular, I don’t like including private git folders, build folders,
coverage reports, etc. in my package builds, as it unnecessarily clutters up a
user’s system.
Next up, you’ve got the setup.cfg file. This file just tells the Python
build tool that your program should run on all platforms when building the
binary. If this isn’t true for your specific project, you can remove this
file.
NOTE: For 99.99% of people, you’ll want to leave this file alone =)
123
# setup.cfg
[bdist_wheel]universal=1
Finally, you’ve got the setup.py file. This is where you tell Python all
about your CLI tool and how it is packaged up.
Now, the next file we’re going to look at is quite large (setup.py), so I
won’t copy / paste all the contents here, if you want to view the entire
thing, check it out on Github: https://github.com/rdegges/skele-cli/blob/master/setup.py
Here’s the important / cool bits you should know about:
This setup script will automatically use your README.rst file for
documentation. This is nice because when you deploy your package to PyPI,
it will have legitimate looking documentation:
This setup script includes testing support via the popular py.test library
(and coverage reporting, too!). This means that if you run the $ python
setup.py test command, your entire package will be tested nicely (assuming
you write tests, that is). Here’s the code that makes this possible:
123456789101112131415
classRunTests(Command):"""Run all tests."""description='run tests'user_options=[]definitialize_options(self):passdeffinalize_options(self):passdefrun(self):"""Run all tests!"""errno=call(['py.test','--cov=skele','--cov-report=term-missing'])raiseSystemExit(errno)
This setup script won’t accidentally install your documentation or tests on
the user’s system as actual packages. This happens quite frequently, and
causes nasty namespace collisions. The relevant bit of code that prevents
this from happening can be seen below:
This setup script can install all development dependencies easily — this
means that if you’re cloning this project fresh, and want to work on it for
development purposes, you can run the $ pip install -e .[test] command and
the entire CLI program as well as all test dependencies will be installed!
Lastly, this script ensures that your CLI program is started correctly when
ran from the command line. If a user installs your CLI program, they’ll be
able to run it by simply typing the program name, in this case, $ skele on
the terminal:
Now that we’ve covered the Python packaging files, let’s talk about the actual
CLI package itself! How do we structure our actual Python code?
The first thing we’ll need is a package (a folder in this case) called skele
— as this is our application’s name.
Inside of this folder there are two files we need to quickly discuss.
First, the __init__.py file. The only thing this file contains is our
program’s version number:
12
# __init__.py__version__='1.0.0'
This version number is what you’ll update when you make new releases.
Next, we’ve got our cli.py file — this is where most of the magic happens.
This file contains a function named main which is the code that will actually
run when a user types $ skele on the command line.
The reason this function is the one that runs is because of the code we setup
previously in our setup.py file:
https://github.com/rdegges/skele-cli/blob/master/setup.py#L64-L68 (these lines
of code tell Python to execute this particular function when our program is ran).
So, next up we’ve got our commands module (another folder). This module
contains the actual implementation of our CLI commands.
If you take a look in this folder, you’ll see the following files defined:
__init__.py – This contains our import statements.
base.py – A base command class that all other classes will extend.
hello.py – This is an example command implementation.
If I was building a CLI app that could be used by typing:
12
$ skele hi
$ skele bye
Then I’d have two new Python files in my commands folder: hi.py and
bye.py. This is how I like to structure things to keep things as simple as
possible.
So now that we’ve covered the basic layout, let’s talk about the actual
implementation.
Using docopt to Build a Simple CLI
I love the docopt library. It makes defining CLI interfaces incredibly
simple.
The way docopt works is pretty magical: instead of writing rules and telling
your program what options to look for, you instead just define the manual page
for your CLI program, and docopt will automatically parse this string for
you, and generate all the option parsing code!
Here’s how it works in the skele example application I’ve built. This is the
cli.py file source code (notice the big docstring at the top of the file):
"""skeleUsage: skele hello skele -h | --help skele --versionOptions: -h --help Show this screen. --version Show version.Examples: skele helloHelp: For help using this tool, please open an issue on the Github repository: https://github.com/rdegges/skele-cli"""frominspectimportgetmembers,isclassfromdocoptimportdocoptfrom.import__version__asVERSIONdefmain():"""Main CLI entrypoint."""importcommandsoptions=docopt(__doc__,version=VERSION)# Here we'll try to dynamically match the command the user is trying to run# with a pre-defined command class we've already created.fork,vinoptions.iteritems():ifhasattr(commands,k):module=getattr(commands,k)commands=getmembers(module,isclass)command=[command[1]forcommandincommandsifcommand[0]!='Base'][0]command=command(options)command.run()
That huge docstring at the top of the file is standard CLI documentation, right?
It looks like the output you see when you run a CLI program. It lists how to
use the program, how it works, and what options are available.
Well, what happens here is that down below, in the main function, I’m using
the docopt library to parse that huge docstring and generate a list of options
automatically:
12
# __doc__ is a special variable that references this file's docstring.options=docopt(__doc__,version=VERSION)
If you go ahead and print out the options variable, you’ll see something
similar to the following (depending on how you ran the program):
1234
# `$ skele hello` is the command I ran to output these options.{'--help':False,'--version':False,'hello':True}
Pretty amazing, right? docopt generated a dictionary of options that have
already been parsed and validated automatically.
Notice how the hello variable is set to True? This means that the user
typed $ skele hello command =)
Now, since we know that docopt is already handling the hard stuff:
Parsing our CLI documentation into real options.
Generating a dictionary of options.
All we have to do is run call the appropriate code to run, right?
In the above example, we’re running the $ skele hello command on the CLI — so
in the next section, we’ll take a look at how to hook that logic into our app.
Defining Commands in the CLI Program
When building a CLI program, most of the time your program is going to do
different things based on what sub-commands are being run.
For instance, in our example skele application, I might want to define several
sub-commands so that a user can run:
123
$ skele hello # say hello, world!$ skele bye # say bye!# etc...
In the example above, I’m referring to both hello and bye as sub-commands.
The way I’ve structured the skele sample app is such that you can define a
Python file for each sub-command you want to support, and it will get ran
automatically when the user specifies that command.
Let’s take a look at how a command works. We’ll start by looking at the
hello.py file:
123456789101112131415
# skele/commands/hello.py"""The hello command."""fromjsonimportdumpsfrom.baseimportBaseclassHello(Base):"""Say hello, world!"""defrun(self):print'Hello, world!'print'You supplied the following options:',dumps(self.options,indent=2,sort_keys=True)
The idea is that each command will have a class inside of it that extends from
Base. Here’s what base.py looks like:
1234567891011121314
# skele/commands/base.py"""The base command."""classBase(object):"""A base command."""def__init__(self,options,*args,**kwargs):self.options=optionsself.args=argsself.kwargs=kwargsdefrun(self):raiseNotImplementedError('You must implement the run() method yourself!')
Whenever we construct a new instance of a command class, we’ll pass in the
options that were generated using docopt. This way, each sub-command has access
to all the user supplied CLI information.
Finally, we’ll define a run method on each command class, and this is what
we’ll call to actually do something the user wants. This is where we’ll put
our logic.
In the hello.py example, we’re simply going to say Hello, world! and output
the options.
Now, going back to the cli.py file, let’s take a look at how we actually use
these command classes to get stuff done:
123456789101112131415
# skele/cli.pydefmain():"""Main CLI entrypoint."""importcommandsoptions=docopt(__doc__,version=VERSION)# Here we'll try to dynamically match the command the user is trying to run# with a pre-defined command class we've already created.fork,vinoptions.iteritems():ifhasattr(commands,k):module=getattr(commands,k)commands=getmembers(module,isclass)command=[command[1]forcommandincommandsifcommand[0]!='Base'][0]command=command(options)command.run()
What we’re doing here is this:
We parse the CLI options from the user via docopt.
We loop through the CLI options.
If there is a command module whose name matches a CLI option, then we’ll
dynamically figure out the name of the command class.
After getting the command class, we’ll create an instance of it, passing along
the user supplied options from docopt.
Finally, we’ll call the run method on our class, which will actually make
stuff happen.
If we were to say $ skele hello, for instance, here’s what would happen:
We’d loop through the commands module and find that commands.hello is a
valid Python module.
We’d then figure out that Hello is the name of the class we’ve defined
inside that file.
Finally, we’ll create a new instance of a Hello class, and call the run
method.
All together now, this is what makes our CLI program work!
This is pretty cool because it means that adding or changing our CLI interface
is as simple as modifying the docstring we’ve defined in skele/cli.py, as well
as creating a proper command in our commands directory.
Simple, right?
Building CLIs Made Simple
By utilizing the awesome docopt module, and structuring your project the
right way, building simple CLI programs can be really easy!
Be sure to check out skele-cli on Github for reference, and if you’re looking for more information about Python packaging best practices, be sure to check out the official Python packaging guide.
In my previous post, I demonstrated how easy it is to go from the most basic Spring Boot app to deploying multiple apps on Heroku and enabling SSO with Stormpath’s ID Site service.
In this post, I will show you how easy it is to enable Google login for your Stormpath enabled applications. While the focus here is using the ID Site service, what follows applies to the use of any of the Stormpath SDKs. That is, you get social logins out-of-the-box with any of Stormpath’s SDKs, just like you get login and registration forms.
If you haven’t already, follow the instructions in the previous post for creating and configuring your Stormpath account.
You can deploy the code used here to your Heroku account using this handy button:
Make sure the application is deployed and working in your Heroku account before continuing, because guess why? No further coding changes are necessary to enable Google Login for your application. It’s all Google and Stormpath ID Site configuration from here!
Enable Google Login
With ID Site you get typical authentication and authorization flows out of the box. You also get single sign-on. Adding in social logins is a snap as well. In this section we will setup your ID Site to allow users to login with Google.
There are no code changes and no new deploys are needed.
There are a ton of options here. The one we care about is APIs & auth -> Credentials:
Click the OAuth Consent Screen tab:
You’ll need to enter a Product Name at a minimum. Make sure you hit the Save button.
Back on the Credentials screen, choose the Add credentials dropdown and select OAuth 2.0 client ID:
Next, you’ll enter in valid origin and callback urls. The origin url is your ID Site. The format of the url is:
https://<tenant name>.id.stormpath.io
In the example I setup, the tenant name is topaz-monkey, so the authorized origin url would be:
https://topaz-monkey.id.stormpath.io
The authorized redirect urls are the same as we set up in your ID Site:
Note: If you used the Heroku deploy button at the top of this post, you will have a Heroku url to your application. You must setup the redirect urls using your Heroku app:
Click the Create button and you will get your client ID and client Secret. That’s the information we need to update the ID Site settings.
Phew! That was a lot of work to get the Google side of things setup. It’s easy from here.
Connect Google Login API to Stormpath ID Site
Jump over to your Stormpath Admin Dashboard and click the Directories tab:
Click the Create Directory button and select Google from the Directory Type dropdown. Plug in the values you just got back from Google for client ID and client Secret, as well as the Google authorized redirect:
Click the Create Directory button.
Now, the last thing before the magic – you need to add in Google as an Account Store for each of your Stormpath Applications that you want to provide Google login for. Click the Applications and select one of your Stormpath Applications. Then, click the Account Stores link on the left:
Click the Add Account Store button and select the Google Account Store you just created:
Click the Create Mappings button.
Now, the magic! Browse back to the web app you setup in your Heroku at the beginning. Click the Click here for a secret message button.
Whadya know – there’s a Google button there!
To recap, with a slightly convoluted Google configuration, and a pretty easy Stormpath Directory configuration, we’ve added in the ability for users to log in with Google. This is with no code changes and no deployments.
When you click the Google button, you get the familiar popup asking for permissions:
Once you grant the requested permissions, you are authorized to access the restricted page and are redirected there. And the same Single Sign-On we set up previously works when you’ve logged in with Google as well.
Wrapping Up
In this follow-up post, you’ve added the ability to login to your Stormpath enabled web applications with Google. You did it all by interacting with Google and Stormpath’s administrative web UIs. No additional coding or even deployment was necessary.
I hope you’ve enjoyed learning about how Stormpath can relieve you of the burden associated with authentication and authorization in your applications. I’d love to hear about your experience in working with the examples in this post.
Feel free to drop a line over to email or to me personally anytime.
Here at Stormpath, we <heart> Spring Boot. It makes it so easy and fun to build rich Java webapps.
We’re very excited for our latest Java SDK release which includes a major overhaul to our Spring Security and Spring Boot support.
If you’ve built a web app before, you know that all the “user stuff” is a royal pain. Stormpath gives developers all that “user stuff” out-of-the-box so you can get on with what you really care about – your app! By the time you’re done with this tutorial ( < 15 minutes, I promise), you’ll have a fully-working Spring Boot webapp that protects user access to restricted paths with Spring Security and is backed by Stormpath.
We’ll focus on our Spring Boot integration to roll out a simple Spring Boot web application, with a complete user registration and login system, with these features:
Login and Registration pages
Password reset workflows
Restricting access according to Group membership
The ability to easily enable other Stormpath features in our Java library (API authentication, SSO, social login, and more)
In this demo we will be using the stormpath-default-spring-boot-starter. Its modular design bakes in Spring Boot 1.2.5 and Spring Security 4.0.2 as well as Spring Boot WebMVC and the Thymeleaf templating engine. I will be using my Mac, the Terminal app, and the IntelliJ IDE.
Throughout this post, you can see the example code in action by clicking on the Deploy to Heroku button. All you need to do is register for a free Heroku account.
What Is Stormpath?
Stormpath is an API service that allows developers to create, edit, and securely store
user accounts and user account data, and connect them with one or multiple applications. Our API enables you to:
In short: we make user account management a lot easier, more secure, and more
scalable than what you’re probably used to.
Ready to get started? Register for a free developer account here.
Start Your Spring Boot Project
Got your Stormpath developer account? Great! Let’s get started…
Whether you are a Maven maven or Gradle grete, getting your project setup is a snap.
Here’s a pom.xml file to start with:
12345678910111213141516171819202122232425262728
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.stormpath.sample</groupId><artifactId>stormpath-spring-boot-spring-security-tutorial</artifactId><version>0.1.0</version><name>Spring Boot Spring Security Stormpath Tutorial</name><description>A simple Spring Boot Web MVC application with Spring Security and out-of-the-box login and self-service screens!</description><dependencies><dependency><groupId>com.stormpath.spring</groupId><artifactId>stormpath-default-spring-boot-starter</artifactId><version>1.0.RC5.1</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
You may notice that both for Maven and Gradle there is a single dependency: stormpath-default-spring-boot-starter. Yup. That’s it. As you will see below, that one dependency gives you all of the Spring Boot, Spring Security and Stormpath magic at once.
Gather Your API Credentials and Application Href
The connection between your app and Stormpath is secured with “API Key Pair”. You will provide these keys
to your web app and it will use them when it communicates with Stormpath.
You can download your API key pair from our Admin Console. After you log in you can download your API key pair from the homepage, it will download the apiKey.properties file – we will use this in a moment.
While you are in the Admin Console you want to get the href for your
default Stormpath Application. In Stormpath, an Application object is used to
link your web app to your user stores inside Stormpath. All new
developer accounts have an app called “My Application”. Click on “Applications”
in the Admin Console, then click on “My Application”. On that page you will see
the Href for the Application. Copy this — we will need it later.
Writing the Spring Boot Application
The code for this section can be found in the LockedDown tag of the code repo.
We need three small Java classes and an html template to fire up the first version of our webapp. They’re small enough that I will put them right here. Let’s get to it!
Spring Boot Application Entry Point
All Spring Boot applications have an entry point that works just like an ordinary Java program. It has a main method and everything.
6 lines of code including the @SpringBootApplication annotation kicks off the party.
Spring Security Configuration
By default (and by best security practices), Spring Security locks down your entire application. It locks it down to the point that it’s not even accessible! While this conforms to best security practices, it’s not terribly useful. Additionally, we need to hook Spring Security and Stormpath together. That brings us to our SpringSecurityWebAppConfig.java:
For now, the class is completely empty. the @Configuration annotation causes Spring Boot to instantiate this class as a configuration. Extending StormpathWebSecurityConfigurerAdapter hooks all of the Stormpath goodness (authentication and authorization workflows) into Spring Security.
Because the class is empty, we will still see the default behavior of having everything locked down. However, instead of the default Spring Security authentication flows, we will see the default Stormpath flows. That is, attempting to browse to any path in the application will result in a redirect to the Stormpath login page.
So, 2 lines and we’ve got security!
Spring WebMVC Ties It All Together
Our security configuration above ensures that all paths in the application will be secured.
A Controller determines how requested paths get directed to display which templates.
The @Controller annotation signals Spring Boot that this is a controller. We have one path defined on line 3, /. Line 5 returns the Thymeleaf template named home.
7 lines of code and we have Model-View-Controller (MVC) routing.
Bring Us home.html
By default, the Thymeleaf templating engine will look for templates returned from controllers in a folder called templates in your classpath. It will also look for the default extension of .html.
So, when our controller above returns "home", Thymeleaf will find the template in resources/templates/home.html.
Line 3 looks like an html/xml comment. However, this is a directive that Thymeleaf picks up on to include a fragment in this template. The fragment is found at: resources/templates/fragments/head.html. This fragment contains all the setup to hook in Bootstrap styling for our views.
Lines 13 and 14 is where the action is. Since every pathway in our application is locked down, we know that the only way to get to this page is after having logged in. Part of the Stormpath magic is that once logged in, an account object is always in scope to your views. Line 13 shows the logged in user’s full name. Line 14 provides a link to log out when clicked.
For more information on working with Thymeleaf templates, click here.
Let’s Fire It Up!
Creating a Stormpath account, 15 lines of Java code and 19 lines of html template code (3 of which are significant) has brought us to the point of a fully functional Spring Boot WebMVC app protected by Spring Security and backed by Stormpath.
If you stored your apiKey.properties file from before in the standard location: ~/.stormpath/apiKey.properties and if you have only the default Stormpath Application that was created for you, no other configuration is necessary to start up the application.
By adding STORMPATH_API_KEY_FILE and STORMPATH_APPLICATION_HREF environment variables to the command line, we can easily tell our app where to find the api keys and which Stormpath Application to use.
The Stormpath Java SDK has an extremely flexible configuration mechanism. We will see more of that below when we get to restricting access to your application by Stormpath Group membership.
Refined Access Control With Spring Security
The code for this section can be found in the BasicAccessControl tag of the code repo.
In the previous section, we created an application that was locked up tight. Every path, including /, required you to be logged in first.
Perhaps you want a publicly accessible home page. Perhaps you want some parts of the site that any authenticated user can get to and another part of the site where only members belonging to a particular group can get to.
We are going to explore those fine grained controls in this section.
We’ll start by allowing public access to the home page. Users will still have to authenticate to access any another page.
Spring Security: Your Bouncer at the Door
Remember our empty SpringSecurityWebAppConfig.java from before? We are going to add a little something to it now:
On Lines 5 – 7 above, we are building up a rule set for how Spring Security will allow access to our application.
You might state it like this in plain English:
Permit anyone to go to the front door
Ensure that they've authenticated for anything else
The rules we are specifying take precedence before the default behavior of locking everything down.
Let’s update our home.html template as well:
1234567891011121314151617181920212223242526272829
<htmlxmlns:th="http://www.thymeleaf.org"><head><!--/*/ <th:block th:include="fragments/head :: head"/> /*/--></head><body><divclass="container-fluid"><divclass="row"><divclass="box col-md-6 col-md-offset-3"><divclass="stormpath-header"><imgsrc="https://stormpath.com/images/template/logo-nav.png"/></div><!--/* displayed if account IS NOT null, indicating that the user IS logged in */--><divth:if="${account}"><h1th:inline="text">Hello, [[${account.fullName}]]!</h1><ahref="/restricted"class="btn btn-primary">Restricted</a><ath:href="@{/logout}"class="btn btn-danger">Logout</a></div><!--/* displayed if account IS null, indicating that the user IS NOT logged in */--><divth:unless="${account}"><h1>Who are you?</h1><ahref="/restricted"class="btn btn-primary">Restricted</a></div></div></div></div></body></html>
Notice how we now have two distinct sections. The first starts on line 13 and is displayed if the user is logged in.
The second section starting on line 20 is displayed if the user is not logged in.
This is Thymeleaf templates in action. It provides very powerful controls for conditionally showing parts of a template.
Before we make any additional changes, let’s pause here and startup the app as before.
When you browse to http://localhost:8080, you’ll see the unauthenticated version of the home template.
Cick the Restricted button, and you’ll be redirected to the login form as expected. After you authenticate, you’ll end up at a 404 page, because we haven’t defined the restricted page yet.
Let’s set that up to finish up this section.
Defining the restricted page is as easy as adding a route in our controller and creating a template to show. Here’s the updated HelloController.java:
<htmlxmlns:th="http://www.thymeleaf.org"><head><!--/*/ <th:block th:include="fragments/head :: head"/> /*/--></head><body><divclass="container-fluid"><divclass="row"><divclass="box col-md-6 col-md-offset-3"><divclass="stormpath-header"><imgsrc="https://stormpath.com/images/template/logo-nav.png"/></div><h1th:inline="text">[[${account.fullName}]], You are allowed here.</h1><ahref="/"class="btn btn-primary">Go Home</a></div></div></div></body></html>
Notice how we re-use the head fragment to provide Bootstrap styling for this template.
Re-start the app again, and you will get the full experience. Take note of how the home page changes depending on whether or not you are logged in.
Spring Security Access Control By Group Membership
The code for this section can be found in the GroupAccessControl tag of the code repo.
Spring Security provides a set of annotations and a rich expression language for controlling access to methods in your application. Among the most commonly used Spring Security Annotations is @PreAuthorize. And, among the most commonly used SpringEL expressions is hasRole.
Stormpath integrates with this mechanism connecting Stormpath Groups to Spring Security roles.
Let’s look at the code for this and then break it down. We are going to add a new service that restricts access by Group membership. Here’s AdminService:
Line 3 above is the key, here. The annotation along with the SpringEL expression could be stated in plain English as:
Before this method is even entered,
check to see that user is authenticated and
is a member of the ADMIN group
The check to see that user is authenticated part of this may not be obvious. What’s going on is that a @PreAuthorize check can only be done on an authenticated user. Spring Security is smart enough to check that the user is logged in before checking to see if they are a member of the specified group.
Let’s dig in to that Spring Expression Language above. Where is Spring Security looking for @roles.ADMIN? The @ symbol is special – it identifies a Java bean. In this case, a bean named roles. Defined inside that bean we expect to find a constant named ADMIN.
Ultimately, hasRole needs to be checking against a unique Href representing a Stormpath Group. So, our ADMIN constant needs to be a Java String that holds the Href to our Stormpath Group used for admin.
To complete this configuration and to make it awesomely dynamic, we need a new class called Roles.java:
These 9 lines are so amazingly powerful, I’m geeking out over here! Let’s dig in.
By annotating this class with @Component on line 1, Spring will instantiate it and expose it as a bean. Guess what the name of the bean is? Spring will take the name of the class and camel-case it to derive the bean name by default. So, the bean name is roles. Sweet!
The @Autowired annotation on line 5 causes Spring Environment object to be passed into the constructor. Inside the constructor, we have our only opportunity to set ADMIN since it’s declared final – a requirement to be able to use it inside the hasRoles clause.
The last piece of the puzzle utilizes some Stormpath configuration magic. Notice that we are setting the value of ADMIN to whatever the environment property named stormpath.authorized.group.admin is set to. This is standard Spring. If you have a property in your application.properties file with this name, it will be available in the Spring Environment.
Stormpath adds the ability to set this as a system environment variable alleviating the need to have the value – a Stormpath Group Href in this case – hardcoded anywhere in your application.
Typically, system environment variables are all caps with words separated by underscores. The Stormpath Java SDK automatically converts these system variables into the lowercase dotted notation.
Behind the scenes, Stormpath will convert the STORMPATH_AUTHORIZED_GROUP_ADMIN system environment variable to a Spring stormpath.authorized.group.admin environment variable. That will get picked up by our code above.
Phew! Who thought such magic could be achieved in so few lines of code!
Now, we need to wire the AdminService to our Controller. Here are the relevant parts of our updated HelloController.java:
AdminService is Autowired in on lines 4 & 5. Notice on line 11, we are calling the adminService.ensureAdmin method. If the logged in user is NOT in the ADMIN group, a 403 (forbidden) response will be generated.
The last bit of code housekeeping to do here is to create an admin.html template. In the code that is associated with this post, there’s a simple admin.html template that shows a nicely formatted message confiring that you are, indeed, an admin.
Now, to see this in action, you’ll need to do a little bit of Stormpath housekeeping in the admin console.
Here are the steps:
Create a new Application
Create a new Group called admin for the Application
Create a new Account in the admin Group
Create a new Account NOT in the admin Group
In the code that is associated with this post, I’ve also included a handy error page so that if you are not in the admin group you get a nicely formatted page rather than the default 403 page.
Let’s see it in action. We are going to start up the app as before, only this time we are going to use the Hrefs found in the admin console for the new Application and new Group you created in the previous step.
If you log in as the user you created in the Stormpath admin Group (micah+admin@stormpath.com in my case), you will have access to the admin page. If you log in as the user you created that’s NOT in the Stormpath admin Group (micah+user@stormpath.com in my case), you will get the forbidden page.
No matter who you log in as, you will have access to the /restricted page as we setup before.
Wrapping It Up
Well, we’ve covered a lot of ground here, haven’t we!
We saw how you can protect individual pages as well as protect methods based on membership in a group.
We saw how you can extend StormpathWebSecurityConfigurerAdapter to define access controls for different paths as well as make use of the Spring Security @PreAuthorize annotation for a finer grain of control.
We saw the almost magical way the Stormpath Java SDK manages environment configuration properties to provide a high degree of flexibility for your application without having to hardcode anything.
There are a lot more features in the Java SDK and the Spring Boot integration. Check out the in-depth tutorial here.
Feel free to drop a line over to support or to me personally anytime.
When you research web application security you will come across Cross-Site
Request Forgery (CSRF). This attack vector is taking advantage of cookies, but
in a preventable way. In this post we’ll discuss what the attack is and how it
can be prevented. We’ll also discuss Angular’s XSRF feature, which helps you
prevent attack. It requires cooperation from your server, and we’ll explain what
you need to do.
Note: Angular uses the acronym XSRF, but this is synonymous with CSRF.
What is Cross-Site Request Forgery (CSRF)?
Most attacks focus on stealing your cookies because nearly every website uses
cookies as a form of authentication. The setup is this: when a user logs into
your server, you set a cookie in the browser. This cookie contains a unique ID
which is a link to the user’s session information in your database. The browser
supplies this cookie on future requests, and the server knows who you are.
On the surface this sounds not-so-bad, but here is the catch: the web browser
can be tricked into making requests to your server, even if the end-user
didn’t perform the action themselves.
How is that possible? This attack exploits the default nature of the
HTML parser in your browser. Imagine that you run a store at www.mystore.com.
Your store has an API that allows users to make 1-click purchases. That API
uses a URL that requires the user to be logged in (to have a cookie session),
and looks like this:
http://www.mystore.com/buy?item=expensiveThing
Now imagine that there is a malicious person that wants to exploit your Buy API
and cause a headache for your users. This malicious person carries out their
attack by making posts on websites and social media that contain an image link
that looks like this:
Now imagine a customer who is logged into your site, who is visiting one of the
pages where this link has been placed. When their browser encounters this tag it
will automatically makes a GET request to the URL (because it naively wants to
show the picture to your customer). When it does this it automatically sends
along the cookies for www.mystore.com with the request. Thus, the server
thinks your customer is logged in and completes the 1-click purchase for the
customer!
This is pretty disturbing, as the customer has no idea that this has happened –
they are simply surfing the web as normal and aren’t aware that this request has
been made.
CSRF Mitigations That Don’t Work
Before we get into the proper solutions for this problem, I want to enumerate
two common approaches that don’t actually solve the problem. I mention these
because I see these solutions on the interwebs, but they are wrong:
Using POST Requests. It is sometimes thought that using proper form-based
POST requests will mitigate this attack, but that is not true. You can create
a form on another website and point its action URL to your site, and the
browser will do the same thing: make the malicious request, with cookies.
Using HTTP-Only or Secure cookies. While you definitely should use these
flags on your session cookie, they don’t implicitly stop the attack: the
browser still sends the cookies to your domain when a request is made to your
domain. Your server does not know if this is a real user or an attack.
With that out of the way, let’s move on to the important discussion: how do
we stop this for reals :)
How To Prevent CSRF
Preventing this attack requires a knowledge of where the request is coming from
in the browser. We want to ensure that the request was triggered by an explicit
action from a user who is using the JavaScript application on our website.
We can achieve this by relying on a set of rules that browsers respect, called
the Same-Origin Policy. This policy asserts that certain sensitive
operations are performed by JavaScript code that is running on our website, not
some other website.
One of those operations is the ability to read cookies. While the browser will
automatically supply your cookies for the domain of the request, there is one
useful limitation: the JavaScript code that is running on a website cannot read
the cookies of other websites. We can leverage this to create our CSRF
solution.
Using a CSRF Token Cookie
Because JavaScript can only read cookies from our domain, we will store a second
cookie on our domain that contains a unique token. This is the CSRF Token
cookie. This cookie must be created when the user is logged in, and should contain
a random, un-guessable string that is associated with the user’s session ID (for
future lookups).
Every time the JavaScript application wants to make a request, it will need to
read this token and send it along in a custom HTTP header. Because these
operations (reading the cookie, setting the header) can only be done on the same
domain of the JavaScript application, we can know that this is being done by a
real user who is using our JavaScript application.
A passive image tag or malicious form post, on another site, would not be able
to do these things. If your server sees a request that is missing the custom
header, or the token in the header is not the one that is associated with the
user’s session, your server should reject the request.
Leveraging Angular’s XSRF Feature
Angular packages the CSRF token approach, making it simpler for us to implement.
For every request that your Angular application makes of your server, the
Angular $http service will do these things automatically:
Look for a cookie named XSRF-TOKEN on the current domain.
If that cookie is found, it reads the value and adds it to the request as
the X-XSRF-TOKEN header.
Thus the client-side implementation is handled for you, automatically! But this
does leave the server side pieces in your hands. You will need to do the
following parts:
During login: create the CSRF token (with a random, un-guessable string), and
associate it with the user session. You will need to send it on the login
response as the XSRF-TOKEN cookie.
Assert that all incoming requests to your API have the X-XSRF-TOKEN header,
and that the value of the header is the token that is associated with the
user’s session.
That’s it! With a little bit of backend work, you now have a strategy which
protects you from CSRF attacks.
Go Forth and Secure All the Things!
My goal for this post is to demystify what CSRF is, and how Angular tries to
help you with a solution. CSRF is just a small piece in the web-application
security puzzle. For more information, please see the other posts that I have
written on this subject:
As a .NET developer, I’ve spent most of my time coding on Windows machines. It’s only logical: Visual Studio is the richest development experience for building C# and VB.NET applications, and it only runs on Windows…right?
When I joined Stormpath to work on our open-source .NET authentication library, I was handed a MacBook Pro and given an interesting challenge: can a Mac be an awesome .NET development platform?
To my surprise, the answer is yes! I’ll share how I turned a MacBook Pro into the ultimate Visual Studio development machine.
How to Run Visual Studio on a Mac
Visual Studio doesn’t run natively on OS X, so my first step was to get Windows running on my MacBook Pro. (If you want an editor that does run natively, Xamarin Studio or Visual Studio Code might fit the bill).
There are multiple options for running Windows on a Mac. Every Mac comes with Apple’s Boot Camp software, which helps you install Windows into a separate partition. To switch between OSes, you need to restart.
Parallels is a different animal: it runs Windows (or another guest OS) inside a virtual machine. This is convenient because you don’t have to restart your computer to switch over to Windows. Instead, Windows runs in an OS X application window.
I found that a combination of both worked best for me. I installed Windows into a Boot Camp partition first, and then turned that partition into an active Parallels virtual machine. This way, I have the option of using Windows in the virtual machine, or restarting to run Windows natively at full speed.
I was initially skeptical of the performance of a heavy application like Visual Studio running in a virtual machine. The option to restart to Windows via Boot Camp gave me a fallback in case Visual Studio was sluggish.
There are some minor disadvantages to this method: you can’t pause the virtual machine or save it to a snapshot. A non-Boot Camp virtual machine doesn’t have these limitations. This guide will work regardless of what type of virtual machine you create.
After three months of serious use, and some tweaks, I’ve been very impressed with Parallels’ performance. I haven’t needed to boot directly to Windows at all. (For comparison, my host machine is a 15” mid-2015 MacBook Pro with 16GB of RAM and a 1TB flash drive.)
In the remainder of this guide, I’ll detail the steps I took to optimize both Parallels and Visual Studio to run at peak performance.
Installing Windows With Boot Camp and Parallels
This part’s easy. I followed Apple’s Boot Camp guide to install Windows in a separate partition.
Then, I installed Parallels and followed the Parallels Boot Camp guide to create a new virtual machine from the existing Boot Camp partition.
Tweaking Parallels for Performance and Usability
The Parallels team publishes guidelines on how to maximize the performance of your virtual machine. Here’s what I adopted:
Virtual machine settings:
2 virtual CPUs
4096MB system memory
256MB graphics memory
Parallels options:
Optimization: Faster virtual machine, Adaptive hypervisor, Tune Windows for speed all turned on.
Sharing: Shared cloud, SmartMount, and Access Windows folders from Mac turned off, as I didn’t need these for my workflow.
I experimented with both of Parallels’ presentation modes, Coherence and Full Screen. While it was cool to see my Windows apps side-by-side with OS X in Coherence mode, I found that the UI responsiveness (especially opening and closing windows and dialogs) felt sluggish.
Because of this, I use Full Screen exclusively now. I have Windows full-screen on my external Thunderbolt display, and OS X on my laptop. If I need to use OS X on my large monitor, I can swipe the Magic Mouse to switch desktops.
Adjusting OS X and Windows Features
I fixed a few annoyances and performance drains right off the bat:
Function keys. If you’re using the Mac keyboard, you’ll want to change the function key behavior so the F1-F12 keys work correctly in Visual Studio. From System Preferences – Keyboard, make sure Use all F1, F2, etc. keys as standard function keys is checked. With this turned on, hold Fn to use the Mac functions (brightness, volume, etc.) on F1-F12. With an external non-Mac keyboard, this isn’t an issue.
Start menu. I’m using Windows 8, and the removal of the Start menu annoyed me. I clung to my old ways and installed Start8 to restore it.
Disable Windows visual effects. I turned off most of the Windows desktop manager visual effects by going to Control Panel – System and Security – Advanced system settings – Advanced – Performance – Settings – Visual Effects and choosing Adjust for best performance. However, I left Smooth edges of screen fonts checked because it improves text rendering on my monitor.
Installing Visual Studio and Helpful Extensions
Installing Visual Studio is a piece of cake once the virtual machine is set up. I simply downloaded the latest release from MSDN and let the installer run.
If you use an Apple Magic Mouse (as I do), Visual Studio tends to be overly eager to zoom the text size in and out as you swipe your finger over the mouse. The Disable Mouse Wheel Zoom add-on fixes this annoyance.
Improving Visual Studio for Performance
I was impressed with how well Visual Studio performed under emulation. With a large multi-project solution open, though, I saw some slowdowns.
Through trial and error, I found a number of things that could be disabled to improve performance. You may not want to make all of the changes I did, so pick and choose your own list of tweaks:
Disable hardware-accelerated rendering. Unchecking Automatically adjust visual experience based on client performance, Enable rich client visual experience, and Use hardware graphics acceleration if available via Options – Environment made the UI feel much more responsive on my machine.
Start up to an empty environment. Starting up Visual Studio for the first time feels a lot snappier if you skip the default news page on startup. Select Empty environment under Options – Environment – Startup – At startup.
Remove unused extensions. Visual Studio ships with a number of extensions that you may not need. From Tools – Extensions and Updates – Installed, remove any extensions you aren’t actively using (you can always reinstall them later). I got rid of six extensions I didn’t need.
Disable extra debugging features. I turned off both Enable Diagnostic Tools while debugging and Show elapsed time PerfTip while debugging in Options – Debugging – General. I wasn’t using these debugging features, and debugging felt snappier after I disabled them.
Turn off the Navigation Bar. I found the code editor Navigation Bar to be unnecessary if the Solution Explorer is open. I disabled it via Options – Text Editor – All Languages – Navigation Bar.
Disable CodeLens. CodeLens is a cool feature for collaboration, but it’s not part of my current workflow. I got rid of the CPU overhead by turning it off via Options – Text Editor – All Languages – CodeLens – Enable CodeLens.
Turn off Track Changes. When a file is open in the code editor, Visual Studio will represent recent changes by displaying small regions of green or yellow on the scroll bar. If you can live without this, turn off Track changes via Options – Text Editor – General for a small performance boost.
Turn off Track Active Item. Squeeze out a little bit more UI performance out by ensuring Track Active Item in Solution Explorer is unchecked under Options – Projects and Solutions – General.
Visual Studio on a Mac: The Best of Both Worlds
With these tweaks, I’ve come to love using Visual Studio on a Mac. The performance is good, and by running Windows in a virtual machine, I get the best of both OS worlds.
Want to see what I’m building with this setup? Check out our open-source .NET SDK on Github.
Do you have any other tricks you’ve used to improve Visual Studio performance? Any must-have add-ons that boost your productivity? Leave me a comment below!
A little over 3 years ago, Stormpath introduced PHP support for User Management and the response from the PHP community has been overwhelming and so supportive. Thank you! Since then, we have been working very hard on the PHP SDK to make it your go-to service for User Identity.
Today, we are happy announce that a stable version of the PHP SDK is being released to General Availability. Begone Beta Tag!
This release includes many changes: we removed the dependency on PEAR and now support installation using Packagist. Composer and Packagist gives us nice autoloader options, both of which uses the PHP Standards Recommendations (PSR). The PHP SDK has been updated to use PSR-4 autoloading from the deprecated PSR-0.
What’s New in the Stormpath PHP SDK?
Removing the PEAR Dependency
PEAR (PHP Extension and Application Repository) was introduced into PHP in 1999 by Stig Bakken to help promote the use of reusable PHP components. It is now 16 years old, and though still a useful component manager and actively supported, PEAR is not as simple as other options out there.
Terry Chay also stated it well on Twitter a few weeks ago while talking about PEAR.
The burning realization that you should have stopped
depending on #PEAR#PHP packages 2 years ago…
#composer
The most actively used dependency manager is now Composer, so we wanted to make the integration of Composer much simpler and easier to use. Thank you to the many people who offered this feedback. We heard you loud and clear!
Moving to Composer and Packagist PHP Package Manager
Packagist is currently the most common PHP package manager and offers many different packages to include in your project. Many of our PHP users are fans, and better support for it was one of the main reasons we moved away from using PEAR.
During our beta period, you could install our PHP SDK with Packagist using Composer, but it required some modifications to your composer.json file.
Because we had the beta flag as part of our releases to Packagist, you had to have your minimum-stability set to ‘beta’ to install. If you did not do this, you would have to add in PEAR as a repository, and who remembers what that looks like? It would make for a messy Composer file, and would cause issues during updates.
The move to Packagist was pretty simple since we had been developing on the 1.x branch of the package already and it was enabled inside of Packagist.
PHP Feature Parity with the REST API
The biggest part of this GA release was getting the PHP SDK up to parity with the Stormpath REST API. The new ‘Organization’ endpoint is supported, and support for ID Site is brought up to par. JSON Web Tokens and OAuth Tokens are now supported (learn more about Token Authentication with Stormpath).
If we had just made a GA release of the PHP SDK back a few months ago, we would not have been able to release some of the code as it would have introduced backwards incompatible changes to the 1.x release. The changes that are left to give us 100% parity will be backwards compatible, which will be easier on our active users.
How to Install the Stormpath PHP SDK Now
The first thing to understand is that we now have dependencies inside of the SDK. These dependencies help with our JWTs for ID Site and OAuth Tokens and Guzzle which helps our HTTP calls to the API. These dependencies require you to use Composer to install the PHP SDK so you don’t have to worry about installing it manually.
Make Sure Composer is Installed
The first step is to ensure you have Composer installed. You can do so by running which composer in your terminal. You are ready to install the PHP SDK if this returns a path such as /usr/local/bin/composer.
Initialize Composer
Next, from within your projects root, initialize your Composer instance. If you have a composer.json file in your project root, you can skip this step. Run composer init from the project root and follow the prompts. I usually suggest to skip the part that asks you if you want to specify your dependencies and deal with them later.
Require the Stormpath PHP SDK
Once the composer.json file exists, run composer require stormpath/sdk from terminal in your projects root. This will update your Composer file to include the most recent stable release of the PHP SDK, which is now using Packagist.
PSRs are a set of PHP Standards Recommendations created by a group of members of the PHP Framework Interop Group in 2009 at the php[tek] conference. The group was set up to work together and talk about commonalities between their projects.
The first PSR, PSR-0, is the standard for describing how autoloading would work to maintain interoperability with the projects. PSR-0 became an integral part of Composer and made it so you didn’t have to create your own autoloaders inside your project. Composer did it for you. Stormpath’s PHP SDK began using PSR-0 during the first release of the 1.x series. Since then, the PSR has been deprecated for an improved version of the autoloader: PSR-4.
Migrating from PSR-0 to PSR-4
When you update your SDK from <= 1.11.x@beta to 1.12.0, you will notice a lot of changes related to where files are being stored. Do not let this scare you! You can still easily update our SDK in your project (or migrate your own project).
If you look at our old code structure, everything was in a namespace folder named Stormpath that lived under the src directory. This was required for PSR-0 to work according to spec.
We have removed the Stormpath directory, which not only cleans up our directory structure, but also allows for PSR-4 to be implemented.
123456
.
|-- src
|-- Authc
...
|-- Resource
|-- Util
What’s Next for the PHP SDK?
We have come a long way since the start of the PHP SDK and are happy to finally provide you with a stable release. We have begun the implementation of PSR standards set out by PHP-FIG and will continue to implement them into the PHP SDK to make sure full interoperability amongst other projects that follow these standards recommendations.
Additionally, we’re continuing to extend PHP support into framework integrations, most recently Laravel, with more on the horizon. This release makes that work much easier.
Let Us Know What You Think
If you have any suggestions on features you would like to see in a future release, feel free to let us know with a
GitHub issue or reach out to support.
When building full-stack JavaScript applications, it’s all too easy to defer the
user authentication until some later date. With the power of frameworks
like Angular.js and Express.js, you can “just get going” with your core application
functionality, without really needing to invest effort in figuring out the “user login part”.
But if you’ve worked this way, you’ve likely discovered that adding in user
authentication can be a real pain once your development picks up and the
deadline suddenly turns into tomorrow :)
In this post, I’ll show you how we can include user authentication up front,
as part of your boilerplate. We’ll be using Stormpath as our authentication
service, and you’ll be up and running in 15 minutes – *promise*.
What Is Stormpath?
Stormpath is an authentication and user management service that allows
developers to create, edit, and securely store user accounts and user account
data. Our API enables you to:
To get started with our example application, you will need to sign up for a
Stormpath tenant. It’s free to use and quick to create your tenant account.
After you sign in, you will have the opportunity to get an API Key and Secret.
These are secure credentials that your example application will use to
communicate with the Stormpath API. You should also find the default Stormpath
Application, called “My Application”. This application has an HREF that you
will need to use as well.
Here is a screenshot that shows you were to find these items:
Fetch The Angular.js-Express.js Example Code
All of the code for our example project can be found in this repository:
Please download this code to your computer, then open your terminal and enter
the folder. We need to install the node modules by running this command:
npm install
You should see a list of installed modules when the operation completes. Then
we can move on to configuration.
Configure Stormpath
We need to create a properties file in this folder, this file will be used to
store our secure API credentials that we gathered from the Stormpath Admin Console.
Please create the file stormpath.yml and place the following inside it:
That’s it! The server should now be usable, we’ll start it up in the next
section.
Start The Node Server
You should now be able to start the server by running the server script:
node server/server.js
If all is well you should see the following logged to your console after a few
seconds:
Stormpath Ready
Application running at http://localhost:3000
The server should now be available! Visit http://localhost:3000 in your browser, you
should now see the Angular application:
Woot! It’s been about 15 minutes, right? Maybe less? What you’re looking at
is a basic, but complete Angular + Express application that has a user management
system built in. Give it a try! You can use the registration screen to sign up
for an account, then you can login and view your user profile. #awesome
Play around with the app, then continue reading. We’ll discuss how this
application works, and what you can do to modify it – or how you can steal pieces
of it for your own application.
Server-Side: Stormpath Express.js Integration
The heavy worker in this fullstack application is our express-stormpath
library. This library wires up your Express application to Stormpath’s API,
and helps with serving the Angular application.
Behind the scenes it is using
our lower-level Stormpath Node SDK to communicate directly with the
Stormpath REST API. It then ties in with the Express API to provide you
an experience that feels very much like an Express middleware experience, but
backed by Stormpath authentication services.
If you take a peek inside server.js, you’ll see where we setup this integration:
These options are telling express-stormpath how it should integrate with our
fullstack application. We’ve told it where our Angular application is (spaRoot),
that we’re building a website (rather than a pure API service), and that we
want to expand the account’s custom data and groups (a convenience feature to
provide our Angular application with all the user data that it needs).
The Angular application is also leveraging a Stormpath module, the
[Stormpath Angular.js SDK][]. This module has some more nuanced configuration
than the server side component, so I’ll walk you through each bit and discuss
what it does.
How Authentication Works – Tokens!
This is where it gets really cool. The Stormpath API provides
OAuth2 Token Management, which is a very powerful feature if you’re building
a web application. In a nutshell, it is sessions as a service. I’ll explain
how we use this in our fullstack application, but don’t worry: all this is
handled for you automatically by the Stormpath modules.
When a user posts the login form, we send their username and password to the
Stormpath API. If the credentials are valid, we exchange them for an access
token and refresh token. These tokens are then stored in secure, HTTPS-only
cookies in the browser. On subsequent requests, these access tokens will be
provided for authentication. Stormpath authenticates the tokens for you without
any extra effort on your part.
Should you ever need to revoke tokens, you can easily do so by finding the user
in the Stormpath Admin Console and revoking their issued tokens. Again,
this is like sessions as a service: you never have to build your own database
for this! mic drop
Our Stormpath Angular SDK has broken out the templates from the core code,
because you may find that you want to supply your own templates. If you go this
route you can simply omit this dependency.
Each of our directives that need a template will allow you to supply your own
template. Please see the individual directives for more information, such
as these common ones:
In this example we are using the UI-Router module, but please note that
support for ngRoute will be coming very soon.
To configure UI-Router, we tell it what our default state should be (where users
go after login) and the name of the state where our login page can be found.
You will find this in the main Angular script, client/app.js:
Please see the documentation of the $stormpath service for the more advanced
UI Router configuration options.
Login and Registration Forms
The Stormpath Angular SDK provides default forms for Login and Registration,
via directives. These directives need to be placed in the appropriate location
in your Angular application.
This example application has the structure of one folder per major view, so you
will find the login view in client/login/login.html:
This is where we’ve placed the sp-login-form directive. The
Stormpath Angular SDK will replace this element with the default form.
You will find a similar directive, for registration, in client/register/register.html.
Handling Logout
When a user wants to logout, we need to revoke their access tokens. This is
done by making a request to the /logout endpoint on your express server.
What should happen in your UI after logout? We leave that in your control, as
UI Router represents everything as view states.
As such, you’ll find that in client/app.js we listen for the session end event
and then redirect the user back to the login page. This event is emitted once
the tokens have been revoked:
To trigger the deletion of the tokens, we add the sp-logout directive to
our logout link in client/navbar/navbar.html:
1
<ahref=""sp-logout>Logout</a>
Please see sp-logout and $sessionEnd for more information on how
to use these together.
More Features!
In the previous section I went into detail about the core features of login
and registration. But there are many more features in this example that I’ll
cover quickly, so that you can get on with building the rest of your application
:)
Email Verification
Stormpath provides an email verification feature that allows you to send a
verification email to users when they register. Their account is not activated
until they click on this link. The Stormpath Angular SDK provides the
landing pages that users will come to when they click on this link. You will
see this code in client/email-verification.
To configure email verification and the related emails, please login to the
Stormpath Admin Console and find the Directory that is attached to your
default Stormpath Application. In there you will find the Workflows section,
where you can configure this feature.
Password Reset
Stormpath provides a password reset feature that allows users to request a
password reset email. When they click on the link in the email, they will
arrive at your angular application and be prompted to enter a new password. You
will see the code for this feature in client/forgot-password and client
/change-password.
To configure the password reset feature, please login to the
Stormpath Admin Console and find the Directory that is attached to your
default Stormpath Application. In there you will find the Workflows section,
where you can configure this feature.
Social Login
Would you like to provide Google Login and Facebook Login for your users? No
problem! This is super easy to setup. Simply login to the
Stormpath Admin Console and create two new directories, one for Google and
one for Facebook. During the setup you will have to enter the associated
information for your Google App and Facebook App.
After you have created the directories, go back to your default Stormpath
Application and map these directories to your application. Then restart your
Express server and you should see the buttons on your login page:
Easy!
Custom Profile Data
All accounts in Stormpath can have arbitrary custom data assigned to them. In
this example we show you how to create a custom profile editing form, and
how you can post to your Express server and save the data onto the user object.
You can find the Angular code in client/profile and the server code in
server/routes/profile.js
Go Forth and Develop!
While this is an example application, you can definitely use it as the base for
your own project. So go ahead, start building your next awesome app on top of
it! Or just steal the good parts for your existing application :)
As always, we’re here to help! Hit us up via
support@stormpath.com, or leave a
comment below.
As we planned our burn-down to the holidays, our head of Marketing made some
pretty big commitments to our growth plan. But what is a good growth plan
without some technical fussery? So, here’s what I came up with as a response:
All new API calls to Stormpath Thanksgiving week will result in a shipment of
free, freshly home-baked cookies to the holder of the Stormpath tenant!
So, In the spirit of the holidays and web developers everywhere,
we’ve decided to put cookies at the center of your Thanksgiving week. I’ll cover how to use http cookies securely in your web application, and if you try out the Stormpath API for the first time this week, you’ll get some free Stormpath cookies, straight from Claire’s kitchen. Woot!
Cookies Are Delicious
No doubt about that, right? They taste good, they allow you to store useful
information in the user’s browser, and they allow the browser to automatically
send that information back to your server, on every request. These features are too
tasty to turn away. So go ahead, have a few cookies! It is the holidays, after
all!
Unfortunately, cookies have gotten a bad rap. They typically contain gluten, and
are often poorly baked, exposing your users to bad taste and poor web design.
In this recipe, we will show you how to make cookies that are delicious,
responsible, and guilt-free.
Recipe: The Best Darn HTTP Cookies
1 Part Secure flag
1 Part HttpOnly flag
2 parts responsibility (client AND server)
1 Part highly unique identifier (if using cookie for session lookup)
Hold the PII (personally identifiable information)
Unique cookie name, to taste
One medium-sized, CSRF and XSS-safe baking sheet
HTTPS (for delivery)
Step 1: Inspect Your Ingredients
For best flavor, ensure that your ingredients are fresh but not too raw.
No PII – Your cookies will be sitting in plain sight on the table. As
such they should not contain burnt edges, real names, email addresses, social
security numbers, etc. A cookie is not a mirror, or your filing cabinet.
Highly Unique Identifiers – If you are whipping up some session cookies
(the ones that link the browser session to a session database), then the
contents of the cookie should be highly random. If an attacker can guess the
ingredients of your cookie, they can pose as your user. Oatmeal-Raisin is
about as bland as you can get, so you should absolutely avoid that entropy
source.
Step 2: Prepare Your Baking Sheet
How your cookies are formed are just as important as their contents. Nobody
likes a sloppy cookie. You want to form your cookies with some protection from
crumbly edge cases.
XSS Prevention. The JavaScript environment in the browser is hostile. Your
cookies are not going to survive rummaging hands, curious snouts, and malicious
JavaScript that made its way into your cookie jar. Protect your
cookies from XSS by providing the HttpOnly flag when you send the cookie to
the browser. This prevents the JavaScript environment from accessing the
cookie. You should do this for any cookie that gives the user implicit access to
sensitive resources.
CSRF Prevention. Your cookies can be used maliciously, by other domains
that make requests to your website without your user’s consent. If your
server blindly authenticates a user, simply because they have a tasty, buttery,
sugary cookie, then you’ve got more problems than your hard drive size. You’re
also allowing CSRF attacks, where other websites trigger state-changing actions
on your server without your user’s consent. This is possible because the browser
will always send the user’s cookies automatically, regardless of how the request
was triggered. Use one of the many CSRF Prevention measures to reduce this risk.
Step 3: Delivery
Sliding your cookies onto some tableware and wrapping them with saran wrap may be
fine or a birthday or make-up attempt, but it’s the holidays! Let’s get fancy,
and secure, about this operation. Use red saran wrap.
And Always use Secure cookies. The secure flag tells the browser that the
cookie should only be transmitted over secure, HTTPS connections. We want
this because Santa is listening “on the wire”, and we don’t want him to steal
your cookies.
And That’s How The Cookie Crumbles
Having the best recipe in the world is great, but why do all that work when
someone else is probably going to be bringing the same cookies to the party?
Save yourself some time and Sign Up for Stormpath – Not only will you
get these security features out-of-the box with our full suite of
SDKs and framework integrations, but we’ll also send you some free cookies –
really!
The easiest way to get started is with one of our quickstarts:
How this will work operationally: We will check the API logs on Monday. Anyone who has created a new Stormpath tenant and successfully made an API call between the timestamp when this post goes live and Sunday 11/29 at midnight PST will get an email asking for a mailing address where we can send your cookies.
Sadly, due to customs restrictions, we can’t ship homemade baked goods outside the US. But we can in most cases send you some Swag.
Unfortunately, we can’t honor special requests or dietary restrictions. I bake a lot, and nuts, gluten and other allergens are regularly flung around my kitchen.
Exciting things are happening in .NET Land! The Stormpath .NET SDK is quickly marching towards a full, feature-rich ASP.NET integration. Big thanks to all the folks who have reached out over email and on Github to let us know what features you are looking for in this library!
In this release, we’ve fixed some bugs and added two crucial pieces: ID Site for single sign-on support and a client-side caching layer. As usual, there are a few other goodies thrown in too!
Getting the Newest .NET SDK Release
As always, installing the SDK is as easy as:
install-package Stormpath.SDK
If you’re already using the SDK, this release should be a drop-in upgrade:
We’ve added full support for Stormpath’s ID Site single sign-on solution in this release. With this feature, you’ll be able to enable a hosted login flow for your application in only a few lines of code.
Using ID Site from your web application is a two-step process:
Generate an ID Site redirect URL
Handle the ID Site result callback
Generate an ID Site Redirect URL
This part’s easy. Simply use the IIdSiteUrlBuilder interface to construct the appropriate URL, and redirect the user:
12345
varredirectUrl=application.NewIdSiteUrlBuilder().SetCallbackUri("https://my-site-url/HandleRedirect").Build();// Redirect the user to redirectUrl
Handle the ID Site Result Callback
After ID Site has handled the login request, the user will be redirected back to your callback address (https://my-site-url/HandleRedirect in this example).
In the controller that handles the HandleRedirect endpoint, create and call an ID Site handler to process the callback:
1234567891011121314151617181920212223
// Construct an IHttpRequest wrapper from the current Request objectvarrequestDescriptor=HttpRequests.NewRequestDescriptor().WithMethod(Request.HttpMethod).WithUri(Request.Url).Build();// Construct an ID Site callback handlervarhandler=application.NewIdSiteAsyncCallbackHandler(requestDescriptor);// Get the result of the ID Site requestvaraccountResult=awaithandler.GetAccountResultAsync();// accountResult.Status is one of:// IdSiteResultStatus.Authenticated// IdSiteResultStatus.Logout// IdSiteResultStatus.Registeredif(accountResult.Status!=IdSiteResultStatus.Logout){varaccount=awaitaccountResult.GetAccountAsync();// do cool things with account}
For more information on how to build applications that use ID Site, consult the ID Site documentation.
Faster Performance with Client-Side Caching
Another important feature added in this release is client-side caching support. This can reduce the number of requests made to the Stormpath API and improve the performance of your application.
The caching layer intelligently intercepts requests made to Stormpath and stores the resource data locally. If the same data needs to be retrieved again, the data is pulled from the local cache instead of making a network request.
The caching layer is designed to be pluggable through the ICacheProvider interface. If you don’t want to use the default cache implementation, you can swap another implementation out easily.
Out of the box, the .NET SDK ships with an in-memory cache that’s suitable for use on a single-server application. For applications that run on multiple servers, a distributed cache is highly recommended. This is covered in the next section.
Starting with this release, caching is enabled by default. If your application runs on a single-server instance, you don’t have to do anything! The cache layer is already working for you.
Disabling Client-Side Caching
If you’d rather not cache requests, you can specify this when building an IClient object:
Unless otherwise specified, the cache time-to-live (TTL) and time-to-idle (TTI) default to one hour. These defaults can be changed when building a new ICacheProvider instance.
For example, to set a TTL of 2 hours and a TTI of 30 minutes:
These values can be further customized by cache region. The .NET SDK treats each resource type as a separate cache region, so per-resource type TTL and TTI values can be set by specifying a resource type while building the ICacheProvider:
In this case, every cached resource will have the default TTL (2 hours) and TTI (30 minutes), except for Account resources, which expire after 15 minutes, or 5 minutes of inactivity.
Distributed Caching with Redis
The default in-memory cache is not suitable for applications that run on multiple servers (such as a load-balancing configuration), because each server maintaining its own local cache can lead to coherence problems. In this case, a distributed caching technology such as Redis or Memcached is highly recommended.
If you’re using Redis, we’ve got you covered. A Redis cache adapter is available in the nuget package Stormpath.SDK.Cache.Redis. Plugging it in is easy:
12345678910111213
// At the top of your classusingStormpath.SDK.Cache.Redis;varcacheProvider=RedisCaches.NewRedisCacheProvider().WithRedisConnection("server:6379").WithDefaultTimeToLive(TimeSpan.FromMinutes(60)).WithDefaultTimeToIdle(TimeSpan.FromMinutes(30)).Build();varclient=Clients.Builder()// (other configuration).SetCacheProvider(cacheProvider).Build();
If your project uses a different distributed cache, the source code for this implementation should provide a starting point to writing a custom ICacheProvider. If you need help getting a specific caching technology working, drop us a line.
Further Performance Improvements with Link Expansion
The Stormpath REST API supports link expansion as a way to retrieve multiple related resources in a single request. This works beautifully as a way to prime the cache with data you know you’ll need in the future.
In this release, we’ve added a new Expand operator that exposes this API behavior. You can use this operator when making a single-resource request, or in the context of a LINQ search query.
For example, when retrieving an Account, you could also retrieve and cache the account’s custom data:
123456
varaccount=awaitclient.GetResourceAsync<IAccount>(accountHref,opt=>opt.Expand(x=>x.GetCustomData()));// If caching is enabled, no HTTP request is made here:varaccountCustomData=awaitaccount.GetCustomDataAsync();
You can expand multiple properties, too. For example, when performing an account search, you could retrieve each account’s custom data and directory information:
The additional data is silently passed to the cache, and the resulting type of your query won’t change. It’s all under the hood.
With strategic use of Expand, you can prime the cache with data you know you’ll need, and cut down even more on network traffic compared to naive caching alone.
New Account Store API for Directories and Groups
This release also adds some additional methods and interfaces for managing Account Stores (Directories and Groups) mapped to Applications. For background on how Stormpath uses Account Stores, see the Account Store Mapping documentation.
Adding and Removing Account Stores From a .NET Application
Adding Directories and Groups to an Application as an Account Store Mapping requires only one line of code:
12345678910111213
// Add by name:awaitapp.AddAccountStoreAsync("My Group Or Directory Name");// Or, add by href:awaitapp.AddAccountStoreAsync(hrefOfGroupOrDirectory);// Or, from an existing IDirectory or IGroup object:awaitapp.AddAccountStoreAsync(myGroupOrDirectory);// If you want to get really fancy, you can add by the// result of a query (provided the query produces one item only):awaitapp.AddAccountStoreAsync<IDirectory>(dirs=>dirs.Where(d=>d.Name.StartsWith("My Dir")));
Controlling Login Order With Account Stores
The listIndex property of an Account Store Mapping determines when it is consulted in the Stormpath login flow. Account Store Mappings with higher priority are consulted first. By default, newly-created mappings are given lowest priority.
You can customize this by setting the Account Store Mapping properties directly:
Applications cannot store Accounts or Groups directly; Accounts and Groups are always stored in an Account Store (a Directory or Group). You can specify which Account Stores are the default Account and Group store by setting these properties when creating a mapping:
In this example, if an Account Store Mapping already exists, it is updated and set as the default Account Store. If it does not exist, it is created.
Specifying an Account Store During Requests
In addition, you can specify an Account Store, Account Store href, or Organization nameKey during login and password reset requests. In Applications that have a large number of associated Account Stores, this can reduce the time it takes to process a request.
1234567891011
// Specify an Account Store to search during a login attemptvarloginResult=awaitapp.AuthenticateAccountAsync(request=>request.SetUsernameOrEmail("sonofthesuns").SetPassword("whataPieceofjunk$1138").SetAccountStore(accountStore));// Send a password reset email to the account// in the specified Account Storeawaitapp.SendPasswordResetEmailAsync("vader@galacticempire.co",accountStore);
What’s Next for the .NET SDK?
The next few releases will be super exciting. Here’s what’s on the roadmap:
Identity management for mobile and web applications poses a major challenge for companies looking for scalability, availability, and security in their system. The problem is that it’s extremely expensive and time consuming to build and manage this system yourself.
With Spring Boot and Spring Security, you can integrate identity management with Stormpath in as little as 4 files. This screencast gets you up to speed with Stormpath’s identity management features, the benefits of using Stormpath at the code level, and how to get started with Spring Boot.
Specialized Identity Management for End Users
Modern applications need to support millions of users on a daily basis with unpredictable load spikes, all while keeping this large amount of user data secure. Stormpath allows you to offload identity management so that you can focus on launching your application faster.
Stormpath houses, secures, and manages your user data via a REST API using one of our language libraries or framework integrations. Stormpath provides all of the necessary identity management features out-of-the-box including:
Secure, flexible authentication including password, token, auth, and API.
Deep authorization including groups, roles, customer organizations, and permissions.
A hosted identity portal with user screens and pre-built workflows.
Authentication Pain Points in Java
Typically, building an identity management system in Java requires you to write and maintain a large amount of code that has nothing to do with your core business. But it’s necessary to have an authentication and authorization layer in your application.
On top of that, you have to keep up with best practices for security like how to hash encrypted passwords and store them. Even with the latest version of Spring Boot and Spring Security, you have to call out in the configuration to encrypt passwords and ensure you have CSRF tokens in your views. This requires you to define each user path and how to secure it.
Using Stormpath With Spring Boot
There are only four steps to set up an application with a complete user management system when using Stormpath with Spring Boot:
Create a Stormpath account
Create an API Access keyset
Use the Maven package Spring Boot Starter – removes need for defining paths and creating workflows
Write your Spring Boot App
Setting Up Stormpath with Spring Security
You can add in all of the Stormpath features with a simple web security configuration. To get started, all you need is a Maven configuration file with a single dependency. This includes all of the Stormpath templates and Spring Security integrations. The only thing left for you to do is set the rules for your own application!
The other day, a bunch of us at Stormpath were talking about our favorite books. We thought it would be cool to both have a list of these books and order them by popularity. So we set up a private Subreddit to do just that.
Forget NoSQL – we’re going NoDB in this post!
Stormpath’s hosted Identity Management solution includes a feature called CustomData. It’s basically an unstructured JSON datastore tied to each of your Stormpath Entities, such as Accounts and Groups.
The other day, a bunch of us at Stormpath were talking about our favorite books. We thought it would be cool to both have a list of these books and order them by popularity. So we set up a private Subreddit to do just that.
Only, some of us here at Stormpath don’t have Reddit accounts. Some of us, don’t even like Reddit (not naming names, here).
So I thought: “I wonder how hard it would be to implement this book voting system in Stormpath using CustomData instead of a database?”
Well, the answer is it took a couple of days to create, coding it outside of my normal working hours (What does that even mean in a startup?)
Before we get to building the code sample, let’s examine some pros and cons of this approach:
Cons:
Must make API calls to access CustomData (see Pros)
Limit of 10MB per Stormpath Entity (pretty generous, actually)
Pros:
No database for you to worry about
Easy to optimize API calls to make as few as possible
CustomData implements Java Map interface for easy conversion to your own entities
You can check out the docs for a variety of platforms here.
Follow the Java Quickstart to create a Stormpath account. That’s all you need to get going!
What the Heck is CustomData?
Stormpath has up to 10MB of text based CustomData attached to just about every Stormpath Entity. For example, Every Stormpath Directory, Group and Account can have
CustomData attached to it.
The actual data is schema-less JSON. Ordinarily, this would be data would have something to do with your identity management needs. But, there’s no rule book and for this sample, we’ll be storing book data.
Setup your Stormpath Application and Groups
To exercise this app, you’ll need to create a Stormpath Application, as well as an Admin Group and a User Group. Make note of the href of each of these.
We’ll use them later.
Anyone – even someone who is not logged in – can see the list of books ordered by upvote.
Anyone can create an account.
Only members of the User Group you specify can add new books. For the sake of making the app as hands-off as possible, authenticated users can add themselves to the User Group.
Only members of the Admin Group you specify can rebuild the book list. More on that later.
Here’s what this looks like through the view of the Stormpath Admin Console:
Data Structure For Your CustomData
We’re going to use a particular key so as not to interfere with any other CustomData you might want to have. Here’s a sample of what it looks like:
The top level key is books. It’s an array of book data including the number of votes a book has.
The books you submit will be stored in the CustomData attached to your Stormpath Account.
Now, here’s the tricky bit: The CustomData attached to the the User Group you set up earlier will store the aggregated book data. Why? So that the app is responsive in returning the book data to you. Otherwise, it would need to gather up all the books CustomData from
each member of the User Group and build the book list on the fly.
Here’s how the CustomData looks in the Stormpath Admin Console:
Note: This is not a very scalable app. You would not want to store many thousands of books in Stormpath CustomData. But it is functional and fun to play with!
Build and Run Your Spring Boot Application
If you want to see this in action right away, use the Deploy button below.
To build and run locally, do the following:
123456
mvn clean package
STORMPATH_API_KEY_FILE=<path to your apiKey.properties file> \
STORMPATH_APPLICATION_HREF=<full href to your Stormpath Application> \
STORMPATH_AUTHORIZED_GROUP_USER_HREF=<full href to your Stormpath User Group> \
STORMPATH_AUTHORIZED_GROUP_ADMIN_HREF=<full href to your Stormpath Admin Group> \
java -jar target/*.jar
How the Book Upvoting Application Works
Follow these steps to get going with the app:
Create an Account
Verify your Account
Login and Join the User Group
Now you can post new books and upvote
You may ask yourself, “Why is step 3 even there?”
I wanted to demonstrate some of the awesome power of Spring Security.
Only members of the User Group are allowed post new books.
You also have to be a member of the group to upvote. This is
protected both on the client side and the server side.
On the client side, you will not see the form to post a new book until you are
a member of the user group.
All too often, I’ve seen application developers stop at the client side only
to have script kiddies perform
unauthorized actions on their site because they didn’t properly protect the server side.
Here’s how method level protection works on the server side:
The above is an excerpt from BookService.java. The @PreAuthorize lines makes it so
that you can’t even enter the method unless you are a member of the Stormpath User Group.
This blog post has more on Stormpath’s
Spring Security integration.
The final bit of functionality in this app is the ability to rebuild the master book list
if you’re a member of the Admin Group. All this function does is iterate over the Account
level CustomData and rebuild the Group level CustomData. This is a little demonstration
of how easy it is to efficiently work with Stormpath objects.
This is what you’ll see if you’re a member of the Admin Group:
Notice the @PreAuthorize on line 1. You can’t even enter this method unless you are a member of the Admin Group.
Line 5 makes all the difference in how efficiently we iterate over our collection of
Stormpath Accounts. By having the .withCustomData() as part of the chained method calls,
it ensures that every Account we fetch will also have the associated CustomData with it.
There will not be an additional request over the wire on line 8 at account.getCustomData() because of this use of link expansion. If we did not have the .withCustomData(), every call to account.getCustomData() would trigger another request to Stormpath.
On Line 7, I’m just iterating over ALL the Accounts. What if there’s a million of them? Well, Stormpath automatically takes care of paging and fetching. The number of Accounts that are
fetched at once is configurable and defaults to 50. So, I get to just have a familiar for
loop and Stormpath takes care of all the messy pagination behind the scenes. Pretty cool, right?
That’s pretty much it. There’s not a ton of bells and whistles – yet!
It’s not a SPA (Single Page Application). Making an Angular app out of it would be a fun improvement.
It’s not meant to have tons of data. It should be very responsive with hundreds of books. It may start to become less responsive if you have thousands of books. Maybe I’ll do a little stress testing to see how it performs with a ridiculous number of books. I’ll keep you posted!
Known Issues
There’s an issue with Spring Security and creating a new Account when email verification is turned off.
You can define Account Registration & Verification workflows in the Directory attached to your Stormpath Application.
One of these workflows is Verification Email. That is, when a user creates an Account for your application, they will get an email with a link in it to verify their Account. By default, this is turned off.
Under these conditions, when you create an Account, you are immediately logged in to the Application. Only, the Stormpath Spring Security integration is not properly handling that login event, so it doesn’t know you’ve authenticated.
The workaround is to enable the Verification Email in the Stormpath Admin Console for the Directory associated with your Application.
This issue will be addressed in a upcoming release! In the meantime, you can learn more about building applications with our Spring Boot and Spring Security integration here.
If you work in web development, chances are you’ve heard about a nifty little
device called “Yubikey” that is becoming widely adopted as a simple and secure
form of two-factor authentication.
Yubikeys (pictured above) are small hardware devices that can be inserted into
your computer’s USB port, or touched to the back of a NFC device, and
generate securely random one-time passwords that can be used as a second factor
in authentication schemes.
Today, we’re going to take a look at how you can support two-factor
authentication in your Node.js and Express.js web applications using
Stormpath and Yubikey.
First Off: Why Yubikey for Two-Factor Authentication?
If you’re building a security-sensitive application, and want to ensure your end
users are who they say they are — allowing your users to authenticate with a
Yubikey device after logging in with their email address and password is a great way to ensure an extra level of security.
Yubikey devices generate securely-random passwords that are identifiable to each
hardware key. This means that when a user authenticates with a Yubikey, you
know they’re logging in with a strong, random password, that is 100% guaranteed
to have been generated by the specific hardware key this user has previously
registered with you.
Secondly, Yubikey secrets are never stored anywhere by any vendor. This means
that, unlike SMS, for instance, there is significantly less risk for third
parties to exploit two-factor authentication when a Yubikey is used.
Next, Yubikey devices are EASY for end users to use:
They are cheap (about $40 at the time of writing).
They require no software or drivers — you just insert it into your computer’s
USB port.
They cannot be “hacked” by malicious software. To authenticate with a Yubikey
device, the user must PHYSICALLY touch the small button on the Yubikey
device. This ensures malicious software won’t “automatically” attempt to
authenticate a user against their wishes.
On top of all the above, Yubikey devices comply with all the popular security
standards for devices like this, and are used at lots of larger companies:
Google, Facebook, Dropbox, etc.
Storing user accounts securely is another pain point in modern web
applications. There’s a lot of complexity in modeling out user schemas, group
and role schemas, and making things work with existing authentication and
authorization technologies like OAuth2, Basic Auth, Social Login providers,
etc.
Stormpath makes storing user accounts, handling
permissions and roles, and also integrating with other authentication
technologies really simple and secure.
Also: the Stormpath Express.js library is amazing! And I’m not just saying
that because I wrote it — cough cough. =)
Getting Started with Yubikey Two-Factor Authentication
To get started, you’ll need to have a Yubikey device, as well as a Stormpath
account. Assuming you have those two things ready to go, let’s clone the
example project and get going!
Finally, you’ll need to generate a Stormpath API key (once you log into
Stormpath, you can generate an API key by clicking the big API key button), as
well as create a Stormpath Application on the
Applications Page.
You’ll then need to set some Stormpath environment variables so the Node app
knows how to talk to Stormpath:
NOTE: The Stormpath Application href will be visible to you once you create
an Application on the Stormpath Applications page above.
Finally, you should be able to run the example project — just navigate to
http://localhost:3000 in your browser to get started.
Go through the registration and login workflow. You should see something like
this:
Cool, right?!
How Yubikey Two-Factor Authentication Works with Stormpath
Here’s how user registration works:
When a new user registers for your site, they will have a Stormpath Account
created.
Next, the new user will be forced to register a Yubikey device with their
account as a second authentication factor. This process makes the user insert
their Yubikey into their computer, and tap the button.
Once the Yubikey has been successfully registered with the user’s Stormpath
Account, they will be allowed into the website.
Here’s how user login works:
When a user logs into your site, they’ll be prompted for their email address
and password.
Once this information has been validated, the user will be prompted to insert
their Yubikey device and tap the button to verify themselves.
Once the user has been verified via Yubikey, they will be allowed into the
website.
As you can see, there’s a two step process. The user must have a normal user
account as well as a registered Yubikey device.
Behind the scenes, when a user registers their Yubikey device after there
account has been created, we’ll do two things:
We’ll verify that the Yubikey device is legitimate.
We’ll grab the Yubikey’s unique User ID, and store it in the user’s Stormpath
Account. This way we know in the future that when a user authenticates, that
they are authenticating with the CORRECT Yubikey device. Each Yubikey has a
unique ID associated with it.
When a user logs in, a similar process occurs: we verify the Yubikey password,
then ensure that the Yubikey ID is the one we previously stored in the user’s
Stormpath Account. Only then do we allow the user to log in.
To explore the code, and see how this works in detail, be sure to check out the
project’s Github repository!
Secure Two-Factor Authentication with Node.js and Yubikey
Adding secure two-factor authentication to your site doesn’t have to be hard.
Not only is the Yubikey device really easy to pair with any existing
authentication systems, but it also gives your users a really secure way to
prove their identity easily.
If you’re looking to build a secure site, I’d highly recommend checking out both
Yubikey and Stormpath.
Got any questions? Drop a comment below. If you’d like to learn more about the
Stormpath Express.js library, check out the articles below:
Visual Basic has a long and interesting history. For developers of a certain generation (including yours truly), a flavor of BASIC was your first language. Some snobs fans of other languages claim that the syntax is awkward and outdated, but VB.NET continues to fill a niche for rapid application (and web) development, just like its non-.NET predecessor did back in the early days.
If you love using XML literals in a pinch (try that, C#!), or just plain don’t like semicolons everywhere, never fear. I write more lines of C# these days, but VB.NET holds a special place in my heart, too. That’s why I’m excited about Stormpath support for VB.NET!
What’s that, you say? You need an easy way to handle user identity management and authorization, in just a few lines of code? You’re in luck! The Stormpath .NET SDK was built from the ground up with first-class support for VB.NET in mind.
In this short guide, I’ll walk through the steps necessary to build a simple VB.NET console application that uses Stormpath for user authentication and authorization.
To follow along, create a new Visual Basic.NET console project in Visual Studio. If you’re using a Mac, check out the guide I wrote about how I turned a MacBook Pro into the ultimate Visual Studio development machine.
Getting an API Key
All API requests to Stormpath require a valid API Key and Secret. The Stormpath .NET SDK does this automatically; all you have to do is generate an API Key in the Stormpath Admin Console.
If you haven’t already, register for Stormpath, and click the link in the verification email.
Click Create API Key or Manage API Keys under Developer Tools on the right side of the page.
Scroll down to Security Credentials and click Create API Key. This will generate your API Key and download it to your computer as an apiKey.properties file.
We recommend you store the API Key and Secret values as environment variables, or place the downloaded file into a hidden folder in your home directory. (In a production environment, environment variables are highly preferred!)
To store the API Key and Secret as secure environment variables, open the apiKey.properties file in a text editor and execute these commands in a terminal window (Command Prompt or PowerShell both work):
Note: If you followed the steps above to create secure environment variables (or placed the file into the default location of ~\.stormpath\apiKey.properties), you can omit this step! The next call to Clients.Builder.Build() will check the default locations for you; creating an IClientApiKey instance is only necessary if you need to specify the location of the API Key file manually.
Create an IClient instance. You’ll reuse this object to make calls to the Stormpath API:
1234
' Call to .SetApiKey() is only necessary if you manually created an IClientApiKey aboveDimclient=Clients.Builder_.SetApiKey(apiKey)_.Build()
When you registered for Stormpath, a default application called “My Application” was created for you. You’ll need to retrieve it by making a request to the Stormpath API:
Asynchronous and Synchronous Programming in VB.NET
This tutorial uses the Awaitable asynchronous methods available in the SDK. If you’re following along, you’ll need to make a small change:
1234567
SubMain()RunDemo.GetAwaiter.GetResult()EndSubPrivateAsyncFunctionRunDemo()AsTask' ... your existing code hereEndFunction
The SDK includes a synchronous API as well, if you don’t want to use Async and Await in your code. To make synchronous API calls, use the methods in the Stormpath.SDK.Sync namespace instead, and use the Synchronously helper method in LINQ queries:
To persist the account in Stormpath, you simply Await CreateAccountAsync (or call CreateAccount if you are using the Sync namespace):
1
Awaitapp.CreateAccountAsync(joe)
Authenticating a User
To make a login request, call AuthenticateAccountAsync and pass the username/email and password. This method will throw a ResourceException if the login is invalid, so you can wrap it in a try/catch block:
1234567
TryDimloginResult=Awaitapp.AuthenticateAccountAsync("tk421@deathstar.co","Changeme!123")DimloginAccount=AwaitloginResult.GetAccountAsync()Console.WriteLine("User "&loginAccount.FullName&" logged in!")CatchrexAsResourceExceptionConsole.WriteLine("Could not log in. Error: "&rex.Message)EndTry
If the login attempt is successful, the returned IAuthenticationResult instance will include a link to the authenticated account. Calling GetAccountAsync will follow the link and retrieve the account details.
Role-Based Authorization Using Groups
Stormpath models roles using Groups. To demonstrate assigning a role to Joe Stormtrooper, create some demo groups:
1234567891011
' In a production application, these would be created beforehand and only onceDimdemoUsers=client.Instantiate(OfIGroup)_.SetName("DemoUsers")_.SetDescription("Demo users who do not have administrator access.")DimdemoAdmins=client.Instantiate(OfIGroup)_.SetName("DemoAdmins")_.SetDescription("Demo users who have administrator access.")AwaitTask.WhenAll(app.CreateGroupAsync(demoUsers),app.CreateGroupAsync(demoAdmins))
Once the Groups are set up, assigning a user a role is a single line of code!
1
Awaitjoe.AddGroupAsync(demoUsers)
When your application needs to perform an authorization check, the Groups a user belongs to can be enumerated, and your application can grant or restrict access based on which Groups are present.
As a simple example, you can print the Groups Joe belongs to:
1234
DimroleNames=(Awaitjoe.GetGroups().ToListAsync())_.Select(Function(g)g.Name)Console.WriteLine("Roles for "&joe.GivenName&": "&String.Join(", ",roles))
Fine-Grained Permissions with Custom Data
If you need more granular control of a user’s permissions, you can store arbitrary key-value pairs using Custom Data.
For example, to indicate that Joe has read (but not write) access, you could store these values:
Checking the user’s permissions becomes a simple matter of getting and parsing the values you stored earlier:
12345
DimjoeCustomData=Awaitjoe.GetCustomDataAsync()DimcanRead=CBool(joeCustomData("read"))DimcanWrite=CBool(joeCustomData("write"))Console.WriteLine("Can Joe read? "&canRead)Console.WriteLine("Can Joe write? "&canWrite)
Custom Data isn’t limited to storing permissions data; it can also be used to store additional user profile information, or any other schemaless data you need to persist alongside your Stormpath resources. You can store strings, booleans, and other primitive data types – up to 10MB of data per resource.
Sample Code
A working example of the code from this article is available in the vb-console-sample Github repo. A synchronous version of the demo is included, so you can see how the Stormpath.SDK.Sync namespace works.
Code on, Fellow Visual Basic Traveler!
We’ve got plenty of exciting things coming up, including rich ASP.NET support! In the meantime, if you have questions or feature requests, don’t hesitate to send us an email, or join the conversation on Github.
Today, I’m going to walk you through everything you need to know in order to
build a secure API service with Express.js and Stormpath.
Specifically, I’ll walk you through building a simple Express.js API, and then
locking it down via HTTP Basic Authentication, and OAuth2 Client Credentials
authentication. These two authentication protocols allow you to build secure
server-to-server API services.
So, let’s do this!
Quick Note: What are Basic and OAuth2 Client Credentials Authentication?
When you’re securing an API service for use by server-side applications, you’ll
typically be choosing between two authentication protocols: Basic Authentication
or OAuth2 Client Credentials.
HTTP Basic Authentication is a very old, and popular protocol. The way it works
is simple:
Each developer is given an API key to access your service.
On every API request the developer makes, they’ll include this API key to
identify and authenticate themselves.
Simple.
Now, OAuth2 Client Credentials is a much newer protocol that is slightly more
secure than HTTP Basic Authentication, but works in a similar manner.
Each developer is given an API key to access your service.
The developer makes a special request to your API service using their API key
to obtain a temporary “Access Token”. This “Access Token” expires after a
short amount of time (usually an hour or so).
Then, the developer sends this “Access Token” to your API service on every
request, in order to identify / authenticate.
The OAuth2 protocol is slightly more secure than Basic Auth, as it doesn’t
require the developer to send their confidential API key over the public
internet as frequently, thereby reducing the chance of leaking confidential
information.
In general:
If you’re building an API service where security is a major concern, use
OAuth2.
If you’re building an API service where security is still important, but
convenience is also important: use Basic Auth.
Building a Simple Express.js API
Before we get into the authentication part, let’s build a simple Express.js API
service that we can use to secure later.
To get started, create a new folder somewhere, we’ll use this for our example:
12
mkdir examplecd example
Next, install express, as well as express-stormpath (which we’ll use
for authentication later on):
1
npm install express express-stormpath
Finally, create a new file: server.js, in which we’ll place our Express.js
code:
The small API service above exposes a single endpoint: /api/test, which just
returns a simple JSON message. If you run the above API service using node:
1
node server.js
And then run the following curl command to test the API endpoint — you’ll
see that things work as expected:
Now that we’ve got an API service we’re ready to secure, let’s create a
Stormpath account. Stormpath is an API service that stores user accounts
securely, and provides open source libraries that make it easy to build secure
websites and API services =) Andddd, it’s also 100% free!
Finally, create a new Stormpath Application for this example app. Typically,
each project you have will require it’s own unique Stormpath Application:
Once you’ve created a new Stormpath Application, copy the Application href,
we’ll need this in a moment.
Now that we’ve got our Stormpath stuff set up, let’s initialize the Stormpath
express library in our code — here’s the new source:
12345678910111213141516171819202122
'use strict';varexpress=require('express');varstormpath=require('express-stormpath');varapp=express();app.use(stormpath.init(app,{application:{// This href should be copied from the href of the Stormpath Application you// created.href:'https://api.stormpath.com/v1/applications/xxx'}}));app.get('/api/test',function(req,res){res.json({test:'successful!'});});app.on('stormpath.ready',function(){app.listen(3000);});
All we have to do here is make a couple minor modifications:
Initialize the Stormpath middleware, telling Stormpath what Application to
use.
Start the Express.js webserver only after the Stormpath library has been fully
initialized.
Now, with the modifications we made, all we’ve done is initialize Stormpath —
we haven’t yet secured our API.
We’ll get to that in the next section =)
Securing an API with Stormpath
To secure an API with Stormpath, you really only need to include one simple
middleware. Here’s our test route, from above, re-written to enforce API
authentication:
The only difference from before? We’ve included the
stormpath.apiAuthenticationRequired middleware. This middleware looks at
the HTTP Authorization header on incoming requests, and authenticates a user
based on their API credentials (either using Basic Auth or OAuth2), and
only once a user has authenticated, allows them to access the route.
Let’s see what happens if we retry our unauthenticated curl request from
earlier:
12
curl http://localhost:3000/api/test{"error": "Invalid API credentials."}
As you can see, we’re now getting an error (if you look at what headers are
returned, you’ll notice we’re also getting an HTTP 401 UNAUTHORIZED response).
Now, assuming we want to deploy our API live into production right now, all we’d
need to do is serve our API over HTTPs — and we’d have a secure API
service!
In the next section, we’ll go over how you can manage users, API keys, and
actually authenticate to your newly secured API service.
Managing Stormpath Users / API Keys
So, now that we’ve got a secure API, let’s go ahead and create a user account in
our Stormpath Application — this way we have a user who can eventually
authenticate against our API.
Usually, you’d create users by building a registration / login page (our
Express.js library can do that for you!), but for now, I’ll show you how to
manually create users.
First off, go to your newly created Stormpath Application from the
“Applications” page in your dashboard.
Next, click the “Accounts” on the left of your screen. From this page, you
can manually create a user account:
Once you’ve created a new user Account, scroll to the bottom of your new
Account, and open up the API Keys tab. In Stormpath, each Account can have as
many API keys as they want — so if you’re building an API service, Stormpath
will securely generate API keys for your users.
Click the “Create API Key” button to generate a new API key for this user.
This will download the user’s new API credentials so we can use them later:
That wasn’t too bad, right? With a few clicks we were able to create user
accounts, and API keys for our users.
In the next section, we’ll talk about how to authenticate against our new API
using our API credentials.
Authenticating Against an API Service
First, let’s talk about the most simple form of API authentication: Basic
Auth!
Basic Auth is my favorite form of API authentication because it’s very simple,
and most developers are familiar with it.
With Basic Authentication, a developer will send their API key to your API
service on each request they make, in order to authenticate.
When we generated an API key for our user in the previous section, we downloaded
an API key file.
If we open this file up, we should see some API credentials:
The --user flag tells curl to put our API credentials into Basic Auth format.
Easy right?
If you run the above curl command, you’ll see that now you’re able to
successfully authenticate and get the original JSON response back! Yey!
Now, let’s talk about OAuth2 Client Credentials.
The OAuth2 protocol provides several different authentication mechanisms — but
the type you want to use when building a server-to-server API is the Client
Credentials type.
This flow basically works like so:
A developer exchanges their API key for a temporary Access Token using your
API.
The developer then uses this Access Token to authenticate against your API
service.
This is a bit more secure than Basic Auth, because developers are not sending
their API keys to your service on every request — instead, they’re sending a
temporary access token only.
To generate an Access Token, we’ll first need to exchange our API key for an
Access Token using the Stormpath library:
By sending the above API request to /oauth/token (a route provided by the
Stormpath library automatically), you’ll get back a temporary Access Token as
shown above.
Now that we have an Access Token, let’s use it to authenticate against our API
endpoint!
So, you’re working with a shiny new API service in your latest project, and
while reading API documentation stumble across something worrying: “OAuth2
Client Credentials Authentication Required”.
Fear not, OAuth2 and the Client Credentials grant type are actually quite simple
once you know what you’re working with.
Today I’m going to show you how to authenticate against an OAuth2 API service
using Node.js.
What’s Up with OAuth2?
The OAuth2 protocol is pretty large, and allows users to authenticate in several
different ways. The OAuth2 protocol is broken up into separate “grant types”,
which are each used in different authentication scenarios.
I’ve written about OAuth2 in detail before, so if you want to know everything
about the protocol, you might want to start by reading this.
But, today we’re talking about authenticating against API services with OAuth2
— this means we’re going to be discussing the Client Credentials grant type!
The Client Credentials grant type is what you’ll be using if you’re writing
server-side software that authenticates against an OAuth2 API service.
The way it works is quite simple:
First, you (a developer) are given an API key.
Next, you make an API request to the OAuth2 API service and “exchange” your
API key for a temporary “Access Token”.
Finally, you use this temporary “Access Token” to make authenticated API
requests.
That’s it!
Now, let’s cover some terminology here:
When you exchange your API key for an Access Token, you’ll be making a POST
request to the API service at a particular URL, typically /oauth/token, and
supplying your API Key via Basic Auth.
An Access Token is just a long string. It could be anything — most of the
time though, it’s a cryptographically signed token known as a JWT. The most
important thing to know about Access Tokens is that they expire after a short
amount of time (usually an hour or so).
The reason Access Tokens expire, is so that you (a developer) don’t need to
constantly send your top-secret API key over the network. This reduces the risk
of your API key being compromised.
Exchanging an API Key for an Access Token
The first step in authenticating against an OAuth2 protected API service is
exchanging your API key for an Access Token.
Let’s take a look at how to do this.
Here are the requirements:
We need to create a POST request.
We need to supply grant_type=client_credentials in the body of our request.
Our request needs to be application/x-www-form-urlencoded.
We need to supply our API key credentials via Basic Auth.
Let’s say we have an API key with two components:
ID: xxx
Secret: yyy
We could use the curl command to get an Access Token from a typical OAuth2 API
service by doing:
12345
curl \ --user xxx:yyy --data grant_type=client_credentials -X POST https://api.someapi.com/oauth/token
NOTE: Most OAuth2 services use the /oauth/token URI endpoint for handling
all OAuth2 requests.
In Node, we could use the request library to do something similar:
When you receive a response from the OAuth2 server, you should get back a JSON
response that contains an access_token string.
Authenticating Against an OAuth2 API
Now that we’ve seen how we can exchange our API key for an Access Token, let’s
take a look and see how we can actually authenticate ourselves against an
OAuth2 protected API.
We’ll do this by generating an HTTP Authorization header, and including our
token inside of it.