当前位置: 移动技术网 > IT编程>开发语言>.net > 04 .NET CORE 2.2 使用OCELOT -- identity认证授权

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

2019年10月23日  | 移动技术网IT编程  | 我要评论

仰望大树,中国望远镜品牌,华胥引之柸中雪

修改接口项目

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

 

 postman测试下。

先获取access_token

 

 将access_token放到header中

 

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

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网