亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

keystone源碼分析(一)——Paste Deploy的應(yīng)用

系統(tǒng) 1571 0

  本keystone源碼分析系列基于Juno版Keystone,于2014年10月16日隨Juno版OpenStack發(fā)布。

  Keystone作為OpenStack中的身份管理與授權(quán)模塊,主要實(shí)現(xiàn)系統(tǒng)用戶的身份認(rèn)證、基于角色的授權(quán)管理、其他OpenStack服務(wù)的地址發(fā)現(xiàn)和安全策略管理等功能。Keystone作為開源云系統(tǒng)OpenStack中至關(guān)重要的組成部分,與OpenStack中幾乎所有的其他服務(wù)(如Nova, Glance, Neutron等)都有著密切的聯(lián)系。同時(shí),Keystone作為開源的身份管理和授權(quán)系統(tǒng),對(duì)于其當(dāng)前實(shí)現(xiàn)機(jī)制的探討已經(jīng)成為許多信息安全領(lǐng)域研究人員的一個(gè)重要方向,基于其提出的安全模型與擴(kuò)展實(shí)現(xiàn)已經(jīng)很多,這里我們并不贅述這些學(xué)術(shù)成果。

  由于作者精力和能力有限,希望得到讀者的反饋與指正,轉(zhuǎn)載請(qǐng)注明出處。

  在分析任何一個(gè)系統(tǒng)前安裝并了解該系統(tǒng)的使用方法都是有益的,Keystone也不例外。關(guān)于如何安裝和配置Keystone請(qǐng)參考本博客的其他隨筆,這里我們假設(shè)讀者已經(jīng)熟悉OpenStack中每個(gè)服務(wù)的.conf和paste.ini配置文件的大體作用。

  首先介紹我的系統(tǒng)環(huán)境,由于重點(diǎn)關(guān)注Keystone的相關(guān)機(jī)理,我在團(tuán)隊(duì)已有10臺(tái)服務(wù)器組成的小型云外搭建了一個(gè)Keystone的開發(fā)調(diào)試環(huán)境。當(dāng)前使用的是Ubuntu 14.04 LTS Desktop,系統(tǒng)中的Keystone采用Ubuntu的apt工具安裝,源碼采用git下載,并且都是使用的Juno版本的分支,配置文件集中于/etc/keystone目錄下。

  首先我們查看/etc/keystone/keystone-paste.ini文件,這里簡(jiǎn)要的介紹這個(gè)文件的大體結(jié)構(gòu)與含義。

      
        #
      
      
         /etc/keystone/keystone-paste.ini
      
      
        

#
      
      
         filters
      
      
        [
        
          filter
        
        :token_auth]

paste.filter_factory 
      
      =
      
         keystone.middleware:TokenAuthMiddleware.factory


        
[ filter :admin_token_auth] paste.filter_factory
= keystone.middleware:AdminTokenAuthMiddleware.factory ... # applications [ app :service_v3] paste.app_factory = keystone.service:v3_app_factory ...
# pipelines [ pipeline :api_v3] pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth xml_body_v3 json_body ec2_extension_v3 s3_extension simple_cert_extension revoke_extension service_v3 ...
# composites [ composite :main] use = egg:Paste # urlmap /v2.0 = public_api /v3 = api_v3 / = public_version_api [ composite :admin] use = egg:Paste # urlmap /v2.0 = admin_api /v3 = api_v3 / = admin_version_api

  可以發(fā)現(xiàn)這個(gè)文件事實(shí)上由若干filter, pipeline, application和composite的定義組成,在定義時(shí)并非必須嚴(yán)格按照這樣的順序進(jìn)行隔離,這里為了分析的方便我們將其總結(jié)為這些段落。對(duì)于這些內(nèi)容的具體含義,可以參考Paste Deploy和Python WSGI相關(guān)的介紹。

