利用 UsernameToken 鑑別 Web 服務用戶端
WebSphere® Application Server Liberty 支援 OASIS「Web 服務安全」UsernameToken 設定檔 1.1 規格。 這個規格說明 Web 服務用戶端如何提供 UsernameToken 作為手段,以利用使用者名稱,及選擇性利用密碼或密碼對等項,讓 Web 服務提供者識別要求端。 Liberty 中處理 Web 服務提供者原則的「Web 服務安全」(WS-Security) 執行時期,可以利用這個識別資訊來鑑別使用者。
在 WS-Security 原則中,UsernameToken 需求以其支援記號之一表示。 您可以新增 UsernameToken 需求作為其中一項支援記號確認中的必要記號,其中包括 SupportingTokens、SignedSupportingTokens、SignedEndorsingSupportingTokens、SignedEncryptedSupportingTokens 和 EncryptedSupportingTokens。
<sp:SupportingTokens>
<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken11 />
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
除了必須提供使用者名稱或密碼,您還可以配置原則,將 nonce 和 created 時間戳記併入到 UsernameToken 中。
<sp:SupportingTokens>
<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken11 />
<sp13:Created />
<sp13:Nonce />
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
<sp:SupportingTokens>
<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken11 />
<sp:HashPassword />
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
如需 nonce、created 及不同密碼類型的相關資訊,請參閱 OASIS WS-Security 原則 1.3 規格。
在 Web 服務用戶端中提供使用者名稱和密碼
Liberty 中的 WS-Security 特性提供多種方法,可在產生 UsernameToken 時,用來指示用戶端應用程式的使用者名稱和密碼。您可以用程式設計方式,或在 server.xml 檔中,設定使用者名稱和密碼。
用戶端可以產生含有 server.xml 檔所提供之使用者名稱和密碼的 UsernameToken。 在 server.xml 檔中的使用者名稱和密碼被視為預設配置,用戶端 Web 服務呼叫的 RequestContext 所提供的內容會置換它。
<wsSecurityClient id="default"
ws-security.username="alice"
ws-security.callback-handler="com.acme.PasswordCallback"
</wsSecurityClient>
- ws-security.username - 使用者名稱
- ws-security.password - 使用者密碼(如果未定義 ws-security.callback-handler 的話)
- ws-security.callback-handler - 用來取得密碼的 CallbackHandler 實作類別
Map<String, Object> requestCtx = ((BindingProvider)port).getRequestContext();
requestCtx.put("ws-security.username", "bob_username");
requestCtx.put("ws-security.password", "bob_password");
在 Web 服務提供者中使用 UsernameToken
當收到 UsernameToken 時,WS-Security 會自動利用 Liberty 安全使用者登錄來驗證使用者名稱和密碼 (如果需要密碼的話)。如果 UsernameToken 中的密碼類型是 PasswordDigest 或是使用衍生金鑰,您必須在 server.xml 檔中配置密碼回呼處理常式,以提供 ws-security.callback-handler 的實作。這個回呼處理常式必須傳回所有預期使用者名稱的有效密碼,以便 WS-Security 執行時期能夠計算摘要值來比較 SOAP 訊息中的值。 摘要值順利比較完成之後,會針對使用者登錄來驗證使用者名稱和密碼。
<wsSecurityProvider id="default"
ws-security.callback-handler="com.acme.PasswordCallback"
</wsSecurityProvider>
密碼 CallbackHandler
WS-Security 利用密碼 CallbackHandler 來擷取使用者密碼。 在 Liberty 中,這個密碼 CallbackHandler 類別必須包裝成一項 Liberty 特性。如需密碼 CallbackHandler 的相關資訊,請參閱開發 WS-Security 的密碼回呼處理常式。
如需回呼處理常式實作的需求和限制的相關資訊,請參閱利用 X.509 記號保護 Web 服務的「私密金鑰密碼 CallbackHandler」一節。
保護 SOAP 訊息中的 UsernameToken
<UsernameToken>
<Username>myusername</Username>
<Password
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
mypassword
</Password>
</UsernameToken>
當您想要利用 PasswordText 來傳送 UsernameToken 時,請考慮訊息的其他保護,例如使用 HTTPS,或利用 EncryptedSupportingToken 原則主張將記號加密。 如需要求在原則中使用 HTTPS 傳輸的相關資訊,請參閱 Liberty:Web 服務安全 HTTPS 傳輸原則主張。
UsernameToken 金鑰衍生
依照「Web 服務安全」UsernameToken Profile 1.1 規格所述:
與使用者名稱相關聯的密碼可用來衍生共用秘密金鑰,以達成訊息內容得到完整性或機密性保護之目的。
請注意,密碼有可能遭到多種攻擊,從而導致任何衍生金鑰的曝光。 這個金鑰衍生程序的目的是在儘可能的範圍內,使金鑰遭受攻擊的風險降到最低,但它終究要受限於密碼能夠為人所記憶,並在標準鍵盤上進行輸入的不安全性。
必須有兩個其他元素,才能夠從密碼衍生金鑰。 它們是 <wsse11:Salt> 和 <wsse11:Iteration>。 這些值不是秘密,當使用金鑰衍生時,必須在 Username 記號中傳送它們。 當使用金鑰衍生時,密碼不能包含在 Username 記號中。 接收端會利用其密碼知識來衍生與傳送者相同的金鑰。
如果 UsernameToken 是使用金鑰衍生,則對於提供者應用程式,您必須在 server.xml 檔中配置密碼回呼處理常式,以提供 ws-security.callback-handler 的實作。
<sp:SymmetricBinding>
<wsp:Policy>
<sp:ProtectionToken>
<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken10 />
<sp:RequireDerivedKeys />
</wsp:Policy>
</sp:UsernameToken>
<wsp:Policy>
</sp:ProtectionToken>
</wsp:Policy>
</sp:SymmetricBinding>
<wsse:UsernameToken wsse:Id="...">
<wsse:Username>...</wsse:Username>
<wsse11:Salt>...</wsse11:Salt>
<wsse11:Iteration>...</wsse11:Iteration>
</wsse:UsernameToken>