• 【Part 2】在ASP.NET Core中使用Ocelot构建API网关


    Introduction

    In my last article, Building API Gateway Using Ocelot In ASP.NET Core, I introduced how we can use Ocelot to build our API Gateway with the simplest demo. In this article, I will continue with the topic of Building API Gateway In ASP.NET Core and will show you something about authentication later.

    As all we know, API services are protected resources. We should secure them as far as we can!

    Normally, we will follow Security to handle the security of our projects. This repository contains the security and authorization middleware for ASP.NET Core.  It always makes things easier.

    Do we need to make a big change when we import API Gateway into our project? The answer is - No! We only make some imperceptible changes. It means that everything will be easy.

    Let's look at the below screenshot first.

    ASP.NET Core

    This screenshot shows that when we want to access our services, the authentication module of API Gateway should be visited at first. We need to visit the auth service to get the access token at first so that we can visit the protected services with the access_token.

    Maybe some of you will put the auth service alone,= which means that the clients should visit auth service to get access_token straight at first, then send a request to API Gateway to do something later. There is no doubt that thing will be all right but I recommend that you put your auth service together with other services.

    API Gateway is the entry of all our services; we just make auth service can be accessed by the clients without authentication.

    OK, let's begin to do it.

    I will use something the same as last article's demo here. I think it may help you to understand more quickly.

    Step 1

    Create four projects here.

    Project Name Project Type Description
    APIGateway ASP.NET Core Empty entry of this demo
    CustomersAPIServices ASP.NET Core Web API API Service that handles something about customers
    AuthServer ASP.NET Core Web API API Service that handles something about auth
    ClientApp Console App This is a Console App that simulates client.

    Make APIGateway and CustomerAPIServices project the same as in the last demo. You can find them in  APIGatewayBasicDemo.

    Step 2

    Finish AuthServer. This service is mainly for generating access_token for the request. What we need to do is add a method to handle this.

     
    1. [HttpGet]  
    2. public IActionResult Get(string name, string pwd)  
    3. {  
    4.     //just hard code here.  
    5.     if (name == "catcher" && pwd == "123")  
    6.     {  
    7.         var now = DateTime.UtcNow;  
    8.   
    9.         var claims = new Claim[]  
    10.         {  
    11.             new Claim(JwtRegisteredClaimNames.Sub, name),  
    12.             new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),  
    13.             new Claim(JwtRegisteredClaimNames.Iat, now.ToUniversalTime().ToString(), ClaimValueTypes.Integer64)  
    14.         };  
    15.   
    16.         var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_settings.Value.Secret));  
    17.         var tokenValidationParameters = new TokenValidationParameters  
    18.         {  
    19.             ValidateIssuerSigningKey = true,  
    20.             IssuerSigningKey = signingKey,  
    21.             ValidateIssuer = true,  
    22.             ValidIssuer = _settings.Value.Iss,  
    23.             ValidateAudience = true,  
    24.             ValidAudience = _settings.Value.Aud,  
    25.             ValidateLifetime = true,  
    26.             ClockSkew = TimeSpan.Zero,  
    27.             RequireExpirationTime = true,  
    28.   
    29.         };  
    30.   
    31.         var jwt = new JwtSecurityToken(  
    32.             issuer: _settings.Value.Iss,  
    33.             audience: _settings.Value.Aud,  
    34.             claims: claims,  
    35.             notBefore: now,  
    36.             expires: now.Add(TimeSpan.FromMinutes(2)),  
    37.             signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)  
    38.         );  
    39.         var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);  
    40.         var responseJson = new  
    41.         {  
    42.             access_token = encodedJwt,  
    43.             expires_in = (int)TimeSpan.FromMinutes(2).TotalSeconds  
    44.         };  
    45.   
    46.         return Json(responseJson);  
    47.     }  
    48.     else  
    49.     {  
    50.         return Json("");  
    51.     }  
    52. }  

    When verifying the users, I just use the hard code here because it's not an important thing to implement it in this article's topic!

    We have finished auth service. We can run it up now.

    ASP.NET Core

    Step 3

    Turn to CustomerAPIServices project, we should secure this service!!

    Edit the Startup class so that we can enable the authentication. I use JwtBearer here and I set the default authentication scheme to TestKey which I will mention in the next step.

     
    1. public void ConfigureServices(IServiceCollection services)  
    2. {  
    3.     var audienceConfig = Configuration.GetSection("Audience");  
    4.   
    5.     var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(audienceConfig["Secret"]));  
    6.     var tokenValidationParameters = new TokenValidationParameters  
    7.     {  
    8.         ValidateIssuerSigningKey = true,  
    9.         IssuerSigningKey = signingKey,  
    10.         ValidateIssuer = true,  
    11.         ValidIssuer = audienceConfig["Iss"],  
    12.         ValidateAudience = true,  
    13.         ValidAudience = audienceConfig["Aud"],  
    14.         ValidateLifetime = true,  
    15.         ClockSkew = TimeSpan.Zero,  
    16.         RequireExpirationTime = true,  
    17.     };  
    18.   
    19.     services.AddAuthentication()  
    20.             .AddJwtBearer("TestKey", x =>  
    21.              {  
    22.                  x.RequireHttpsMetadata = false;  
    23.                  x.TokenValidationParameters = tokenValidationParameters;  
    24.              });  
    25.   
    26.     services.AddMvc();  
    27. }  
    28. public void Configure(IApplicationBuilder app)  
    29. {              
    30.     app.UseAuthentication();  
    31.     app.UseMvc();  
    32. }  

    And then, we should use Authorize attribute in our method.

     
    1. [Authorize]  
    2. [HttpGet]  
    3. public IEnumerable<string> Get()  
    4. {  
    5.     return new string[] { "Catcher Wong", "James Li" };  
    6. }  

    Here, I just authorize of them because we need to show the not protected resources for comparison.

    Note

    This project is based on ASP.NET Core 2.0. If you are working with 1.x, you may find some difference here. You can follow Migrating Authentication and Identity to ASP.NET Core 2.0 to migrate.

    Run it up too!

    ASP.NET Core

    Step 4

    The most important step is now arriving. Configure the authentication in your API Gateway.

     
    1. public void ConfigureServices(IServiceCollection services)  
    2. {  
    3.     var audienceConfig = Configuration.GetSection("Audience");  
    4.   
    5.     var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(audienceConfig["Secret"]));  
    6.     var tokenValidationParameters = new TokenValidationParameters  
    7.     {  
    8.         ValidateIssuerSigningKey = true,  
    9.         IssuerSigningKey = signingKey,  
    10.         ValidateIssuer = true,  
    11.         ValidIssuer = audienceConfig["Iss"],  
    12.         ValidateAudience = true,  
    13.         ValidAudience = audienceConfig["Aud"],  
    14.         ValidateLifetime = true,  
    15.         ClockSkew = TimeSpan.Zero,  
    16.         RequireExpirationTime = true,  
    17.     };  
    18.   
    19.     services.AddAuthentication()  
    20.             .AddJwtBearer("TestKey", x =>  
    21.              {  
    22.                  x.RequireHttpsMetadata = false;  
    23.                  x.TokenValidationParameters = tokenValidationParameters;  
    24.              });  
    25.   
    26.     services.AddOcelot(Configuration);  
    27. }  

    You will find that most of the code is the same as Customer Service.

    When Ocelot runs, it will look at this ReRoutes AuthenticationOptions.AuthenticationProviderKey and check that there is an Authentication Provider registered with the given key. If there isn't, then Ocelot will not start up. If there is, then the ReRoute will use that provider when it executes.

    So, we also should modify the configuration.json file. We should add a new node named AuthenticationOptions and make the AuthenticationProviderKey the same as what we defined in the Startup class.

     
    1. {  
    2.     "DownstreamPathTemplate": "/api/customers",  
    3.     "DownstreamScheme": "http",  
    4.     "DownstreamHost": "localhost",  
    5.     "DownstreamPort": 9001,  
    6.     "UpstreamPathTemplate": "/customers",  
    7.     "UpstreamHttpMethod": [ "Get" ],  
    8.     "AuthenticationOptions": {  
    9.         "AuthenticationProviderKey": "TestKey",  
    10.         "AllowedScopes": []  
    11.     }  
    12. }  

    We also run it up now.

    ASP.NET Core

    Note
    If you meet the following error when you run this project, you need to check your code whether the AddJwtBearer method specifies the authentication scheme.

    Unhandled Exception: System.InvalidOperationException: Scheme already exists: Bearer

    Step 5

    We have done all preparation work here. Now, we should use our client app to simulate some request of the API Gateway.

    First of all, we need to add a method to get the assess_token.
     
    1. private static string GetJwt()  
    2. {  
    3.     HttpClient client = new HttpClient();  
    4.     client.BaseAddress = new Uri( "http://localhost:9000");  
    5.     client.DefaultRequestHeaders.Clear();  
    6.     var res2 = client.GetAsync("/api/auth?name=catcher&pwd=123").Result;  
    7.     dynamic jwt = JsonConvert.DeserializeObject(res2.Content.ReadAsStringAsync().Result);  
    8.     return jwt.access_token;  
    9. }  

    Then, write some code to visit the customer services via API Gateway.

     
    1. static void Main(string[] args)  
    2. {  
    3.     HttpClient client = new HttpClient();  
    4.       
    5.     client.DefaultRequestHeaders.Clear();  
    6.     client.BaseAddress = new Uri("http://localhost:9000");  
    7.       
    8.     // 1. without access_token will not access the service  
    9.     //    and return 401 .  
    10.     var resWithoutToken = client.GetAsync("/customers").Result;  
    11.       
    12.     //print something here   
    13.       
    14.     //2. with access_token will access the service  
    15.     //   and return result.  
    16.     client.DefaultRequestHeaders.Clear();  
    17.     var jwt = GetJwt();  
    18.       
    19.     client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwt}");  
    20.     var resWithToken = client.GetAsync("/customers").Result;  
    21.       
    22.     //print something here   
    23.       
    24.     //3. visit no auth service   
    25.     client.DefaultRequestHeaders.Clear();  
    26.     var res = client.GetAsync("/customers/1").Result;  
    27.       
    28.     //print something here   
    29.       
    30.     Console.Read();  
    31. }  

    When you run this project, you may find the results as follows.

    ASP.NET Core

    So far, we have done the job.

    Summary

    This article introduced how to configure authentication when you use Ocelot as your API Gateway. Hope this will help you.

    原文地址:https://www.c-sharpcorner.com/article/building-api-gateway-using-ocelot-in-asp-net-core-part-two/

  • 相关阅读:
    Golang调用windows下的dll动态库中的函数
    Golang 编译成 DLL 文件
    go 通过nginx代理后获取用户ip
    idea教程--Maven 骨架介绍
    idea教程--快速插入依赖
    Java开发名词解释
    Android Studio安装
    Java基础--Eclipse关联Java源码
    【排序基础】3、随机生成排序算法 测试用例
    【排序基础】2、使用模板(泛型)编写选择排序算法
  • 原文地址:https://www.cnblogs.com/jiangyihz/p/12703675.html
Copyright © 2020-2023  润新知