04 .NET CORE 2.2 使用OCELOT -- identity认证授权
程序员文章站
2024-01-22 18:21:52
修改接口项目 在上次的项目基础上,分别修改两个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; } }
postman测试下。
先获取access_token
将access_token放到header中
如果不加入header中,则会报500错误
推荐阅读
-
04 .NET CORE 2.2 使用OCELOT -- identity认证授权
-
05 .NET CORE 2.2 使用OCELOT -- NLog
-
【翻译】使用WebApi和Asp.Net Core Identity 认证 Blazor WebAssembly(Blazor客户端应用)
-
03 .NET CORE 2.2 使用OCELOT -- Docker中的Consul
-
01 .NET CORE 2.2 使用OCELOT -- 简单使用
-
02 .NET CORE 2.2 使用OCELOT -- 路由
-
【.NET Core项目实战-统一认证平台】第九章 授权篇-使用Dapper持久化IdentityServer4
-
ASP.NET Core使用JWT认证授权的方法
-
asp.net core 使用identityServer4的密码模式来进行身份认证(2) 认证授权原理
-
ASP.NET Core学习之使用JWT认证授权详解