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

.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来测试一下,先用原来的客户端模式,看,我们对客户端模式不会影响。 

.NET Core IdentityServer4实战 第Ⅳ章-集成密码登陆模式

现在我们再试一下密码登陆模式,首先获取token!

.NET Core IdentityServer4实战 第Ⅳ章-集成密码登陆模式

我们再去resourceapi中进行测试,ok,没问题!

.NET Core IdentityServer4实战 第Ⅳ章-集成密码登陆模式

现在我们创建一个客户端,用于硬编码的密码登陆。

 

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();
        }
    }
}

启动,结果如下:

 .NET Core IdentityServer4实战 第Ⅳ章-集成密码登陆模式

如果需要不做secret验证,在config中添加该参数:

new client()
                {
                    clientid = "pwdclient",
                    allowedgranttypes = granttypes.resourceownerpassword,
                    clientsecrets ={
                        new secret("secret".sha256())
                    },
                    requireclientsecret = false,
                    allowedscopes = {"api"}
                }

.NET Core IdentityServer4实战 第Ⅳ章-集成密码登陆模式

上图是基本的客户端登陆模式,而密码模式呢,则会在获取获取token中body上下文中加入username,password来加以复杂认证,但是用密码也不太可靠,抽时间我们说下授权码模式,说一说它们的区别与实现。