OpenSAML 使用引導 I : 簡介——關(guān)于OpenSAML你所需知道的一切

相關(guān)閱讀SAML2.0入門指南, 此文中已經(jīng)介紹了SAML協(xié)議的基本信息媒怯,今天開始將會為大家詳解OpenSaml——SAML協(xié)議的一種開源實現(xiàn)岛琼。

SAML

What's OpenSAML

OpenSAML是一個便于使用SAML消息的依賴庫,其提供的主要功能包括:

  1. 創(chuàng)建SAML消息季研;
  2. 解析SAML對象并導出為XML格式剃盾;
  3. 簽名和加密坏逢;
  4. 對SAML消息進行編碼并傳輸。

目前OpenSAML庫提供Java和C++實現(xiàn)的版本妙黍,需要注意的是OpenSAML雖然多應(yīng)用用于SSO(單點登錄)的開發(fā)中悴侵,但是該庫本身不提供任何身份識別和授權(quán)的功能,其只是實現(xiàn)對于SAML消息的相關(guān)操作而已拭嫁。

SAML

SAML是一種XML框架用來交換安全信息可免,其中定義了按照安全規(guī)范所需要的通信的協(xié)議和格式。

SAML是一種中心化的認證機制做粤,其定義了兩種實體相互通信:

  • Service Provider(SP): 向用戶提供正式商業(yè)服務(wù)的實體浇借,通常需要認證一個用戶的身份;
  • Identity Provider(IDP): 提供用戶的身份鑒別怕品,確保用戶是其所聲明的身份妇垢;

SAML的重要用途:

  • 單點登錄(SSO Single Sign-ON);
  • 聯(lián)合認證(Federated Identity)肉康;
  • 在其他架構(gòu)內(nèi)使用SAML闯估,比如WS-Security。

更多關(guān)于SAML的內(nèi)容吼和,請參看SAML2.0入門指南

SAML相關(guān)定義

1. 斷言(Assertions) 即信息

斷言是在SAML中用來描述認證的對象涨薪,其中包括一個用戶在什么時間、以什么方式被認證纹安,同時還可以包括一些擴展信息尤辱,比如用戶的Email地址和電話等等砂豌。

下面便是一個斷言的實例:


但愿.png

2. 協(xié)議(Protocol)即通信

協(xié)議規(guī)定如何執(zhí)行不同的行為。這些行為被細化成一些列的Request和Response對象光督,而在這些請求和相應(yīng)的對象中包含了行為所特別需要的信息阳距。比如,認證請求協(xié)議(AuthnRequest Protocol)就規(guī)定了一個SP如何請求去獲得一個被認證的與用戶结借。

<saml2p:AuthnRequest
    AssertionConsumerServiceURL=http://localhost:8080/webprofile-refproject/sp/consumer
    Destination="http://localhost:8080/webprofile-refproject/idp/singleSignOnService"
    ID="_52c9839568ff2e5a10456dfefaad0555"
    IssueInstant="2014-05-13T17:34:37.810Z"
    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTPArtifact"
    Version="2.0">
    <saml2:Issuer>
        TestSP
    </saml2:Issuer>
    <saml2p:NameID
        PolicyAllowCreate="true"
        Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
    <saml2p:RequestedAuthnContext Comparison="minimum">
        <saml2:AuthnContextClassRef>
            urn:oasis:names:tc:SAML:2.0:ac:classes:Password
        </saml2:AuthnContextClassRef>
    </saml2p:RequestedAuthnContext>
</saml2p:AuthnRequest>

3. 綁定(Binding)即傳輸

綁定定義了SAML信息如何使用通信協(xié)議被傳輸?shù)目鹫1热纾琀TTP重定向綁定船老,即聲明SAML信息將通過HTTP重定向消息傳輸咖熟;再比如SAML SOAP綁定,聲明了通過SOAP來傳遞SAML消息柳畔。

SAML消息.png

配置(Profiles) 即綜合

配置定義了如何組織以上信息馍管,并且在一個更高的層次上描述斷言,協(xié)議和綁定如何被使用去解決一個具體情況薪韩。比如Web瀏覽器的SSO配置就描述了如何一個用戶使用瀏覽器被認證确沸。