?  Keystone的代碼生態(tài)圈包括keystone, python-keystoneclient和keystonemiddleware。其中keystone以WSGI服務(wù)器的方式實(shí)現(xiàn),其監(jiān)聽python-keystoneclient和keystonemiddleware發(fā)送來的HTTP請(qǐng)求并作出相應(yīng)響應(yīng)。

  keystone-paste.ini文件事實(shí)上是一個(gè)paste-deploy配置文件,該文件由application, filter, pipeline, composite等定義段落組成。composite是第一層調(diào)度者,它粗略地根據(jù)不同的url類型將請(qǐng)求分配到不同的pipeline上。每一個(gè)pipeline由若干filter和一個(gè)application組成。正如其名,filter按照其在pipeline中的先后順序依次對(duì)http請(qǐng)求進(jìn)行過濾,包括對(duì)參數(shù)進(jìn)行格式化處理等操作。application位于pipeline的末尾,每一個(gè)pipeline只有一個(gè)application。最終通過所有filter的請(qǐng)求被application進(jìn)一步調(diào)度到系統(tǒng)實(shí)現(xiàn)上每一個(gè)模塊的路由層(routers),路由層根據(jù)HTTP請(qǐng)求方法和具體的請(qǐng)求路徑,將HTTP請(qǐng)求分發(fā)給對(duì)應(yīng)的控制層(controllers),controllers集中實(shí)現(xiàn)業(yè)務(wù)邏輯,并通過調(diào)用更低的驅(qū)動(dòng)層完成底層的工作,如數(shù)據(jù)庫(kù)的讀寫等等。這些構(gòu)成了composite, pipeline, filter, application和keystone實(shí)現(xiàn)間的邏輯關(guān)系。

  keystone-paste.ini文件從一個(gè)高層次定義了keystone所需的composite會(huì)將哪些類型的url交由由哪些pipeline, 每一個(gè)pipeline由哪些filter和app組成,以及具體到每一個(gè)filter和app是由系統(tǒng)源碼的哪一個(gè)部分實(shí)現(xiàn)的,事實(shí)上,從下文的分析可以看出,每一個(gè)filter在實(shí)現(xiàn)上都對(duì)應(yīng)著一個(gè)特定的類,而每一個(gè)application在實(shí)現(xiàn)上則對(duì)應(yīng)著一個(gè)具體的方法。

  以前文節(jié)選的部分keystone-paste.ini文件為例,我們以一個(gè)OpenStack系統(tǒng)要求的REST風(fēng)格的HTTP請(qǐng)求視角看一下系統(tǒng)是如何實(shí)現(xiàn)的:

  當(dāng)用戶以HTTP POST方式請(qǐng)求http://localhost:5000/v3/auth/tokens這個(gè)url時(shí),意味著用戶希望進(jìn)行身份認(rèn)證,同時(shí)獲得keystone簽發(fā)的Token。當(dāng)然,用戶需要在自己的HTTP請(qǐng)求中給出一些自己的身份信息,這樣keystone才能據(jù)以判斷該用戶是否是系統(tǒng)合法的用戶,并根據(jù)其擁有的角色和權(quán)限為其簽發(fā)token。

  下面是一個(gè)這樣的HTTP請(qǐng)求例子,采用cURL命令行工具模擬,-d 代表了POST方法,-i參數(shù)說明我們要求系統(tǒng)顯示未來獲得的響應(yīng)(response)的header,-H參數(shù)指明了我們的請(qǐng)求攜帶的header,這里向keystone指出我們接受的網(wǎng)絡(luò)數(shù)據(jù)傳輸類型。

      curl -
      
        i \


      
      -H 
      
        "
      
      
        Content-Type: application/json
      
      
        "
      
      
         \


      
      -d 
      
        '


      
      
        {

    
      
      
        "
      
      
        auth
      
      
        "
      
      
        : {

        
      
      
        "
      
      
        identity
      
      
        "
      
      
        : {

            
      
      
        "
      
      
        methods
      
      
        "
      
      
        : [

                
      
      
        "
      
      
        password
      
      
        "
      
      
        

            ],

            
      
      
        "
      
      
        password
      
      
        "
      
      
        : {

                
      
      
        "
      
      
        user
      
      
        "
      
      
        : {

                    
      
      
        "
      
      
        domain
      
      
        "
      
      
        :{

                        
      
      
        "
      
      
        name
      
      
        "
      
      : 
      
        "
      
      
        Default
      
      
        "
      
      
        

                     },

                    
      
      
        "
      
      
        name
      
      
        "
      
      : 
      
        "
      
      
        USER_NAME
      
      
        "
      
      
        ,

                    
      
      
        "
      
      
        password
      
      
        "
      
      : 
      
        "
      
      
        PASSWORD
      
      
        "
      
      
        

                }

            }

         },

         
      
      
        "
      
      
        scope
      
      
        "
      
      
        : {

            
      
      
        "
      
      
        project
      
      
        "
      
      
        : {

                
      
      
        "
      
      
        domain
      
      
        "
      
      
        : {

                        
      
      
        "
      
      
        name
      
      
        "
      
      :
      
        "
      
      
        Default
      
      
        "
      
      
        

                },

               
      
      
        "
      
      
        name
      
      
        "
      
      : 
      
        "
      
      
        PROJECT
      
      
        "
      
      
        

            }

         }

     }

}
      
      
        '
      
      
         \
      
      

