vue 使用的是d2admin:
github地址:https://github.com/fengddd/permissionadmin.git
net core的环境:webapi 使用的是:net core sdk2.1 identityserver和ocelot:net core sdk2.2
github地址:https://github.com/fengddd/identityserverocelotdemo.git
我也是在初学阶段,所以有些地方可能描述的不是很清楚,可以下载源码查看,也可能大家一起交流,学习
public static ienumerable<identityresource> getidentityresources() { return new identityresource[] { new identityresources.openid(), new identityresources.profile(), new identityresource("delimitclaim","delimitclaim",new list<string>(){ "role", "name"}), //在claims添加role 和 name信息 }; } public static ienumerable<apiresource> getapiresource() { return new list<apiresource> { new apiresource("identityserverapi", "identityserverapi"), }; } public static ienumerable<client> getclients() { new client { clientid = "js", //客户端id clientname = "javascript client", //客户端名称 allowedgranttypes = granttypes.code, //授权模式 //allowedgranttypes = granttypes.implicit, requirepkce = true, requireclientsecret = false, requireconsent = false, //禁用 consent 页面确认 allowaccesstokensviabrowser = true, alwaysincludeuserclaimsinidtoken = true, redirecturis = { "http://localhost:8080/#/identityservercallback", //登陆后回调页面 "http://localhost:8080/#/identityserverrefreshtoken" //刷新token的页面 }, postlogoutredirecturis = { "http://localhost:8080/#/identityserverclient" },//注销退出后跳转的页面(登录页) allowedcorsorigins = { "http://localhost:8080" }, //跨域 accesstokenlifetime = 60, //accesstoken 的有效时间 allowedscopes = { identityserverconstants.standardscopes.openid, identityserverconstants.standardscopes.profile, "identityserverapi", //授权的scopes "delimitclaim" //claims 信息 }, allowofflineaccess = true, } }
有时我们需要自定义验证以及自定义一些claim的信息,所以需要实现 iprofileservice 接口
public virtual task getprofiledataasync(profiledatarequestcontext context) { context.logprofilerequest(logger); //判断是否有请求claim信息 if (context.requestedclaimtypes.any()) { var userclaims = new list<claim> { new claim("demo1", "测试1"), new claim("demo2", "测试2"), }; list<testuser> userlist = new list<testuser>() { new testuser(){subjectid = "cfac01a9-ba15-4678-bccb-cc22d7896362",password = "123456",username="李锋",claims = userclaims}, new testuser(){subjectid = "cfac01a9-ba15-4678-bccb-cc22d7855555",password = "123456",username="张三"}, }; testuserstore userstore = new testuserstore(userlist); //根据用户唯一标识查找用户信息 var user = userstore.findbysubjectid(context.subject.getsubjectid()); if (user != null) { //调用此方法以后内部会进行过滤,只将用户请求的claim加入到 context.issuedclaims 集合中 这样我们的请求方便能正常获取到所需claim context.addrequestedclaims(user.claims); } //context.issuedclaims=userclaims; } context.logissuedclaims(logger); return task.completedtask; } /// <summary> /// 验证用户是否有效 例如:token创建或者验证 /// </summary> /// <param name="context">the context.</param> /// <returns></returns> public virtual task isactiveasync(isactivecontext context) { logger.logdebug("isactive called from: {caller}", context.caller); var userclaims = new list<claim> { new claim("demo1", "测试1"), new claim("demo2", "测试2"), }; list<testuser> userlist = new list<testuser>() { new testuser(){subjectid = "cfac01a9-ba15-4678-bccb-cc22d7896362",password = "123456",username="李锋",claims = userclaims}, new testuser(){subjectid = "cfac01a9-ba15-4678-bccb-cc22d7855555",password = "123456",username="张三"}, }; testuserstore userstore = new testuserstore(userlist); var user = userstore.findbysubjectid(context.subject.getsubjectid()); context.isactive = user?.isactive == true; return task.completedtask; }
其中关于claims的地方这里做测试所以直接实例出来的数据,这里可以通过读取数据库进行验证,以及添加claims的信息
在startup 的configureservices 注入identityserver信息 ,configure下注册useidentityserver中间件
services.addidentityserver() .adddevelopersigningcredential() .addinmemoryidentityresources(identityconfig.getidentityresources()) .addinmemoryapiresources(identityconfig.getapiresource()) .addinmemoryclients(identityconfig.getclients()) //.addtestusers(identityconfig.getusers().tolist()) .addprofileservice<identityprofileservice>(); //使用的是code模式,使用自定义claims信息 //.addresourceownervalidator<identityresourceownerpasswordvalidator>(); app.useidentityserver();
然后找到quickstart中的登录方法,这里修改为从数据库读取验证用户信息
"reroutes": [ { "downstreampathtemplate": "/api/{url}", "downstreamscheme": "http", "downstreamhostandports": [ { "host": "localhost", "port": 44375 } ], "upstreampathtemplate": "/api/{url}", "upstreamhttpmethod": [ "get", "post" ], "priority": 2, "authenticationoptions": { "authenticationproviderkey": "identityserverkey", "allowscopes": [ "identityserverapi", "delimitclaim" ] }, "ratelimitoptions": { "clientwhitelist": [ //白名单 ], "enableratelimiting": true, //启用限流 "period": "1m", "periodtimespan": 30, "limit": 5 }, "qosoptions": { "exceptionsallowedbeforebreaking": 3, "durationofbreak": 3000, "timeoutvalue": 5000 }
]
}
services.addauthentication() .addidentityserverauthentication("identityserverkey", options => { options.authority = "http://localhost:17491"; options.apiname = "identityserverapi"; options.supportedtokens = identityserver4.accesstokenvalidation.supportedtokens.both; options.requirehttpsmetadata = false; }); services.addocelot() .addconsul() .addpolly(); //配置跨域处理 services.addcors(options => { options.addpolicy("any", builder => { builder.allowanyorigin() //允许任何来源的主机访问 .allowanymethod() .allowanyheader() .allowcredentials();//指定处理cookie }); }); //配置cors app.usecors("any"); app.useauthentication();
program中添加
public static iwebhostbuilder createwebhostbuilder(string[] args) { return webhost.createdefaultbuilder(args) .configureappconfiguration((hostingcontext, config) => { config .setbasepath(hostingcontext.hostingenvironment.contentrootpath) .addocelot(hostingcontext.hostingenvironment) //ocelot合并配置文件,不能出现同样的一个端口,多个路由 .addenvironmentvariables(); }) .usestartup<startup>(); }
edison zhou: identityserver4和ocelot
晓晨master: identityserver4
solenovex : identityserver4 bibi上还有identityserver4视频喔
灭蒙鸟: 入门教程:js认证和webapi
.net框架学苑: ocelot 一系列教程