zoukankan      html  css  js  c++  java
  • 04 .NET CORE 2.2 使用OCELOT -- identity认证授权

    修改接口项目

      在上次的项目基础上,分别修改两个api项目的startup.cs

      

     public void ConfigureServices(IServiceCollection services)
            {
                var audienceConfig = Configuration.GetSection("Audience");
                var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(audienceConfig["Secret"]));
                var tokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = signingKey,
                    ValidateIssuer = true,
                    ValidIssuer = audienceConfig["Iss"],
                    ValidateAudience = true,
                    ValidAudience = audienceConfig["Aud"],
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero,
                    RequireExpirationTime = true,
                };
                services.AddAuthentication(o =>
                    {
                        o.DefaultAuthenticateScheme = "TestKey";
                    })
                    .AddJwtBearer("TestKey", x =>
                    {
                        x.RequireHttpsMetadata = false;
                        x.TokenValidationParameters = tokenValidationParameters;
                    });
    
                //services.AddConsulConfig(Configuration);
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            }

      修改配置文件

      

    {
      "Logging": {
        "LogLevel": {
          "Default": "Warning"
        }
      },
      "AllowedHosts": "*",
      //"Consul": {
      //  "Host": "http://192.168.2.29:8500"
      //},
    
      "Service": {
        "Name": "ApiService",
        "IP": "192.168.2.16",
        "Port": "9001"
      },
      "Consul": {
        "IP": "192.168.2.29",
        "Port": "8500"
      },
      "Audience": {
        "Secret": "Y2F0Y2hlciUyMHdvbmclMjBsb3ZlJTIwLm5ldA==",
        "Iss": "http://www.c-sharpcorner.com/members/catcher-wong",
        "Aud": "Catcher Wong"
      }
    }

      在接口的action中加入[Authorize]属性

      

    [Authorize]
            [HttpGet]
            public string Count()
            {
                return $"Count {++_count} from ApiServices1";
            }

    加入Identity

      新建webapi项目 。将authapi项目也加入到consul中。所以要新建health控制器,新建一个授权控制器,修改startup.cs

      

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    
    namespace Test.WebApi.AuthServer.Controllers
    {
        [Produces("application/json")]
        [Route("api/[controller]")]
        [ApiController]
        public class HealthController : ControllerBase
        {
    
            [HttpGet]
            public IActionResult Get() => Ok("ok");
        }
    }
    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.Http;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Options;
    using Microsoft.IdentityModel.Tokens;
    
    namespace Test.WebApi.AuthServer.Controllers
    {
        [Route("authapi/[controller]")]
        [ApiController]
        public class AuthController : ControllerBase
        {
            private IOptions<Audience> _settings;
    
            public AuthController(IOptions<Audience> settings)
            {
                this._settings = settings;
            }
    
            [HttpGet]
            public ActionResult Get(string name, string pwd)
            {
                //just hard code here.  
                if (name == "catcher" && pwd == "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(_settings.Value.Secret));
                    var tokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = signingKey,
                        ValidateIssuer = true,
                        ValidIssuer = _settings.Value.Iss,
                        ValidateAudience = true,
                        ValidAudience = _settings.Value.Aud,
                        ValidateLifetime = true,
                        ClockSkew = TimeSpan.Zero,
                        RequireExpirationTime = true,
    
                    };
    
                    var jwt = new JwtSecurityToken(
                        issuer: _settings.Value.Iss,
                        audience: _settings.Value.Aud,
                        claims: claims,
                        notBefore: now,
                        expires: now.Add(TimeSpan.FromMinutes(2)),
                        signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
                    );
                    var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
                    var responseJson = new
                    {
                        access_token = encodedJwt,
                        expires_in = (int)TimeSpan.FromMinutes(2).TotalSeconds
                    };
    
                    
                    return new JsonResult(responseJson);
                }
                else
                {
                    return new JsonResult("");
                }
            }
        }
    
        public class Audience
        {
            public string Secret { get; set; }
            public string Iss { get; set; }
            public string Aud { get; set; }
        }
    }

    修改 startup.cs

      // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
                services.AddOptions();
                services.Configure<Controllers.Audience>(Configuration.GetSection("Audience"));
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                    app.UseHsts();
                }
    
                ConsulService consulService = new ConsulService()
                {
                    IP = Configuration["Consul:IP"],
                    Port = Convert.ToInt32(Configuration["Consul:Port"])
                };
                HealthService healthService = new HealthService()
                {
                    IP = Configuration["Service:IP"],
                    Port = Convert.ToInt32(Configuration["Service:Port"]),
                    Name = Configuration["Service:Name"],
                };
                app.RegisterConsul(lifetime, healthService, consulService);
    
                app.UseHttpsRedirection();
                app.UseMvc();
            }

    配置文件

    {
      "Logging": {
        "LogLevel": {
          "Default": "Warning"
        }
      },
      "AllowedHosts": "*",
    
      "Service": {
        "Name": "AuthService",
        "IP": "192.168.2.16",
        "Port": "9003"
      },
      "Consul": {
        "IP": "192.168.2.29",
        "Port": "8500"
      },
      "Audience": {
        "Secret": "Y2F0Y2hlciUyMHdvbmclMjBsb3ZlJTIwLm5ldA==",
        "Iss": "http://www.c-sharpcorner.com/members/catcher-wong",
        "Aud": "Catcher Wong"
      }
    }

    发布后,部署到IIS中,端口9003

    参考链接:

    https://www.cnblogs.com/xlxr45/p/11321134.html

    修改网关项目

    配置文件configuration.json

    {
      "ReRoutes": [
        {
          "UseServiceDiscovery": true,
          "DownstreamPathTemplate": "/api/{url}",
          "DownstreamScheme": "http",
          "ServiceName": "ApiService",
          "LoadBalancerOptions": {
            "Type": "RoundRobin"
          },
          "UpstreamPathTemplate": "/api/{url}",
          "UpstreamHttpMethod": [ "Get" ],
          "ReRoutesCaseSensitive": false
        },
        {
          "UseServiceDiscovery": true,
          "DownstreamPathTemplate": "/authapi/{url}",
          "DownstreamScheme": "http",
          "ServiceName": "AuthService",
          "LoadBalancerOptions": {
            "Type": "RoundRobin"
          },
          "UpstreamPathTemplate": "/authapi/{url}",
          "UpstreamHttpMethod": [ "Get" ],
          "ReRoutesCaseSensitive": false
        }
      ],
      "GlobalConfiguration": {
        "ServiceDiscoveryProvider": {
          "Host": "192.168.2.29",
          "Port": 8500,
          "Type": "PollConsul",
          "PollingInterval": 100
        }
      }
    }

    运行效果

    新建一个cmd项目,测试下

    class Program
        {
            static void Main(string[] args)
            {
                HttpClient client = new HttpClient();
    
                client.DefaultRequestHeaders.Clear();
                client.BaseAddress = new Uri("http://localhost:9000");
    
                // 1. without access_token will not access the service
                //    and return 401 .
                var resWithoutToken = client.GetAsync("/api/Counter/Count").Result;
    
                Console.WriteLine($"Sending Request to /api/Counter/Count , without token.");
                Console.WriteLine($"Result : {resWithoutToken.StatusCode}");
    
                //2. with access_token will access the service
                //   and return result.
                client.DefaultRequestHeaders.Clear();
                Console.WriteLine("
    Begin Auth....");
                var jwt = GetJwt();
                Console.WriteLine("End Auth....");
                Console.WriteLine($"
    Token={jwt}");
    
                client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwt}");
                var resWithToken = client.GetAsync("/api/Counter/Count").Result;
    
                Console.WriteLine($"
    Send Request to /api/Counter/Count , with token.");
                Console.WriteLine($"Result : {resWithToken.StatusCode}");
                Console.WriteLine(resWithToken.Content.ReadAsStringAsync().Result);
    
                //3. visit no auth service 
                Console.WriteLine("
    No Auth Service Here ");
                client.DefaultRequestHeaders.Clear();
                var res = client.GetAsync("/api/Counter/Count").Result;
    
                Console.WriteLine($"Send Request to /api/Counter/Count");
                Console.WriteLine($"Result : {res.StatusCode}");
                Console.WriteLine(res.Content.ReadAsStringAsync().Result);
    
                Console.Read();
            }
    
    
            private static string GetJwt()
            {
                HttpClient client = new HttpClient();
    
                client.BaseAddress = new Uri( "http://localhost:9000");
                client.DefaultRequestHeaders.Clear();
    
                var res2 = client.GetAsync("/authapi/auth?name=catcher&pwd=123").Result;
    
                dynamic jwt = JsonConvert.DeserializeObject(res2.Content.ReadAsStringAsync().Result);
    
                return jwt.access_token;
            }
        }

     postman测试下。

    先获取access_token

     将access_token放到header中

     如果不加入header中,则会报500错误

  • 相关阅读:
    显示非模式窗口和模式窗口
    delphi 版本号
    数字证书和签名
    DLL知道自己的位置
    拖动处理
    驱动配置相关
    python sturct模块操作C数据
    Lambda学习笔记
    【转】update select
    [转]视频格式分类
  • 原文地址:https://www.cnblogs.com/zhanglinfeng715/p/11724255.html
Copyright © 2011-2022 走看看