Forcing HTTPS In MVC Project

It seems in light of revelations surrounding security of websites that there are more and more sites utilizing HTTPS instead of HTTP. The older reasons not to adopt HTTPS such as the burden on server and client processors has pretty much dissapeared. There is no real reason not to implement HTTPS and if you want to use protocols such as SPDY or HTTP/2 then you have to enforce a secure connection. To do this in an MVC project you have to do a few things, firstly add a filter to the GlobalFilterCollection like this:-

 

 

This code implements the RequireHttpsAttribute and allows through http connections if it is running on localhost which is ideal for a development team that doesn’t want to start messing arround with certificates.

Then you need to edit the web.config, again in a dev environment you can get away with creating transforms that will add the security side of things when you do a publish under that configuration.

The main points in the above code are the requireSSL attributes and the customHeaders element of system.webServer. The Strict-transport-Security custom header enforces HSTS which tells the browser to only connect on HTTPS and never on HTTP; this helps prevent such attacks as cookie hijacking.

In Chrome dev tools you should see this in the Response header:-

Strict-Transport-Security:max-age=16070400; includeSubDomains

Where the max-age is how long the browser will connect over HTTPS for; Twitter for example sets a max age of 20 years to prevent any attack on their servers circumventing HTTPS.

Posted in C#, MVC

Blogging Hiatus

Well its been quite a while since my last post and it might look like I wasn’t going to be blogging again. I am planning on writing more and posting the content here. The reasons I haven’t blogged in a while are numerous, but basically I have been involved with a project over the past 12 months that has taken up my time and at the tail end of last year I got a bit burned out with everything tech.

So excuses over, what am I going to be writing about in the coming weeks and months?

  • Windows 10
  • Node
  • Docker
  • Angular
  • .Net
  • TeamCity and CI/CD

Also I will be writing a bit about my experiences creating and running a mini SASS application which has just gone live called ObsPlanner.

So thats it for now. The first words are always the hardest.

Posted in Personal

Securing Web.API Requests With JSON Web Tokens

Part 1 – Securing Your Logins With ASP.Net MVC
Part 2 – Securing Web.API Requests With JSON Web Tokens (This post)

In the last post I went over the techniques you can use to secure your ASP.Net MVC logins using salted hashes in the database. This post covers the web service layer and how to secure requests to service calls that are essentially exposed to the big bad web. To show what sort of layering I am discussing, here is a basic example of the various layers I have been using on a number of projects.

Three tier architecture

Three tier architecture

 

Once the user has been validated and allowed into the site, all service requests are done on their behalf. To make sure nobody who is not validated get access to the service calls, we implement JSON Web Tokens or JWT.

JSON Web Tokens

Jason Web Tokens are a standard and url safe way of representing claims and was created by the Internet Engineering Task Force (IETF). They are in the form like this:-

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
.
eyJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3VzZXJkYXRhIjoiSXNWYWxpZCIsImlzcyI6InNlbGYiLCJhdWQiOiJodHRwczovL3d3dy5tb2xhcnMub3JnLnVrIiwiZXhwIjoxNDI1NTY2ODY5LCJuYmYiOjE0MjU1NjMyNjl9
.
5XieXPt8kvbAgBlmB-IclmpaIR_PkcusIUc_tWlcxas

A JWT is split into 3 sections which comprise of:-

JOSE Header – this describes the token and the hashing algorithm that is being used for it.
JWS Payload – the main content and can include claims sets, issuer, expiry date as well as any bespoke data you want to include
Signature hash – base64 encoding the header and payload and creating the message authentication code (MAC) leads to the signature hash

Creating JSON Web Tokens in .Net

Going back to the web project, in the constructor of each controller, create a private field that will store our token string.

The code to generate the token uses the System.IdentityModel.Tokens.Jwt namespace which you may need to add extra references for by using the NuGet packages.
The call to Authorization.GetBytes() is a method call from a class we use in a business object that sits in the Webservice layer. All it does is turns a string into a byte array.

Here we just store the web token in the viewbag for rendering on each view, the reason we do this is because we don’t want to run into any cross domain issues as our web and web service layers are running on different machines on different urls.

Now in the angular code that is calling into the service layer we extract that token and append it to the call as a parameter.

Consuming JSON Web Tokens

In the web service layer we intercept each call by creating an override on the OnAuthorization method inside AuthorizeApi.cs within App_Start.

If they have the correct and valid token then they proceed to get the data from the API call, if not they get sent a 403 Forbidden response.

References:-

JSON Web Token (JWT) – OAuth Working Group

Posted in C#, CodeProject, MVC, Practices, Web

Securing Your Logins With ASP.Net MVC

Part 1 – Securing Your Logins With ASP.Net MVC (This post)
Part 2 – Securing Web.API Requests With JSON Web Tokens

An archetectural patterns that is becoming more popular is using ASP.Net MVC with a Web.API layer servicing the web front end via angular.js or similar technology. A kind of hybrid SPA with all the benefits that ASP.Net bring to the table.
This is a two part primer running through what I do to secure logins to MVC applications. In part two I will expand on this post to cover how to secure the Web.API layer utilizing the security built into ASP.Net.

If you ever go to a web site and you cannot remember your password, you will most likely have requested a password reminder. If you get sent your current password in plain text, then that is bad news. It means the website is storing passwords in plain text and if they get hacked then they will have access to those passwords, and knowing the fact that people have a tendency to use the same password on multiple sites then they could compromise multiple sites that you use. It is really important to salt and hash your passwords for storage in the database. By doing this, you can do a string comparison against the hash and not the actual password. Here I will go through the process in code.

As usual you will have a login screen asking for username (or email address) and password. I won’t go into the MVC/Razor side here, just the important code.

Take in the two form values

The LookupUser method on the SecurityService is where the magic happens

This method looks up the User from the database via a UserRepository and appends the salt to the password the user has provided. I explain what salts and hashes are a little later on, but for now know they are just a random string representation of a passkey. This combination of password and salt are then passed into the GetPasswordHashAndSalt method of the PasswordHash class.

The GetPasswordHashAndSalt method reads the string into a byte array and encrypts it using SHA256, then returns a string representation of it back to the calling method. This is then the hash of the salted password which should be equal to the value in the database. On line xx the repository does another database look-up to get the User that matches both the email address and hash value. OK, so how do we get those hashes and salts in the database in the first place? When a new user account is set up you need to generate a random salt like this:-

You then store the usual user details in the database along with the salt and the hashAndSalt values in place of the password. By generating a new salt each time an account is created you minimize the risk that a hacker will get the salt and regenerate the passwords from the hashAndSalt value.

Now back to the login POST method on the controller. Once the user has been authenticated in the system, you need to create a cookie for the ASP.Net forms authentication to work.

First create a ticket that stores information such as the user logged in.

Where LoggedInUser is the valid User object we got from the database earlier. To check for a valid ticket throughout the site, you can decorate each action method with [Authorize] filter attributes, or you could do the whole site and just have [AllowAnonymous] attributes on the login controller actions. To do this for the whole site firstly add a new AuthorizeAttribute to the FilterConfig.cs file inside App_Start like this:-

Then in the Application_AuthenticateRequest method to the global.asax.cs file add this:-

This method will check every request coming in to see if it has a valid FormsAuthentication ticket. If it doesn’t then it will redirect the user to the default location specified in the web.config file.

Posted in C#, CodeProject, MVC, Practices, Web