WS Security 認證方式詳解


本文參考文檔如下:

MSDN 官方詳解 : http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/HowASP.NETWebServicesWork.mspx?mfr=true

WS安全規范說明 : https://www.oasis-open.org/committees/download.php/16782/wss-v1.1-spec-os-UsernameTokenProfile.pdf

WS Security 一些歷史信息 : http://zh.wikipedia.org/wiki/WS-Security

如有不理解,請參考上面三個資源。

 

WS-Security 所涉及的三個方面:身份驗證、簽名和加密

1.身份驗證

常用的的三種認證方法:

 

1.1用戶名/密碼

在Apache CXF中,可以使用如下定義來使用用戶名密碼認證:

客戶端:

<jaxws:client id="xxx" serviceClass="xxxy"
        address="xxx">
        
        <jaxws:outInterceptors>
            <bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
                <constructor-arg>
                    <map>
                        <entry key="action" value="UsernameToken"/>
                        <entry key="user" value="xxx"/>
                        <!-- Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) )  -->
                        <entry key="passwordType" value="PasswordDigest"/>
                        <entry key="passwordCallbackRef" value-ref="myPasswordCallback"/>
                    </map>
                </constructor-arg>
            </bean>
        </jaxws:outInterceptors>
        
    </jaxws:client>

  以上的passwordType值為PasswordText時,則密碼使用明文傳輸;為PasswordDigest時,則Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) )

比如傳輸的SOAP報文為:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
        <wsse:Security
            xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
            xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
            soap:mustUnderstand="1">
            <wsse:UsernameToken wsu:Id="UsernameToken-1">
                <wsse:Username>xxx</wsse:Username>
                <wsse:Password
                    Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">4t7Q2C0DnV21ie6ngsv6CwZ3vVw=</wsse:Password>
                <wsse:Nonce
                    EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">R+6n+Z5L6FaG8IqeDrLGXw==</wsse:Nonce>
                <wsu:Created>2014-04-21T09:56:51.361Z</wsu:Created>
            </wsse:UsernameToken>
        </wsse:Security>
    </soap:Header>
    <soap:Body>
        ......
    </soap:Body>
</soap:Envelope>

 

  則上面計算的Password_Digest的參數則來源於wsse:Security下面的各個節點參數值。

使用加密的密碼傳輸,則客戶端與服務端都需要指定一個passwordCallbackRef,該實現類繼承CallbackHandler,下面做個示例

public class ClientMyPasswordCallback implements CallbackHandler {
    
    private static final Log log = LogFactory.getLog(MyPasswordCallback.class);
    
    /* (non-Javadoc)
     * @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
     */
    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {

        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
        
        pc.setPassword("xxx");
        
        
    }
    
}

 

  服務端則使用:

public class ServerMyPasswordCallback implements CallbackHandler {
    
    private static final Log log = LogFactory.getLog(MyPasswordCallback.class);
    
    /* (non-Javadoc)
     * @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
     */
    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {

        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
        
    //通過數據庫得到該用戶名的密碼,這里略去該過程
String password = getPwdByUname(pc.getIdentifier());
  

        pc.setPassword(password );//直接設置從數據庫得到的密碼,WSS4J自動匹配該值與客戶端傳入的值,不需要調用pc.getPassword();因為它總是返回null
        
        
    }
    
}

  服務端的攔截器中匹配密碼方式是自動的,不需要從pc.getPassword()得到密碼自己匹配,由於加密算法比較麻煩,所以省去這一步應該是比較好的設計

 

X.509 證書與Kerberos則參考:

http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/HowASP.NETWebServicesWork.mspx?mfr=true

文章里說明很清楚,不再重復。

 

2.簽名

簽名可以防止消息在傳輸中被篡改進行重復攻擊等,可使用私鑰對需要的部分進行簽名,比如在上節的<身份認證>中,如果消息被截獲,可導致重復攻擊,

需要對請求設置過期時間(wsu:Timestamp->wsu:Expires)並簽名。

 

3.消息包數據加密

若傳輸的消息屬於高安全級別,則需要使用X.509 證書對消息加密,即客戶端使用服務端的公鑰加密,服務端通過私鑰解包,消息包只能在知道服務端私鑰情況下才能解開。

要對全部SOAP包加密,可啟用SSL(通常為HTTPS)。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM