当前位置: 移动技术网 > IT编程>开发语言>.net > asp.net core系列 55 IS4使用Identity密码保护API

asp.net core系列 55 IS4使用Identity密码保护API

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

我和同学母亲(完),滨海二手房网,12岁哥哥和9岁妹妹

一.概述

  oauth 2.0资源(web api)所有者密码授权,允许客户端(client项目)向令牌服务(identityserver项目)发送用户名和密码,并获取代表该用户的访问令牌。在官方文档中讲到:规范通常建议不要使用“资源所有者密码授权”。当用户进行身份验证并请求访问令牌时,使用一个交互式openid connect流程通常要好得多(下篇再了解)。

  本篇介绍“资源所有者密码授权”是因为这种授权允许我们快速启动identityserver。开源地址:github 

  下面示例与官方示例有点区别,该示例使用了identity密码保护api。关于asp.net core identity的了解实现,查看之前章节或官方文档。示例中分别是identityserver令牌项目、 api资源项目、 client访问项目。与上篇相比一样,还是三个项目,区别在于:

  (1) identityserver令牌项目换成了含有asp.net core identity的mvc项目。

  (2) api资源项目没有变动。

  (3) client访问项目使用了用户名和密码访问受保护的api。

 

二. identityserver项目

  identityserver令牌项目是包含了 identity功能(安装:install-package identityserver4),在项目中,添加了config.cs类和startup.cs中加入了identityserver的启动配置。下面是mvc项目目录结构:

  (1) 添加用户

    identityserver类库中自带testuser测试类,是dto数据传输对象,存储用户及其声明(claims)。testuser是用于测试中的内存(in-memory)用户对象。在正式环境下,获取数据库中的用户表(user),需要结合identityserver的iresourceownerpasswordvalidator接口(不再本篇讲述中)。 下面通过在config.cs类中添加getusers方法获取用户密码,存储在testuser数据传输对象中。

        /// <summary>
        ///获取用户,这些用户可以访问受密码保护的api
        /// </summary>
        /// <param name="provider"></param>
        /// <returns></returns>
        public static list<testuser> getusers(serviceprovider provider)
        {
            var webappidentitydemouser = provider.getrequiredservice<usermanager<webappidentitydemouser>>();
            ilist<webappidentitydemouser> users = null;
            //获取identity的user表用户,条件是属于administrator角色的用户
            users = webappidentitydemouser.getusersinroleasync("administrator").result;

            list<testuser> testuserlist = new list<testuser>();
            foreach (webappidentitydemouser user in users)
            {
                testuserlist.add(new testuser() { subjectid = user.id.tostring(), username = user.username, password = user.passwordhash });
            }
            return testuserlist;
        }

  (2) 然后在startup类的configureservices方法中使用identityserver注入测试用户:

            serviceprovider provider = services.buildserviceprovider();

            var builder = services.addidentityserver()
                .addinmemoryidentityresources(config.getidentityresources())
                .addinmemoryapiresources(config.getapis())
                .addinmemoryclients(config.getclients())
                .addtestusers(config.getusers(provider));

  (3) 定义客户端, 使用密码授予访问此api(资源范围:api1)

    在config.cs类中,定义客户端,通过修改allowedgranttypes枚举来简单地向现有客户端添加对授权类型的支持, 将以下代码添加到客户端配置中, 里面支持二个client授权类型,分别是clientcredentials使用凭证来访问令牌和resourceownerpassword 使用密码来访问令牌。

      public static ienumerable<client> getclients()
        {
            return new list<client>
            {
                new client
                {
                    clientid = "client",

                    // no interactive user, use the clientid/secret for authentication
                    allowedgranttypes = granttypes.clientcredentials,

                    // secret for authentication
                    clientsecrets =
                    {
                        new secret("secret".sha256())
                    },

                    // scopes that client has access to
                    allowedscopes = { "api1" }
                },
                // resource owner password grant client
                new client
                {
                    clientid = "ro.client",
                    allowedgranttypes = granttypes.resourceownerpassword,

                    clientsecrets =
                    {
                        new secret("secret".sha256())
                    },
                    allowedscopes = { "api1" }
                }
            };
        }

  

三.client项目

  该client项目类似于上篇介绍的client项目,该项目名为resourceownerclient, 该client将收集用户名和密码,并在令牌请求期间,将其发送到identityserver令牌服务(webappidentitydemo项目)

            // request token 请求令牌
            var tokenresponse = await client.requestpasswordtokenasync(new passwordtokenrequest
            {
                address = disco.tokenendpoint,
                clientid = "ro.client",
                clientsecret = "secret",

                username = "924964690@qq.com",
                password = "aqaaaaeaaccqaaaaeh4xhui5bbyq6d8vs5z+s2o2snlkyrp5pn9cmmpgj4qiivrt7lblzdlewa6adlpxpa==",
                scope = "api1"
            });

            if (tokenresponse.iserror)
            {
                console.writeline(tokenresponse.error);
                return;
            }

            console.writeline(tokenresponse.json);
            console.writeline("\n\n");

  最后测试,先启动webappidentitydemo项目程序,再启动api程序,最后启动client客户端来访问api,通过下图可以了解到:(1)客户端请求使用“用户名和和密码”访问令牌(token)成功, (2) 客户端使用令牌(accesstoken)来访问受密码保护的web api接口成功。

  

  

  参考文献

    使用密码保护api

 

    

 

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

相关文章:

验证码:
移动技术网