http:
      
        //127
      
      
        .0.0.1:5000/v3/auth/tokens
      
    

  系統(tǒng)首先根據(jù)paste-deploy配置文件結(jié)合請(qǐng)求的url類型(/v3)來判斷處理該請(qǐng)求的pipeline即api_v3,接著系統(tǒng)將該請(qǐng)求交由該pipeline來處理。pipeline api_v3中的所有filter會(huì)依次對(duì)該請(qǐng)求的header以及data等內(nèi)容進(jìn)行處理,比如過濾器sizelimit在進(jìn)行一定的操作后,將其傳給下一個(gè)過濾器url_normalize,依次類推,直到給請(qǐng)求被傳遞給管道盡頭的application。

  我們以兩個(gè)filter為例進(jìn)行探討,分別是token_auth和admin_token_auth,在該paste-deploy文件的filter定義字段,我們能夠找到這兩個(gè)filter的實(shí)現(xiàn)位置,事實(shí)上這也是系統(tǒng)搜尋每一個(gè)過濾器具體實(shí)現(xiàn)的依據(jù)。可以看到token_auth是由keystone.middleware:TokenAuthMiddleware.factory實(shí)現(xiàn)的,那么我們到keystone/middleware/core.py中找到TokenAuthMiddleware這個(gè)類:

      
        #keystone/middleware/core.py
        

class
TokenAuthMiddleware(wsgi.Middleware): def process_request(self, request): token = request.headers.get(AUTH_TOKEN_HEADER) context = request.environ.get(CONTEXT_ENV, {}) context[ ' token_id ' ] = token if SUBJECT_TOKEN_HEADER in request.headers: context[ ' subject_token_id ' ] = ( request.headers.get(SUBJECT_TOKEN_HEADER)) request.environ[CONTEXT_ENV] = context

  發(fā)現(xiàn)該類繼承了wsgi.Middleware,說明這個(gè)類實(shí)質(zhì)上是一個(gè)WSGI中間件。該中間件提取了http請(qǐng)求中的X-Auth-Token字段和(可選的)X-Subject-Token字段的值,將context中相應(yīng)的字段填充為這兩個(gè)值,然后將修改后的上下文寫回到請(qǐng)求攜帶的環(huán)境信息中,傳遞給下一個(gè)filter即中間件admin_token_auth。再來看filter admin_token_auth是如何實(shí)現(xiàn)的,首先定位其實(shí)現(xiàn)的位置:keystone.middleware:AdminTokenAuthMiddleware.factory,接著到源碼keystone/middleware/core.py模塊下找到相應(yīng)的AdminTokenAuthMiddleware類,

      
        #keystone/middleware/core.py
        

class
AdminTokenAuthMiddleware(wsgi.Middleware): """ A trivial filter that checks for a pre-defined admin token. Sets 'is_admin' to true in the context, expected to be checked by methods that are admin-only. """ def process_request(self, request): token = request.headers.get(AUTH_TOKEN_HEADER) context = request.environ.get(CONTEXT_ENV, {}) context[ ' is_admin ' ] = (token == CONF.admin_token) request.environ[CONTEXT_ENV] = context、

  可見這個(gè)過濾器的功能也非常簡(jiǎn)單,就是從http請(qǐng)求header中的X-Auth-Token字段提取附帶的token,同時(shí)解析keystone主配置文件(keystone.conf)中[DEFAULT]字段下的admin_token選項(xiàng),二者進(jìn)行比對(duì),如果結(jié)果相同,說明這個(gè)請(qǐng)求的發(fā)送者是我們系統(tǒng)默認(rèn)的admin,在context字典的is_admin字段設(shè)1后寫回到請(qǐng)求的環(huán)境信息,否則在context字典的is_admin字段置0。當(dāng)然,熟悉keystone官方文檔的用戶會(huì)發(fā)現(xiàn),在keystone的官方文檔中強(qiáng)烈建議生產(chǎn)環(huán)境中刪除該中間件,同時(shí)不設(shè)置keystone.conf文件中[DEFAULT]字段下的admin_token選項(xiàng),因?yàn)樵搕oken的出示者將會(huì)獲得系統(tǒng)的最高權(quán)限,因此禁用該賬戶能夠避免一些不必要的攻擊。

  從上面的兩個(gè)例子可以看到,每一個(gè)filter進(jìn)行一個(gè)具體的操作,這些操作比較簡(jiǎn)單和獨(dú)立,彼此按先后順序串聯(lián)起來,如本例中的過濾器token_auth放置在過濾器admin_token_auth之前,這就使得系統(tǒng)在對(duì)context的is_admin字段進(jìn)行填充以前,會(huì)對(duì)token_id和subject_token_id字段進(jìn)行填充。

  最后我們看一下application是如何實(shí)現(xiàn)的。在pipeline api_v3的末端對(duì)應(yīng)著最終的服務(wù)器應(yīng)用service_v3,我們根據(jù)keystone-paste.ini文件中給出的位置paste.app_factory = keystone.service:v3_app_factory找到該app的具體實(shí)現(xiàn):keystone/service.py,

      
        #
      
      
        keystone/service.py
      
      

