欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

04 .NET CORE 2.2 使用OCELOT -- identity认证授权

程序员文章站 2022-04-18 11:53:37
修改接口项目 在上次的项目基础上,分别修改两个api项目的startup.cs 修改配置文件 在接口的action中加入[Authorize]属性 加入Identity 新建webapi项目 。将authapi项目也加入到consul中。所以要新建health控制器,新建一个授权控制器,修改star ......

修改接口项目

  在上次的项目基础上,分别修改两个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

 

参考链接:

 

修改网关项目

配置文件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("\nbegin auth....");
            var jwt = getjwt();
            console.writeline("end auth....");
            console.writeline($"\ntoken={jwt}");

            client.defaultrequestheaders.add("authorization", $"bearer {jwt}");
            var reswithtoken = client.getasync("/api/counter/count").result;

            console.writeline($"\nsend 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("\nno 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;
        }
    }

04 .NET CORE 2.2 使用OCELOT -- identity认证授权

 

 postman测试下。

先获取access_token

04 .NET CORE 2.2 使用OCELOT -- identity认证授权

 

 将access_token放到header中

04 .NET CORE 2.2 使用OCELOT -- identity认证授权

 

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

04 .NET CORE 2.2 使用OCELOT -- identity认证授权