元數(shù)據(jù)(MetaData)

SAML的元數(shù)據(jù)是配置數(shù)據(jù),其包含關(guān)于SAML通信各方的信息俘陷,比如通信另一方的ID罗捎、Web Service的IP地址、所支持的綁定類型以及通信中實用的密鑰等等拉盾。

OpenSaml中提供了metadata provider來幫助構(gòu)建和解讀元數(shù)據(jù)桨菜。

SAML通過Web瀏覽器實現(xiàn)的協(xié)議流程

通過HTTP協(xié)議綁定來實現(xiàn)SSO:

SAML協(xié)議流程.png

1. 用戶嘗試獲得權(quán)限

流程首先從一個非認證的用戶開始,該用戶嘗試從一個受保護的SP那里獲得訪問權(quán)限捉偏。某種方式的過濾器被設(shè)置在訪問路徑上來檢測用戶是否被授權(quán)(J2ee中servlet類就是一個很好地例子)倒得。這一部分其實并不是SAML協(xié)議里的內(nèi)容,但是卻決定了是否要被授權(quán)告私。

2. 用戶被重定向到IDP

當訪問路徑上被設(shè)置的過濾器發(fā)現(xiàn)用戶并非是被認證的屎暇,將會自動把用戶從定向到IDP,以求驗證用戶的身份驻粟。

3. 用戶被認證

在這一步里根悼,用戶被認證。注意這里并沒任何涉及到SP的交互蜀撑,在安全方式內(nèi)挤巡,IDP對于認證用戶有著全權(quán)責任。

4. 已認證的用戶被從定向回SP

當用戶被認證成功之后酷麦,用戶會攜帶著SAML產(chǎn)物(SAML artifact)被從定向回SP矿卑。這樣的SAML產(chǎn)物也可以說是認證信息的標識,因為認證信息中有敏感的信息不能直接通過瀏覽器傳輸沃饶,所以這里只是發(fā)送標識而已母廷。

5. 要求認證信息

當收到SAML產(chǎn)物之后轻黑,SP將其發(fā)送回IDP,IDP依據(jù)SAML產(chǎn)物找到認證信息琴昆,并通過SAML產(chǎn)物響應(yīng)(SAML Artifact Response)發(fā)送回SP

上面提到的SAML產(chǎn)物響應(yīng)(SAML Artifact Response) 中就包含SAML斷言氓鄙,它就是認證的證據(jù)。斷言中最重要的數(shù)據(jù)就該用戶什么時候以什么方式被認證的业舍。

OpenSAML 快速上手

說了這么多理論上的流程抖拦,現(xiàn)在開始講講OpenSAML這個庫的構(gòu)成和使用。

如何添加OpenSAML庫

OpenSAML庫可以在OpenSAML的主頁中獲得舷暮,對于Maven用戶可以直接在如下鏈接中獲得依賴:
https://build.shibboleth.net/nexus/content/repositories/releases/org/opensaml/

OpenSAML3是由Maven組織的多模塊庫态罪,每個模塊的功能各不相同。由于項目功能越來越豐富下面,對于現(xiàn)在的用戶已經(jīng)不可能通過一個單一的依賴來引用其所有的功能了复颈。每個模塊都需要添加自己都得引用。OpenSAML最新版的模塊列表如下:

? opensaml-core
? opensaml-profile-api
? opensaml-profile-impl
? opensaml-soap-api
? opensaml-soap-impl
? opensaml-saml-api
? opensaml-saml-impl
? opensaml-xacml-api
? opensaml-xacml-impl
? opensaml-xacml-saml-api
? opensaml-xacml-saml-impl
? opensaml-messaging-api
? opensaml-messaging-impl
? opensaml-storage-api
? opensaml-storage-impl
? opensaml-security-api
? opensaml-security-impl
? opensaml-xmlsec-api
? opensaml-xmlsec-impl

用戶可以根據(jù)自己項目的情況自行添加需要的模塊沥割,Maven中具體引用的信息如下:

