locked
Securing the web api RRS feed

  • Question

  • User-1782410546 posted

    Hi,

    I developed a SPA uisng angular JS , ASP.NET MVC and web api.

    Angular js and ASP.NET MVC is built in single solution

    and web api is a separate solution.

    And these are hosted in the same server with different ports.

    I want to secure the web api.

    When i test a web api method using browser or a ajax call from other web application , it returns the result. 

    I am not using OWIN or Identity or other middle ware authentication server.

    In my DB , i have a user table , when ever a user logins , i try to verify the credentials and store the user name in a session if he is a valid user.

    Please can any one tell me a simple and secured way to secure the web api.

    Thanks,

    Vijay Devd

    Monday, October 24, 2016 12:31 PM

Answers

  • User-691209617 posted

    Hi,

    Have you tried  to apply HMAC authentication to secure Web Api. HMAC authentication uses a secret key for each consumer which both consumer and server both know to hmac hash a message, HMAC256 should be used. Most of cases, hashed password of consumer is used as secret key.

    You can see the demo code here too.

    https://github.com/cuongle/Hmac.WebApi

    Simply the method looks like below.

    private static string ComputeHash(string hashedPassword, string message)
    {
        var key = Encoding.UTF8.GetBytes(hashedPassword.ToUpper());
        string hashString;
    
        using (var hmac = new HMACSHA256(key))
        {
            var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
            hashString = Convert.ToBase64String(hash);
        }
    
        return hashString;
    }

    The below mentione link helps as it define allot of ways.

    http://stackoverflow.com/questions/11775594/how-to-secure-an-asp-net-web-api

    Hope it helps.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, October 24, 2016 12:45 PM

All replies

  • User-691209617 posted

    Hi,

    Have you tried  to apply HMAC authentication to secure Web Api. HMAC authentication uses a secret key for each consumer which both consumer and server both know to hmac hash a message, HMAC256 should be used. Most of cases, hashed password of consumer is used as secret key.

    You can see the demo code here too.

    https://github.com/cuongle/Hmac.WebApi

    Simply the method looks like below.

    private static string ComputeHash(string hashedPassword, string message)
    {
        var key = Encoding.UTF8.GetBytes(hashedPassword.ToUpper());
        string hashString;
    
        using (var hmac = new HMACSHA256(key))
        {
            var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
            hashString = Convert.ToBase64String(hash);
        }
    
        return hashString;
    }

    The below mentione link helps as it define allot of ways.

    http://stackoverflow.com/questions/11775594/how-to-secure-an-asp-net-web-api

    Hope it helps.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, October 24, 2016 12:45 PM
  • User-1782410546 posted

    Hi,

    Thanks for your reply.

    I have gone through the link you provided.Really its useful.

    But how can i utilise the same when i call a web api method using ajax call from client side.

    Thanks,

    Vijay Devd.

    Monday, October 24, 2016 5:37 PM
  • User-691209617 posted
    $.ajax({
                    url: '../api/Login/Login',
                    type: 'POST',
                    dataType: 'json',
                    contentType: 'application/json; charset=utf-8',
                    data: JSON.stringify(Login),
                    success: function (data) {
                        alert("Saved successfully");
                    }
                });

    As you are accessing Web Api by action name, please enable Web Api route by action name in WebApiConfig.cs

    public static void Register(HttpConfiguration config)
            {
                config.MapHttpAttributeRoutes();
                config.Routes.MapHttpRoute(
                    name: "MapByAction",
                    routeTemplate: "api/{controller}/{action}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
           }

    Also please make sure you have following entry in Application_Start() in Global.asax.cs

    GlobalConfiguration.Configure(WebApiConfig.Register);

    Monday, October 24, 2016 6:33 PM
  • User-1782410546 posted

    Hi,

    At client side in javascript where we can have a  message handler that uses the methods to calculate the signature and attaches it to the request (as HTTP header)

    Thanks,

    Vijay Devd

    Tuesday, October 25, 2016 10:55 AM
  • User-691209617 posted

    Hi vijay,

    Can you please go through in below mentioned article.

    https://www.asp.net/web-api/overview/advanced/http-message-handlers

    Hope it helps.

    Tuesday, October 25, 2016 12:49 PM
  • User-1782410546 posted

    Hi,

    Can we apply HMAC authentication when the client is Angular JS application.

    Thanks,

    Vijay Devd.

    Tuesday, October 25, 2016 1:39 PM
  • User-691209617 posted

    Hi Vijay,

    User authenticates, username and password over https in the following way.

    1. Server (node.js+express) sends back a temporary universal private key to authenticated users. This key is what the user will use to sign HMACs client side and is stored in LocalStorage on the browser, not a cookie (since we don't want it going back and forth on each request).

      • The key is stored in nodejs memory and regenerates every six hours, keeping record of the last key generated. For 10 seconds after the key changes, the server actually generates two HMACs; one with the new key, one with the old key. That way requests that are made while the key changed are still valid. If the key changed, the server sends the new one back to the client so its can flash it in LocalStorage. The key is a SHA256 of a UUID generated with node-uuid, hashed with crypto. And after typing this out, i realize this may not scale well, but anyway ...

    2. The key is then stored in LocalStorage on the browser (the app actually spits out a your-browser-is-too-old page if LocalStorage is not supported before you can even try to login).

    3. Then all requests beyond the initial authentication send three custom headers:

      • Auth-Signature: HMAC of username+time+request.body (in my case request.body is a JSON.stringify()'d representation of the request vars) signed with the locally stored key
      • Auth-Username: the username
      • X-Microtime: A unix timestamp of when the client generated its HMAC

    4. The server then checks the X-Microtime header, and if the gap between X-Microtime and nowis greater than 10 seconds, drop the request as a potential replay attack and throw back a 401.

    5. Then the server generates is own HMAC using the same sequence as the client, Auth-Username+X-Microtime+req.body using the 6-hour private key in node memory.

    6. If HMACs are identical, trust the request, if not, 401. And we have the Auth-Username header if we need to deal with anything user specific on the API.

    All of this communication is intended to happen over HTTPS obviously.

    Here is the example you can use.

    https://github.com/Monofraps/angular-node-hmac-example

    Tuesday, October 25, 2016 2:39 PM