Magic Authentication and Authorisation
If you are creating your own authentication and authorisation system, the statistical probability of that you are exposing your app to hackers is 99.999%
Join the DZone community and get the full member experience.Join For Free
Magic was created to solve all the repetitive problems I experience in my day job. One of these problems happens to be authentication and authorisation, which is a problem you have to solve every time you create a new application. At this point some might argue that OAuth2 solves these problems, and while technically that is true, OAuth2 is also ridiculously complex and over engineered, and very easy to get wrong. And of course if you get your app's auth parts wrong, you might as well not have auth at all, since it exposes your apps for adversaries doing whatever they want to do with your app. Authorisation is one of those things together with cryptography you really should not solve yourself, unless you really know what you're doing. Watch the following video for a walkthrough of how the auth parts in Magic works.
As you can see in the above video, Magic contains a million parts helping you out with your authentication and authorisation requirements, such as the ability to lock users, implement double optin registrations, having users confirm their email address before being accepted into your site, resetting passwords, etc. In addition of course, the coolest parts is that the Magic Dashboard also contains high level UI components, allowing you to easily administrate your user database, such as illustrated below.
Imagining your manager giving you the required time to implement the above is probably at best delusional, regardless of what company you work for. With Magic, it's simply there. Combining this with the auditing and diagnostic features of Magic, allowing you to see high level KPI charts related to security issues, such as illustrated below - Results in that Magic's features from a conceptual point of view related to this, is something you're probably never going to be able to reproduce using any other means.
Magic exposes a couple of crucial endpoints related to authentication that simplifies your life. These are as follows.
- GET magic/modules/system/auth/authenticate - Authenticates a user with a username/password combination
- PUT magic/modules/system/auth/change-password - Allows a user to change his or her password
- GET magic/modules/system/auth/refresh-ticket - Refresh a user's JWT token granting a new token with a new expiration value
- POST magic/modules/system/auth/register - Allows others to register as users in your system
- POST magic/modules/system/auth/send-reset-password-link - Sends a reset password link to the user's email address
- POST magic/modules/system/auth/verify-email - Double optin endpoint allowing users to verify their emails
- GET magic/modules/system/auth/verify-ticket - Returns success status code if JWT token is valid
Combining the above endpoints gives you more or less everything you need related to authentication and authorisation, allowing you to build UI components in any framework of choice, wrapping the above backend endpoints.
JWT is easily explained to a child. OAuth2 on the other hand, is ridiculously complicated and over engineered, to the point where even the guy in charge of the standardisation committee went on a 2 year long tour throwing sessions who's names were as follows; "OAuth2 sucks!" OAuth2 might be cool if you're Google or Facebook, but if you're anything else, it's a hot smoking pile of garbage!
Seriously, OAuth2 SUX!
JWT on the other hand is ridiculously simple to understand. It's based upon a secret, which you can find in Magic as a configuration setting. Below are all configuration settings related to auth in Magic.
Assuming you can keep the above secret a secret, your auth system is secure enough to be consumed by FSB, MI6 and CIA. The idea is that once a JWT token is generated, its payload is concatenated with the above secret, and a SHA256/HMAC is constructed, which unless can be correctly reproduced in the .Net middleware upon consecutive requests, results in that the token is considered invalid, and the user will not be authorised to do anything requiring authorisation. By default Magic will use the BouncyCastle CSRNG classes to generate your auth secret. But if you're super paranoid, you can also manually edit it as you see fit.
In fact, using Magic as your JWT auth server, to integrate it into your own custom C# apps, is as simple as configuring the correct middleware by implementing a handful of lines of custom C# code. You can get an idea of how to get started by looking at the C# code for magic.lambda.auth. This allows you to share the secret Magic has with your own custom application, and use Magic as an "auth server" having single sign on in your enterprise. As long as you can keep your auth secret a secret, this is a perfectly legitimate method to implement SSO.
On the server side Magic contains a lot of helper slots simplifying your life as you create your apps. These are as follows.
- auth.ticket.create - Creates a new JWT token
- auth.ticket.get - Returns the username and roles associated with the current request
- auth.ticket.in-role - Returns true if user belongs to any of the specified roles
- auth.ticket.refresh - Creates a refreshed JWT token from the old token
- auth.ticket.verify - Verifies that the user is authenticated, and optionally belongs to one or more roles
You can find the complete documentation for these parts in the magic.lambda.auth parts of the documentation. Most of these are "AOP'ish in nature", allowing you to simply inject them into your own Hyperlambda code, resulting in some sort of expected result meeting your requirements related to auth.
Internally Magic will generate an authentication and authorisation database for you 100% automagically as you initially configure Magic. This is one of the reasons why it asks you for a valid database connection during its setup process. The tables related to auth in this database are as follows.
- users - Contains usernames and passwords
- roles - Contains all roles
- users_roles - A many to many link table containing the association between users and roles
This structure is of course easily expanded upon, if you need additional information, such as extra information associated with users, containing for instance user's full names, etc. If you use for instance the "SQL" menu item and you select all records from your users table using something such as the following.
You can see how the passwords are stored using slow BlowFish hashing with individual record based salts.
This is one of those million things that might go wrong as you implement your own authentication, which if done wrong, opens up your password database for Rainbow Dictionary attacks, allowing at least in theory adversaries to brute force your users' passwords. Which of course is a major security threat, since users tends to reuse the same passwords on multiple sites/applications - Implying if an adversary gains access to your user's password in one app, he effectively gains access to your user's passwords in all apps the user is using, and can easily impersonate the user across the entirety of the web.
This results in that you might get sued over your "free pony website" since one of your users reused his or her password on your site also for his internet banking website. I cannot emphasise this strongly enough; Unless you know with 100% certainty what you are doing ...
Do NOT implement your own auth system!
If I had my will, we would legislate the World Wide Web having sites not implementing slow hashing and individual per record based salts showing the following disclaimer.
Warning, by registering at this site, North Korean mafia might steal your credit cards!
We could show the above warning next to the "cookie disclaimer" ... ;)
When you initially configured Magic, you probably noticed that you can use any password you wish, and that Magic does not require you to use special characters, numbers, caps, etc. This actually increases the password entropy of your database, since it allows users to for instance provide sentences and phrases as passwords. The following is a perfectly legitimate password in Magic.
This is a perfectly fine password
Paradoxically, and a bit counter intuitive may I add, this actually results in much stronger passwords than the commonly accepted dogma of providing something such as follows.
The above password for instance is 8 characters long. On average it takes a normal laptop approximately 20 minutes to brute force the above password. While the first password above, containing 33 characters, would require more energy than that which is required to boil all water on earth to brute force. Hence, these ridiculous restrictions for instance Apple has as you creates passwords for their AppStore, is quite counterintuitively much simpler to guess than simple phrases and sentences such as Magic allows you to use. Simply since allowing a user to use a simple sentence, increases password length easily by one order of magnitude, making the brute force approach require trillions of times the number of iterations to guess your users' passwords using a brute force approach.
Combining this with the fact of that users have different native languages, might be using slang etc - Results in that the entropy becomes the same, only exponentially growing for each additional character the user adds to his password. The point of course being that for me as a Norwegian, the following password is ridiculously simple to remember, since it's a Norwegian sentence, that makes perfectly sense for me, which I could easily memorise.
Heisann, teisann, mitt navn er Thomas Hansen og jeg er KUL!
The above password contains 71 characters, and brute forcing it with any known technology we have at our disposal today, would require more energy than the amount of energy required to boil all the water that exists in our galaxy. Implying it's not even possible in theory to brute force the above password. So the above password is actually stronger than the 8 letter "special character password" above it - In addition to that it's a trillion times easier to remember, and allows your users to create unique passwords for all their online services, reducing the likelihood of having your password compromised at one site resulting in that your entire online life is compromised.
However, since Magic also is using individual per record based salts, combined with BlowFish hashing, even if your user has a single character password, the CPU time required to brute force a single character password would still be practically impossible, even if an adversary had access to your entire password database. This is due to the nature of BlowFish hashing, combined with per record based salts.
Don't do this at home kids!
Seriously, do not implement your own authentication system. As you can see, there are clearly a million things that can go wrong. For instance, one of the most popular Open Source OAuth2 implementations for .Net literally contains thousands of security issues (no, I will not tell you which project I am talking about) - I should know, because I ran it through SonarQube to check it out in one of my previous jobs. It contained so many security holes that SonarQube almost crashed and refused to continue. Compare this to Magic's auth system that scores 100% perfect ...
79.3% Unit Test coverage, zero security holes, and the 4 code smells above are actually simplifications for its unit tests, carrying no semantic changes. Unless you can implement your auth system having traits such as the above, you basically have no auth system, and you might as well publish your users' passwords in clear text on the dark web for all to see ...
DO NOT IMPLEMENT YOUR OWN AUTH!
Even if you've got the skills to do it correctly, you highly unlikely will be given the time from your manager to do it correctly. And unless you do it correctly, there are a million things that can go wrong! Auth is the heart of your software, and if one part of it is incorrectly implemented, you basically have no auth.
In this article we walked through some of the features of the authentication and authorisation system of Magic, and we showed the high level UI modules giving you administration and KPI capabilities, in addition to how you could use this to your own advantage in your own apps. Afterwards we walked through several general security concerns, such as slow hashing, password entropy, and general security concerns related to auth. Let's finish up with a nice quote we can all remember.
There are two types of companies, those who are hacked and doesn't know it, and those who used Magic Auth ;)
Published at DZone with permission of Thomas Hansen. See the original article here.
Opinions expressed by DZone contributors are their own.