<dependencies>
    <dependency>
        <groupId>org.opensaml</groupId>
        <artifactId>opensaml-core</artifactId>
        <version>3.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.opensaml</groupId>
        <artifactId>opensaml-saml-api</artifactId>
        <version>3.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.opensaml</groupId>
        <artifactId>opensaml-saml-impl</artifactId>
        <version>3.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.opensaml</groupId>
        <artifactId>opensaml-messaging-api</artifactId>
        <version>3.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.opensaml</groupId>
        <artifactId>opensaml-messaging-impl</artifactId>
        <version>3.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.opensaml</groupId>
        <artifactId>opensaml-soap-api</artifactId>
        <version>3.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.opensaml</groupId>
        <artifactId>opensaml-soap-impl</artifactId>
        <version>3.2.0</version>
    </dependency>
</dependencies>
<repositories>
    <repository>
        <id>Shibboleth repo</id>
        <url>
        https://build.shibboleth.net/nexus/content/repositories/releases
        </url>
    </repository>
</repositories>

保證JCE實現(xiàn)的正確性

OpenSAML使用JCE來提供密碼學的功能模塊券膀。由于某些
JCE的實現(xiàn)并不覆蓋所有OpenSAML要求的功能,所以推薦使用Bouncy Castle的JCE實現(xiàn)驯遇。

為了幫助用戶來確認JCE的實現(xiàn)是否正確,可以使用如下函數(shù):

JavaCryptoValidationInitializer javaCryptoValidationInitializer = 
    new JavaCryptoValidationInitializer();
javaCryptoValidationInitializer.init();

這個方法應(yīng)該在OpenSAML初始化之被調(diào)用蓄髓,來確保當前的環(huán)境可以符合要求叉庐。

如下方法可以用來打印當前已經(jīng)被安裝的所有JCE的provider:

for (Provider jceProvider : Security.getProviders()) {
    logger.info(jceProvider.getInfo());
}

使用Maven引用OpenSAML時,Bouncy Castle
provider將會被自動引用会喝。如果是手動下載OpenSAML源碼依賴陡叠,其中也已經(jīng)包括了Bouncy Castle
provider,但是需要手動添加到class path中肢执。

日志打印

OpenSAML使用SLF4J管理日志信息枉阵。雖然SLF4J本身沒有任何打印日志的能力,但是其依賴于其他logging的實現(xiàn)來做日志管理预茄。OpenSAML團隊選擇使用Logback來實現(xiàn)logging功能(其他的實現(xiàn)也可以)兴溜。

為了能使用LogBack,需要添加依賴包:

  • logback-core
  • logback-classic
  • apache commons logging

其下載鏈接如下:
http://logback.qos.ch/download.html,
https://commons.apache.org/proper/commons-logging/

或者直接添加Maven依賴:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.0.13</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.0.13</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.0.13</version>
</dependency>
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

OpenSAML初始化過程

OpenSAML的初始化依賴于一些列配置文件耻陕。OpenSAML已經(jīng)有一個默認的配置拙徽,其已經(jīng)可以滿足大多數(shù)的使用需求,如果有需要還可以對其修改诗宣。

配置文件必須在OpenSAML使用之前被加載膘怕,加載默認配置需的方法如下進行:

InitializationService.initialize();

這之后,OpenSAML庫才能正常使用召庞;

如果不加載配置文件岛心,OpenSAML的初始化將不能完成来破,其無法返回某個Obejct,返回NullPointerException忘古。這是一個常見的錯誤徘禁。

創(chuàng)建SAML對象

SAML對象的創(chuàng)建使用了工廠模式和構(gòu)建者模式,涉及到鏈式配置和類型準換存皂。

創(chuàng)建SAML斷言對象的方法如下:

XMLObjectBuilderFactory builderFactory =
    XMLObjectProviderRegistrySupport.getBuilderFactory();
Assertion assertion = (Assertion) builderFactory
    .getBuilder(Assertion.DEFAULT_ELEMENT_NAME)
    .buildObject(Assertion.DEFAULT_ELEMENT_NAME);

為了避免大量不需要的代碼晌坤,使用泛型的工具方法是一個好主意〉┐可以通過如下方法生成不同類型的對象:

