Sunday, 11 October 2020

                                                    Using Ocelot Gateway 


here we will create ocelot gateway and 

1) we will call the backend services through gate way

2)we will use aggregation in gateway to call two service 

3)we will apply the authentication on each service using ocelot gate way means we will create naked ms service and will the authentication on gateway label


First Service -User Service

Step 1  first create the ms user micro service as below structure



in user controller paste the below code,

using System;

using System.Collections.Generic;

using System.IdentityModel.Tokens.Jwt;

using System.Linq;

using System.Security.Claims;

using System.Text;

using System.Threading.Tasks;

using Microsoft.AspNetCore.Authorization;

using Microsoft.AspNetCore.Mvc;

using Microsoft.IdentityModel.Tokens;


namespace user_ms.Controllers

{

    [Route("api/user")]

    [ApiController]

    public class UserController : ControllerBase

    {

        // GET api/values

        [HttpGet("getUser")]

        public ActionResult<IEnumerable<User>> Get()

        {

            User user = GetData();

            return Ok(user);

        }

        [AllowAnonymous]

        [HttpGet("login")]

        public IActionResult Get(string name, string password)

        {

            //just hard code here.  

            if (name == "mukesh" && password == "123")

            {

                var now = DateTime.UtcNow;


                var claims = new Claim[]

                {

            new Claim(JwtRegisteredClaimNames.Sub, name),

            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),

            new Claim(JwtRegisteredClaimNames.Iat, now.ToUniversalTime().ToString(), ClaimValueTypes.Integer64)

                };

                var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("hello god ,we are depend on you so please do help"));

                var tokenValidationParameters = new TokenValidationParameters

                {

                    ValidateIssuerSigningKey = true,

                    IssuerSigningKey = signingKey,

                    ValidateIssuer = true,

                    ValidIssuer = "mukesh",

                    ValidateAudience = true,

                    ValidAudience = "enduser",

                    ValidateLifetime = true,

                    ClockSkew = TimeSpan.Zero,

                    RequireExpirationTime = true,

                };

                var jwt = new JwtSecurityToken(

                    issuer: "mukesh",

                    audience: "enduser",

                    claims: claims,

                    notBefore: now,

                    expires: now.Add(TimeSpan.FromMinutes(20)),

                    signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)

                );

                var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

                var responseJson = new

                {

                    access_token = encodedJwt,

                    expires_in = (int)TimeSpan.FromMinutes(2000).TotalSeconds

                };

                return Ok(responseJson);

            }

            else

            {

                return Ok("");

            }

        }

        private User GetData()

        {

            User user = new User

            {

                Id = 1,

                Name = "Mukesh trivedi",

                Email = "mukeshtrvd105@gmail.com",

                Mobile="8845345223"

            };

            return user;

        }

        public class User

        {

            public int Id { get; set; }

            public string Name { get; set; }

            public string Email { get; set; }

            public string Mobile { get; set; }

        }

    }

}


when we run the user micro service it will give the result as below,



Second Service 

Step 2 similarly we will create the second product service and  use in the gateway for concurrent calling product structure is like below

now under  the product controller copy the below code 

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

namespace product_ms.Controllers
{
    [Route("api/product")]
    [ApiController]
    public class ProductController : ControllerBase
    {
        // GET api/values
        [HttpGet("getProduct")]
        public ActionResult<IEnumerable<string>> Get()
        {
            Product product = GetProductData();
            return Ok(product);
        }


        private Product GetProductData()
        {
            Product product = new Product
            {
                Id = 1,
                Name = "Samsung Galaxy",
                Price = "RS 20000"
            };
            return product;
        }

        public class Product
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Price { get; set; }
        }

    }
}
 
when the product ms service will call it look like below,

Gateway 

now come to the ocelot gate way service , now create a web api and then install the ocelot gate way from nuget package 

Step 1 down load the ocelot pakage as below

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Folder Include="wwwroot\" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
    <PackageReference Include="Ocelot" Version="13.5.1" />
  </ItemGroup>

