.NET Core IdentityServer4实战 第Ⅳ章-集成密码登陆模式
程序员文章站
2022-08-29 19:11:15
回顾下ClientCredentials模式,在ReSourceApi中定义了我们公开服务,第三方网站想要去访问ReSourceApi则需要在身份验证服务中获取toekn,根据token的内容,硬编码去访问公开服务(ResApi),这个还是非常简单的,但!仔细思考下,我们在客户端当中设置了对应的身份 ......
回顾下clientcredentials模式,在resourceapi中定义了我们公开服务,第三方网站想要去访问resourceapi则需要在身份验证服务中获取toekn,根据token的内容,硬编码去访问公开服务(resapi),这个还是非常简单的,但!仔细思考下,我们在客户端当中设置了对应的身份验证服务中心的地址,那么也就是可以有多对多的情况,当然我们的第三方网站无需多言去关注这些。
public void configureservices(iservicecollection services) { services.addauthentication("bearer") .addidentityserverauthentication(options => { options.authority = "https://localhost:5000"; options.requirehttpsmetadata = false; options.apiname = "api"; }); services.addmvc().setcompatibilityversion(compatibilityversion.version_2_1); }
下面咱说下密码模式,这个模式安全级别比clientcredentials高得多,第一步我们需要修改一下我们的config文件.然后第二步就是添加我们的testuser对象.
public static ienumerable<client> getclients() { return new list<client> { new client() { clientid = "client", allowedgranttypes = granttypes.clientcredentials,//客户端登陆模式 clientsecrets ={ new secret("secret".sha256()) }, allowedscopes = {"api"} }, new client() { clientid = "pwdclient", allowedgranttypes = granttypes.resourceownerpassword,//密码授权登陆模式 clientsecrets ={ new secret("secret".sha256()) }, allowedscopes = {"api"} } }; }
第二部testuser对象由identityserver4.test 给我们提供了,我们引入就ok,然后添加该方法用于测试.
public static list<testuser> gettestusers() { return new list<testuser> { new testuser() { subjectid = "1", username = "zara", password = "112233" } }; }
当然,你还需要将测试数据注入到core中,我们需要修改下原来的stratup.cs类.
services.addidentityserver()//将idserer di到.netcore .adddevelopersigningcredential() .addinmemoryapiresources(config.getresource())//添加公开服务 .addinmemoryclients(config.getclients())//客户端模拟数据 .addtestusers(config.gettestusers());//用户测试数据
下面我们用postman来测试一下,先用原来的客户端模式,看,我们对客户端模式不会影响。
现在我们再试一下密码登陆模式,首先获取token!
我们再去resourceapi中进行测试,ok,没问题!
现在我们创建一个客户端,用于硬编码的密码登陆。
using identitymodel.client; using system; using system.net.http; namespace thirdpartysolucation { public static class passwordlogin { public static void login() { var diso = discoveryclient.getasync("https://localhost:5000").result; if (diso.iserror) { console.writeline(diso.error); } var tokenclient = new tokenclient(diso.tokenendpoint, "pwdclient", "secret"); var tokenresponse = tokenclient.requestresourceownerpasswordasync("zara","112233").result; if (tokenresponse.iserror) { console.writeline(tokenresponse.error); } else { console.writeline(tokenresponse.json); } httpclient httpclient = new httpclient(); httpclient.setbearertoken(tokenresponse.accesstoken); var response = httpclient.getasync("http://localhost:5001/api/values").result; if (response.issuccessstatuscode) { console.writeline(response.content.readasstringasync().result); } console.writeline(); } } }
启动,结果如下:
如果需要不做secret验证,在config中添加该参数:
new client() { clientid = "pwdclient", allowedgranttypes = granttypes.resourceownerpassword, clientsecrets ={ new secret("secret".sha256()) }, requireclientsecret = false, allowedscopes = {"api"} }
上图是基本的客户端登陆模式,而密码模式呢,则会在获取获取token中body上下文中加入username,password来加以复杂认证,但是用密码也不太可靠,抽时间我们说下授权码模式,说一说它们的区别与实现。
上一篇: 吃泡面会胖吗,答案是肯定的