public static <T> T buildSAMLObject(final Class<T> clazz) {
    XMLObjectBuilderFactory builderFactory =
        XMLObjectProviderRegistrySupport.getBuilderFactory();
    QName defaultElementName = (QName) clazz.getDeclaredField(
    "DEFAULT_ELEMENT_NAME").get(null);
    T object = (T) builderFactory.getBuilder(defaultElementName)
        .buildObject(defaultElementName);
    return object;
}

通過使用上面的方法骤菠,就可以將生成斷言對象的代碼簡化為一行;

OpenSAMLUtils.buildSAMLObject(Assertion.class);

實例項目

為了方便讀者理解和后續(xù)文章的解讀疤孕,這里提供一個示例項目:一個很簡單的網(wǎng)址商乎,其充當SP;同時該項目還包括一個很簡單的IDP祭阀;
SAML協(xié)議的交互將在這二者之間展開鹉戚。

項目地址:
https://github.com/sunrongxin7666/OpenSAML-ref-project-demo-v3.git

這個項目基于Bitbucket的一個實驗項目https://bitbucket.org/srasmusson/webprofile-ref-project-v3
其本身是使用Apache Maveng構(gòu)建的,啟動項目需要執(zhí)行

mvn tomcat:run

嵌入項目中的Tomcat就會啟動专控,運行成功時會有如下信息:

INFO: Starting Coyote HTTP/1.1 on http-8080

經(jīng)過本人的修改抹凳,該項目可以在IntelliJ Idea以工程模式打開,運行方式設(shè)置為mvn伦腐,命令是tomcat:run赢底。這就便于讀者調(diào)試和修改。

Idea配置

項目啟動之后柏蘑,訪問如下網(wǎng)址:
http://localhost:8080/webprofile-ref-project/app/appservlet
這是一個SP的模擬幸冻,第一次訪問該網(wǎng)址時將會跳轉(zhuǎn)到IDP,進行認證流程咳焚。

IDP

點擊“Authenticate”按鈕將通過認證洽损,并重定向回SP,


SP

到此為止整個SAML協(xié)議的流程及完成了,相關(guān)日志信息會在控制臺中輸出革半。

這雖然是一個最簡單的實例碑定,但是涉及多個部分的代碼,如何使用OpenSAML庫實現(xiàn)每一個步的流程又官,歡迎關(guān)注后續(xù)文章:

  1. OpenSAML 使用引導 II : Service Provider 的實現(xiàn)之AuthnRequest
  2. OpenSAML 使用引導 III: Service Provider 的實現(xiàn)之Artifact與斷言
  3. OpenSAMl 使用引導IV: 安全特性
    原創(chuàng)不易不傅,希望大家支持。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赏胚,一起剝皮案震驚了整個濱河市访娶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌觉阅,老刑警劉巖崖疤,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秘车,死亡現(xiàn)場離奇詭異,居然都是意外死亡劫哼,警方通過查閱死者的電腦和手機叮趴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來权烧,“玉大人眯亦,你說我怎么就攤上這事“懵耄” “怎么了妻率?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長板祝。 經(jīng)常有香客問我宫静,道長,這世上最難降的妖魔是什么券时? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任孤里,我火速辦了婚禮,結(jié)果婚禮上橘洞,老公的妹妹穿的比我還像新娘捌袜。我一直安慰自己,他們只是感情好炸枣,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布琢蛤。 她就那樣靜靜地躺著,像睡著了一般抛虏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上套才,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天迂猴,我揣著相機與錄音,去河邊找鬼背伴。 笑死沸毁,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的傻寂。 我是一名探鬼主播息尺,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疾掰!你這毒婦竟也來了搂誉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤静檬,失蹤者是張志新(化名)和其女友劉穎炭懊,沒想到半個月后并级,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡侮腹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年嘲碧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片父阻。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡愈涩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出加矛,到底是詐尸還是另有隱情履婉,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布荒椭,位于F島的核電站谐鼎,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏趣惠。R本人自食惡果不足惜狸棍,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望味悄。 院中可真熱鬧草戈,春花似錦、人聲如沸侍瑟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涨颜。三九已至费韭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間庭瑰,已是汗流浹背星持。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留弹灭,地道東北人督暂。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像穷吮,于是被迫代替她去往敵國和親逻翁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容