...
      
@fail_gracefully def v3_app_factory(global_conf, ** local_conf): controllers.register_version( ' v3 ' ) mapper = routes.Mapper() sub_routers = [] _routers = [] router_modules = [assignment, auth, catalog, credential, identity, policy] if CONF.trust.enabled: router_modules.append(trust) for module in router_modules: routers_instance = module.routers.Routers() _routers.append(routers_instance) routers_instance.append_v3_routers(mapper, sub_routers) # Add in the v3 version api sub_routers.append(routers.VersionV3( ' admin ' , _routers)) sub_routers.append(routers.VersionV3( ' public ' , _routers)) return wsgi.ComposingRouter(mapper, sub_routers)
...

  可以看到,該application將會(huì)實(shí)現(xiàn)第二層路由(第一層由keystone-paste.ini文件中的composite字段實(shí)現(xiàn)),此次路由將具體的請(qǐng)求處理工作進(jìn)一步分發(fā)到系統(tǒng)的各個(gè)模塊上,比如代碼中的assignment,auth, catalog等等。由具體的模塊根據(jù)請(qǐng)求的具體路徑和內(nèi)容完成具體功能。

  裝飾器@fail_gracefully在keystone/service.py中也有定義,主要功能是包裹住前文中的函數(shù)v3_app_factory,正如名稱所示,讓被裝飾的v3_app_factory()函數(shù)能夠“優(yōu)雅”地執(zhí)行,而由fail_gracefully()來處理可能的日志記錄和異常處理等善后工作。

      
        #
      
      
        keystone/service.py
      
      
        

...


      
      
        def
      
      
         fail_gracefully(f):

    
      
      
        """
      
      
        Logs exceptions and aborts.
      
      
        """
      
      
        

    @functools.wraps(f)

    
      
      
        def
      
       wrapper(*args, **
      
        kw):

        
      
      
        try
      
      
        :

            
      
      
        return
      
       f(*args, **
      
        kw)

        
      
      
        except
      
      
         Exception as e:

            LOG.debug(e, exc_info
      
      =
      
        True)



            
      
      
        #
      
      
         exception message is printed to all logs
      
      
                    LOG.critical(e)

            sys.exit(
      
      1
      
        )

    
      
      
        return
      
      
         wrapper

...
      
    

  至此,我們從WSGI和paste-deploy的角度邁出了深入了解keystone實(shí)現(xiàn)的第一步,知道了keystone服務(wù)器是如何將一個(gè)HTTP請(qǐng)求粗略地歸類分發(fā)到pipeline,再通過filter到達(dá)相應(yīng)的app。下一步,我們將會(huì)看到每一個(gè)pipeline末端的app如何針對(duì)具體的HTTP請(qǐng)求方法和地址將其分發(fā)到對(duì)應(yīng)的router,router再將其交給相應(yīng)的controller,由controller承上啟下完成最終的工作的。

keystone源碼分析(一)——Paste Deploy的應(yīng)用


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 毛片免费观看网址 | 国产91亚洲精品 | 高清一区高清二区视频 | 337p欧洲亚洲大胆艺术 | 9191精品国产免费不久久 | 真人视频一级毛片 | 黄色影院免费看 | 美国黑人特大一级毛片 | 久久美剧免费在线观看 | 精品国产乱码久久久久久浪潮 | 欧美一级成人毛片影院 | 亚洲精品乱码国产精品乱码 | 亚洲免费成人在线 | 欧美午夜在线观看理论片 | 久爱www成人网免费视频 | 久久精品国产99久久99久久久 | 欧美日韩国产一区二区三区 | 老司机午夜精品99久久免费 | 亚洲欧美日韩v中文在线 | 日本xxxxx18护士xxx | 香蕉在线精品亚洲第一区 | 亚洲国产精品区 | 亚洲国产精品综合久久2007 | 亚洲精品国产福利一区二区三区 | 日韩精品特黄毛片免费看 | 欧美成人免费看片一区 | 久久久久久久久久免免费精品 | 日本免费人做人一区在线观看 | 亚洲国产国产综合一区首页 | 久久亚洲精中文字幕冲田杏梨 | 日本不卡在线观看 | 亚洲成人aaa | 亚洲视频在线观看不卡 | 久久国产精品久久精 | 中国欧美日韩一区二区三区 | 亚洲福利一区二区 | 日本最猛黑人xxxx猛交 | 橘子视频在线观看 | 波多野结衣中文字幕一区 | 欧美亚洲一区二区三区在线 | 日日射视频 |