Self Hosted Microservice using OWIN, WebApi to authenticate users, this service will store the authentication token on a file and subsequent requests are compared against the stored token.

Author: Shahim Sadakath


Hi Guys,


This time I created Self Hosted Microservice using OWIN, WebApi to authenticate users, this service will store the authentication token on a file and subsequent requests are compared against the stored token.


Hope you like it.

1) Create a console application as following

 


2) Install following packages using Nuget 

Microsoft.AspNet.WebApi.OwinSelfHost

Microsoft.Owin

Microsoft.AspNet.Cors


3) Startup.cs 

using Microsoft.Owin;

using Microsoft.Owin.Security.OAuth;

using Owin;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net.Http.Headers;

using System.Text;

using System.Threading.Tasks;

using System.Web.Http;


namespace SelfHosted.MicroService

{

    public class Startup

    {

        // This code configures Web API. The Startup class is specified as a type

        // parameter in the WebApp.Start method.

        public void Configuration(IAppBuilder appBuilder)

        {

            // Configure Web API for self-host. 

            HttpConfiguration config = new HttpConfiguration();

            config.EnableCors();

            config.Routes.MapHttpRoute(

                name: "DefaultApi",

                routeTemplate: "api/{controller}/{id}",

                defaults: new { id = RouteParameter.Optional }

            );


            config.Formatters.JsonFormatter.SupportedMediaTypes

    .Add(new MediaTypeHeaderValue("text/html"));


            ConfigureOAuth(appBuilder);

            appBuilder.UseWebApi(config);

        }


        public void ConfigureOAuth(IAppBuilder app)

        {

            OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()

            {

                AllowInsecureHttp = true,

                TokenEndpointPath = new PathString("/token"),

                AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(10),

                Provider = new SimpleAuthorizationServerProvider()



            };




            // Token Generation

            app.UseOAuthAuthorizationServer(OAuthServerOptions);

            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());



        }

    }

}


4) SimpleAuthorizationServerProvider 


using Microsoft.Owin.Security.OAuth;

using Newtonsoft.Json;

using SelfHosted.MicroService.Model;

using System;

using System.IO;

using System.Security.Claims;

using System.Threading.Tasks;


namespace SelfHosted.MicroService

{

    public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider

    {

        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)

        {

            context.Validated();

        }


        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)

        {

            //Your authentication logic here

            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });




        

            var user =

               UserService.GetUserByCredentials(context.UserName, context.Password);


            if (user != null)

            {


                var identity = new ClaimsIdentity(context.Options.AuthenticationType);

                identity.AddClaim(new Claim("sub", context.UserName));

                

                context.Validated(identity);



            }


            else

            {

                context.SetError("invalid_grant", "Invalid Username or password");

                return;




            }


        }


        public override Task TokenEndpointResponse(OAuthTokenEndpointResponseContext context)

        {

            //This can be written to a Database table too

            var dataFile = "c:\\temp\\accesstoken.txt";

            TokenStore data = new TokenStore() { token = context.AccessToken };

            File.WriteAllText(@dataFile, JsonConvert.SerializeObject(data));

            return base.TokenEndpointResponse(context);

            

        }


    }

}


5) Program.cs

using Microsoft.Owin.Hosting;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;


namespace SelfHosted.MicroService

{

    class Program

    {

        static void Main(string[] args)

        {

            string baseAddress = "http://127.0.0.1:8080/";


            // Start OWIN host 

            using (WebApp.Start(url: baseAddress))

            {

                Console.WriteLine("Service Listening at " + baseAddress);


                System.Threading.Thread.Sleep(-1);

            }

        }

    }

}


6) CustomAuthorizeAttribute.cs

using Newtonsoft.Json;

using SelfHosted.MicroService.Model;

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Net;

using System.Net.Http;

using System.Text;

using System.Threading.Tasks;

using System.Web.Http;


namespace SelfHosted.MicroService

{

    public class CustomAuthorizeAttribute : AuthorizeAttribute

    {

        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)

        {

            if (AuthorizeRequest(actionContext))

            {

                return;

            }

            HandleUnauthorizedRequest(actionContext);

        }



        protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)

        {

            //Code to handle unauthorized request

            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Forbidden);

            actionContext.Response.Headers.Add("AuthenticationStatus", "NotAuthorized");

         

            return;

        }


        private bool AuthorizeRequest(System.Web.Http.Controllers.HttpActionContext actionContext)

        {

            //This can be read from the database table too

            var token = actionContext.Request.Headers.Authorization.Parameter;

            var dataFile = "c:\\temp\\accesstoken.txt";

            var data = File.ReadAllText(@dataFile);

            var response = JsonConvert.DeserializeObject(data);

            if (response.token == token)

            {

                return true;

            }

            else

            {

                return false;

            }

           

        }

    }

}


7) MoviesController.cs

using System;

using System.Collections;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Web.Http;

using System.Web.Http.Cors;


namespace SelfHosted.MicroService

{

    public class Movie

    {

        public int Id { get; set; }

        public string Name { get; set; }

        public string Description { get; set; }

    }


    [EnableCors(origins: "*", headers: "*", methods: "*")]

    public class MoviesController : ApiController

    {

        Movie[] movies = new Movie[]

        {

            new Movie { Id = 1, Name = "Skorpion King", Description = "Movie about a king"},

            new Movie { Id = 2, Name = "Fast & Furious", Description = "Cars, Girls and fun"},

            new Movie { Id = 3, Name = "Inception", Description = "Mind boggling sensation"},

            new Movie { Id = 4, Name = "Spider Man", Description = "Will Rock your world"}

        };


        // GET api/Websites 

        [CustomAuthorizeAttribute]

        public IEnumerable Get()

        {

            return movies;

        }


        // GET api/Websites/5 

        [CustomAuthorizeAttribute]

        public Movie Get(int id)

        {

            try

            {

                return movies[id];

            }

            catch (Exception e)

            {

                return new Movie();

            }

        }       


        

    }


}

 

 

 

 

 

 

 

 

 

 



Tags: OWIN Microservice Selfhosted
Views: 874
Register for more exciting articles

Comments

Please login or register to post a comment.


Alexander Paulouski - 2018-05-16 10:45:45

Finally I found the reason. Newtonsoft.JSON in my project was 9.0.1 version and after I updated it to latest everything start working. Thank you man! Sorry for prev comment!

Alexander Paulouski - 2018-05-15 12:08:26

This not working. I always get 500 Internal Server Error when try to post Token.