</Project>

Step 2 ,now write the routing in ocelot json file  

Ocelot json file where we set the routing for both the micro service

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/user/getUser",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": "44307"
        }
      ],
      "UpstreamPathTemplate": "/getUser",
      "Key": "User",
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "TestKey",
        "AllowedScopes": []
      }
    },
    {
      "DownstreamPathTemplate": "/api/product/getProduct",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": "44300"
        }
      ],
      "UpstreamPathTemplate": "/getProduct",
      "Key": "Product"
    }
  ],
  "Aggregates": [
    {
      "ReRouteKeys": [
        "User",
        "Product"
      ],
      "UpstreamPathTemplate": "/UserAndProduct"
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "https://localhost:44338/"
  }
}

Step 3 Now configure the json file in program file.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace web_api
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
           WebHost.CreateDefaultBuilder(args)
           .ConfigureAppConfiguration((host, config) =>
           {
               config.AddJsonFile("ocelot.json");
           })
               .UseStartup<Startup>();
    }
}

Step 4 ,now registered the dependency in ioc container and request/response pipeline

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;

namespace web_api
{
    public class Startup
    {
        public IConfiguration Configuration { get; }
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            //authentication  logic

            string textKey = "hello god ,we are depend on you so please do help";

            var key = Encoding.ASCII.GetBytes(textKey);

            var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(textKey));
            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = signingKey,
                ValidateIssuer = true,
                ValidIssuer = "mukesh",
                ValidateAudience = true,
                ValidAudience = "enduser",
                ValidateLifetime = true,
                ClockSkew = TimeSpan.Zero,
                RequireExpirationTime = true,
            };


            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
              .AddJwtBearer("TestKey", x =>
              {
                  x.RequireHttpsMetadata = false;
                  x.TokenValidationParameters = tokenValidationParameters;
              });

            services.AddOcelot(Configuration);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public async void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            await app.UseOcelot();

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }
    }
}


now we using post man for calling two service concurrent result at one go.
we will pass the token during the service call


requested url:https://localhost:44338/UserAndProduct


Passing Token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtdWtlc2giLCJqdGkiOiIxNWU2NDNlZS1hZjJkLTQ1MDEtODc2NS1hN2RmOGQ2YjZkNTAiLCJpYXQiOiIxMS0xMC0yMDIwIDE2OjIwOjAxIiwibmJmIjoxNjAyNDMzMjAxLCJleHAiOjE2MDI0MzQ0MDEsImlzcyI6Im11a2VzaCIsImF1ZCI6ImVuZHVzZXIifQ.oVfWK5qRDGYbyY5c6N6ol1BHT9hVWqcPn9fkjZIyfGg


Result

{
    "User": {
        "id"1,
        "name""Mukesh trivedi",
        "email""mukeshtrvd105@gmail.com",
        "mobile""8845345223"
    },
    "Product": {
        "id"1,
        "name""Samsung Galaxy",
        "price""RS 20000"
    }
}

now calling the single service by requesting the gate way url such as

Requested url -----> https://localhost:44338/getUser


Passing token same as above


eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtdWtlc2giLCJqdGkiOiIxNWU2NDNlZS1hZjJkLTQ1MDEtODc2NS1hN2RmOGQ2YjZkNTAiLCJpYXQiOiIxMS0xMC0yMDIwIDE2OjIwOjAxIiwibmJmIjoxNjAyNDMzMjAxLCJleHAiOjE2MDI0MzQ0MDEsImlzcyI6Im11a2VzaCIsImF1ZCI6ImVuZHVzZXIifQ.oVfWK5qRDGYbyY5c6N6ol1BHT9hVWqcPn9fkjZIyfGg

Result

{
    "id"1,
    "name""Mukesh trivedi",
    "email""mukeshtrvd105@gmail.com",
    "mobile""8845345223"
}


































No comments:

Post a Comment