CSharp

ASP NetCore Microservice

AuthApi

Dockerfile

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /
COPY AuthApi/*.csproj ./AuthApi/
RUN dotnet restore AuthApi/AuthApi.csproj
COPY . .
RUN dotnet publish AuthApi/AuthApi.csproj -c Release -o /app/publish /p:UseAppHost=false

FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish ./
EXPOSE 80
ENTRYPOINT ["dotnet", "AuthApi.dll"]

Jwt

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

Generate Token

public static string GenerateToken(IEnumerable<Claim> claims, string secretKey, string? issuer, string? audience){
    JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
    SymmetricSecurityKey securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));
    SigningCredentials credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
    JwtSecurityToken token = new JwtSecurityToken(
        issuer: issuer,
        audience: audience,
        claims: claims,
        signingCredentials: credentials,
        expires: DateTime.Now.AddDays(30)
    );
    return handler.WriteToken(token);
}

appsettings

{
  "Jwt": {
    "SecretKey": "17283asljkdasdjfaksjdlkjuioweralskfdjfjlasmzvnzxncv"
  }
}

StoreApi

Dockerfile

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /
COPY StoreApi/*.csproj ./StoreApi/
RUN dotnet restore StoreApi/StoreApi.csproj
COPY . .
RUN dotnet publish StoreApi/StoreApi.csproj -c Release -o /app/publish /p:UseAppHost=false

FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish ./
EXPOSE 80
ENTRYPOINT ["dotnet", "StoreApi.dll"]

ShippingApi

Dockerfile

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /
COPY ShippingApi/*.csproj ./ShippingApi/
RUN dotnet restore ShippingApi/ShippingApi.csproj
COPY . .
RUN dotnet publish ShippingApi/ShippingApi.csproj -c Release -o /app/publish /p:UseAppHost=false

FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish ./
EXPOSE 80
ENTRYPOINT ["dotnet", "ShippingApi.dll"]

ApiGateway

Package

dotnet add package Ocelot
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

ocelot.json

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [{ "Host": "storeapi", "Port": 5000 }],
      "UpstreamPathTemplate": "/store",
      "UpstreamHttpMethod": ["GET"],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "Bearer",
        "AllowedScopes": []
      }
    },
    {
      "DownstreamPathTemplate": "/",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [{ "Host": "shippingapi", "Port": 5000 }],
      "UpstreamPathTemplate": "/shipping",
      "UpstreamHttpMethod": ["GET"],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "Bearer",
        "AllowedScopes": []
      }
    }
  ],
  "GlobalConfiguration": { "BaseUrl": "http://localhost:5000" }
}

Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);

var secretKey = builder.Configuration["Jwt:SecretKey"] ?? throw new Exception("Not found Jwt:Secret");

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer("Bearer", options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = false,
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidAudience = builder.Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey))
        };
    });

builder.Services.AddOcelot();
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();

Dockerfile

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /
COPY ApiGateway/*.csproj ./ApiGateway/
RUN dotnet restore ApiGateway/ApiGateway.csproj
COPY . .
RUN dotnet publish ApiGateway/ApiGateway.csproj -c Release -o /app/publish /p:UseAppHost=false

FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish ./
EXPOSE 80
ENTRYPOINT ["dotnet", "ApiGateway.dll"]

Microservice

docker-compose.yml

version: '3.8'
services:
  authapi:
    #build: ./AuthApi
    build:
      context: ./
      dockerfile: AuthApi/Dockerfile
    # environment:
    #   - Jwt__SecretKey=17283asljkdasdjfaksjdlkjuioweralskfdjfjlasmzvnzxncv
    #   - Jwt__Issuer=ceb.net.vn
    #   - Jwt__Audience=ceb.net.vn
    # ports:
    #   - "5001:5000"
    ports: 
      - "5001:80"
    environment:
      - ASPNETCORE_URLS=http://+:80
      - Jwt__SecretKey=17283asljkdasdjfaksjdlkjuioweralskfdjfjlasmzvnzxncv
      - Jwt__Issuer=ceb.net.vn
      - Jwt__Audience=ceb.net.vn
  storeapi:
    #build: ./StoreApi
    build: 
      context: ./
      dockerfile: StoreApi/Dockerfile
    # ports:
    #   - "5002:80"
    ports: 
      - "5002:80"
    environment:
      - ASPNETCORE_URLS=http://+:80

  shippingapi:
    #build: ./ShippingApi
    build:
      context: ./
      dockerfile: ShippingApi/Dockerfile
    # ports:
    #   - "5003:5000"
    ports: 
      - "5003:80"
    environment:
      - ASPNETCORE_URLS=http://+:80

  apigateway:
    #build: ./ApiGateway
    build: 
      context: ./
      dockerfile: ApiGateway/Dockerfile
    #environment: 
    #ports:
    #  - "5000:5000"
    ports: 
      - "5000:80"
    environment:
      - ASPNETCORE_URLS=http://+:80
      - Jwt__SecretKey=17283asljkdasdjfaksjdlkjuioweralskfdjfjlasmzvnzxncv
      - Jwt__Issuer=ceb.net.vn
      - Jwt__Audience=ceb.net.vn
    depends_on:
      - storeapi
      - shippingapi
    

Run

docker-compose up --build