Authentication for webapi

Earlier we have seen how to Create WEBAPI for GET POST PUT methods, as a part of security we can use userid & Password authentication for the service. Each time while the request has been received credentials in the headers are validated before giving response.

  1.   Create new Controller

Create get method to return some data from table.
Controller code with entity framework:

              using System.Threading;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WEBAPIAUTHORIZATION.Models;

namespace WEBAPIAUTHORIZATION.Controllers
{
    public class EmployeeController : ApiController
    {
        public HttpResponseMessage Get() //GET
        {
            string username = Thread.CurrentPrincipal.Identity.Name;
            using (ACT2_MINIQEntities entities = new ACT2_MINIQEntities())
            {
                var employeelist = entities.EmployeeDetails.ToList();
                return Request.CreateResponse(HttpStatusCode.OK, employeelist);
            }
        }
    }
}


2.   Create new class at the root folder of the webapi project.

In my case creating class with Security.cs


                  using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WEBAPIAUTHORIZATION.Models;

namespace WEBAPIAUTHORIZATION
{
    public class Security
    {
        public static bool Login(string Username, string Password)
        {
            //Database connection to retrive daata
            using (ACT2_MINIQEntities entities = new ACT2_MINIQEntities())
            {
                //returns bool
                return entities.users.Any(
                        x => x.username.Equals(
                            Username, StringComparison.OrdinalIgnoreCase)
                            && x.passcode == Password);
            }
        }
    }
}


1.   Create Another new class at the root folder of webapi project.

In my case I have named as Authentication.cs


using System;
using System.Linq;
using System.Web.Http.Filters;
using System.Threading;
using System.Net.Http;
using System.Net;
using System.Text;
using System.Security.Principal;
using System.Web.Http.Controllers;

namespace WEBAPIAUTHORIZATION
{
    public class Authentication : AuthorizationFilterAttribute
    {
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            if (actionContext.Request.Headers.Authorization == null)
            {
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
            }
            else
            {
                string authenToken = actionContext.Request.Headers.Authorization.Parameter;
                string decodedToken = Encoding.UTF8.GetString(Convert.FromBase64String(authenToken));
                string[] credentials = decodedToken.Split(':');

                string userName = credentials[0];
                string password = credentials[1];

                if (Security.Login(userName, password))
                {
                    Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(userName), null);
                }
                else
                {
                    actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
                }
            }
        }
    }
}


4.       Changes in WebApiConfig.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using Microsoft.Owin.Security.OAuth;
using Newtonsoft.Json.Serialization;

namespace WEBAPIAUTHORIZATION
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            //to authenticate globally
            config.Filters.Add(new Authentication());
        }
    }
}


To test output, we should send the credentials in request headers

Credentials should be in format of   username:Password

Credentials should be encoded to base64 format. As shown below.

Read More »

WEB API Throws “No Access-Control-Allow-Origin” Header is present on the requested resource.

This is the error occurs in the Client application that is consuming the WEB API. There might be two different reasons,

Web API by default doesn’t allow Service to be consumed from different domains.

  1.   RESOLVED BY CORS:

 [WEB API APPLICATION]

Open Tools ->   NuGet Package Manager - > Package Manager Console 
And install NuGet packages

Install-Package Microsoft.AspNet.WebApi.Cors

     GO to WebApiConfig.cs

          Add [ using System.Web.Http.Cors;  ] namespace in webapiConfig.cs file

               EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "*");
       CONFIG.EnableCors(cors);


         First star resembles allow requests from all domains, else we can specify specific client URLS, separated by comma (,).

          Second star resembles allow requests for all the headers.

          Third star resembles allow requests for all the methods like POST, GET, PUT, DELETE, etc 


  2.   RESOLVED BY REMOVING HEADERS IN CLIENT REQUEST[AFTER CORS IMPLEMENTATION]

       
While no headers specified in WEB API, just try to remove the headers from the client side.


Read More »

Create WEBAPI Using Console Application and Host as Self-Hosting

We have seen earlier creating WEBAPI selecting WEBAPI project type, also we can create the WEBAPI using Console application.

Soon after listening the word console application we will get a doubt that how the URL of the service is exposed with a generated Executable file (.EXE).

Here we are going to host the application as a Self-Hosting

1.   Create new project


2.   Under Visual C# select Console application as a project type.


3.   Click on Tools ->   NuGet Package Manager - > Package Manager Console.
Install OwinselfHost package for self hosting (internet connection mandatory)

   PM> Install-Package Microsoft.AspNet.WebApi.OwinSelfHost


4.   If the API is also used to consume as a cross origin, we should install CORS packages (internet connection mandatory)


   PM> Install-Package Microsoft.AspNet.WebApi.Cors


5.   Add new class to the project and name it to Startup.cs [Name should be same for self-Hosting]

Place the below code in Startup.cs


              using System;
using Owin;
using System.Web.Http;
using System.Net.Http;

namespace firstMicroService
{
    public class Startup
    {
        public void Configuration(IAppBuilder appBuilder)
        {
            HttpConfiguration CONFIG = new HttpConfiguration();
            CONFIG.EnableCors();
            CONFIG.Routes.MapHttpRoute(
                name: "createUserApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
                );
            appBuilder.UseWebApi(CONFIG);
        }
    }
}



6.   Create new class with [EmployeeController.cs] which inherits from ApiController

Place the code as shown below.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Cors;

namespace firstMicroService
{
    public class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Salary { get; set; }
    }

    [EnableCors(origins:"*", headers:"*", methods:"*")]
    public class EmployeeController : ApiController
    {
        Employee[] employees = new Employee[]
        {
            new Employee{Id=0,Name="Morris",Salary="151110"},
            new Employee{Id=1,Name="John", Salary="120000"},
            new Employee{Id=2,Name="Chris",Salary="140000"},
            new Employee{Id=3,Name="Siraj", Salary="90000"}
        };

        public IEnumerable<Employee> Get()
        {
            return employees.ToList();
        }

        public Employee Get(int Id)
        {
            try
            {
                return employees[Id];
            }
            catch (Exception)
            {
                return new Employee();
            }
        }

    }
}



7.   Open Program.cs file and replace with below code.

using Microsoft.Owin.Hosting;
using System;

namespace firstMicroService
{
    class Program
    {
        static void Main(string[] args)
        {
            string domainAddress = "Http://20.201.36.49/";

            using (WebApp.Start(url: domainAddress))
            {
                Console.WriteLine("Service Hosted " + domainAddress);
                System.Threading.Thread.Sleep(-1);
            }
        }
    }
}


9.   Run the application and keep the console open.
                  




10.   Service is written only for GET method, to test the service,

{given Domain address}/{api}/{Given controllername}/{optional id}

In my case am testing the service with POSTMAN REST Client,

http://20.201.36.49/api/Employee/1


Testing Service.



Read More »