Establishing Digital Trust: Don't Sacrifice Security for Convenience
By Aleksey Gavrilenko, Itransition
Approaches to security issues change constantly, along with evolving threats. One approach is to implement OAuth, an open authorization standard that provides secure access to server resources. OAuth is a broad topic with hundreds of articles covering dozens of its aspects. This particular article will help you create a secure authorization server using OAuth 2.0 in .NET to use for your mobile clients and web applications.
What is OAuth?
OAuth is an open standard in authorization that allows delegating access to remote resources without sharing the owner's credentials. Instead of credentials, OAuth introduces tokens generated by the authorization server and accepted by the resource owner.
In OAuth 1.0, each registered client was given a client secret and the token was provided in response to an authentication request signed by the client secret. That produced a secure implementation even in the case of communicating through an insecure channel, because the secret itself was only used to sign the request and was not passed across the network.https://o1.qnsr.com/log/p.gif?;n=203;c=204650394;s=9477;x=7936;f=201801171506010;u=j;z=TIMESTAMP;a=20392931;e=i
OAuth 2.0 is a more straightforward protocol passing the client secret with every authentication request. Therefore, this protocol is not backward compatible with OAuth 1.0. Moreover, it is deemed less secure because it relies solely on the SSL/TLS layer. One of OAuth contributors, Eran Hammer, even said that OAuth 2.0 may become "the road to hell," because:
"… OAuth 2.0 at the hand of a developer with deep understanding of web security will likely result in a secure implementation. However, at the hands of most developers – as has been the experience from the past two years – 2.0 is likely to produce insecure implementations."
Despite this opinion, making a secure implementation of OAuth 2.0 is not that hard, because there are frameworks supporting it and best practices listed. SSL itself is a very reliable protocol that is impossible to compromise when proper certificate checks are thoroughly performed.
Of course, if you are using OAuth 1.0, then continue to use it; there is no point in migrating to OAuth 2.0. But if you are developing a new mobile or an Angular web application (and often mobile and web applications come together, sharing the same server), then OAuth 2.0 will be a better choice. It already has some built-in support in the OWIN framework for .NET that can be easily extended to create different clients and use different security settings.
Implementing OAuth 2.0 in OWIN
OWIN is a .NET framework for building ASP.NET Web API applications. It offers its own implementation of OAuth 2.0 protocol where two major OAuth terms (clients and refresh tokens) are not strictly defined and need to be implemented separately. On the one hand, it adds some complexity -- because each developer needs to decide how to implement them exactly -- and, on the other hand, it adds the extensibility and new opportunities.
The exact implementation with code snippets can be found in tutorials across the web and in open source projects at GitHub; and therefore it is out of scope of the current article. In particular, Taiseer Joudeh, a Microsoft consultant, has written an article with a step-by-step description of the exact implementation.
From my own experience, it's best to use the following techniques when implementing and using an OAuth 2.0 authorization server:
- Always use SSL. OAuth 2.0 security depends solely on SSL and using OAuth 2.0 without it is just like sending a password in a plaintext across an insecure Wi-Fi connection.
- Always check the SSL certificate to protect from the man-in-the-middle attacks. For web applications, the browser does that job and warns the user if the certificate is not to be trusted. For mobile applications, the application itself should check the certificate for validity.
- Do not store client secrets in the database in plaintext; store the hashed value instead. You may choose not to store client secrets at all (which is an acceptable solution if the authentication relies solely on passwords), but keeping them in plaintext will pose a security threat if they become critical in the future.
- Always use refresh tokens and make access tokens short-lived. Using refresh tokens will give you the following three benefits:
- They can be used to avoid access tokens living forever and not forcing the user to re-enter credentials at the same time. As a bonus, for web applications they can be used to imitate session expiration. When the user is idle for some time, both the access and the refresh token will expire and the user will be forced to re-login.
- They are revocable. When the user changes the password, the token can be revoked and the user will be forced to re-login on all mobile devices. This is very important because a device may be stolen and having a logged-in session on it will pose a significant security threat.
- They can be used for updating access token content. Normally, access tokens are validated without a roundtrip to the database. This makes it faster to process, but user roles (that are cached in claims) may not be easily updated or, even more importantly, revoked if access token expiration takes a long time. Refresh tokens are of great help here because they shorten the access tokens' life.
OWIN Implementation of OAuth 2.0 Offers Flexibility
Also, current OWIN implementation of OAuth 2.0 is flexible enough to be altered to fit particular business needs:
- If there is a background service that needs to act as any user, it can be integrated seamlessly into the authentication process in the following way:
- Alter the clients table by adding a PasswordRequired column.
- Handle the case when the password is not required in the source code.
- Create a new client in the clients table and use it for the background service. Always secure the secret for this client as it will act like the master password. (Never store this secret in plaintext.)
- Alter the clients table by adding an AllowedRoles column.
- Implement additional checks for the user role to the authentication code.
- Dedicate different rows in the client's table for each application. Remember that the authorization checks in the server API must be implemented in any case.
Remember, No Authentication Method Is Perfect
There is no ideal way to protect users from attacks when using applications, and even OAuth 2.0 has advantages and flaws exposed in implementations. By avoiding implementation mistakes and using the methods described in the article above, developers can help users stay more secure without breaking the seamless interaction with the app.
Aleksey Gavrilenko is a senior developer at Itransition and is the technical lead for a large ASP.NET project on automating key project document management and control procedures for leading engineering and utilities companies in the U.S. and around world. He received a master’s degree in computer science from Belarusian State University. His areas of interest are .NET, enterprise content management, performance tuning, and software design and architecture.