2012-10-23 68 views
7

我正在使用Jain Sip庫,嘗試創建與星號服務器的連接。我一直在從這個頁面的textclient示例應用程序工作: http://www.oracle.com/technetwork/articles/entarch/introduction-jain-sip-090386.htmlJain-Sip身份驗證

但這實際上並沒有與服務器進行身份驗證。我可以將消息發送給服務器上的用戶,但我通常需要在服務器上進行用戶/密碼驗證。

據我可以告訴我必須使用「javax.sip.OUTBOUND_PROXY」屬性,但我找不到任何有關如何設置用戶名或密碼的文檔。有沒有其他人對此有過任何成功?

回答

7

最好的例子,我已經找到了更好登記發現here。 這裏,如果萬一鏈接乾涸,一片天的要點:

註冊請求被用來在 的註冊服務器更新用戶的當前位置。應用程序發送一條註冊消息 ,通知服務器其當前位置,該位置又存儲在位置服務器 中。當呼叫者呼叫用戶時,代理服務器使用此 信息來查找被呼叫者的位置。

註冊請求應該由客戶端定期發送。 REGISTER請求的有效性由Expires標頭決定。

流量

image

樣品申請

REGISTER sip:sip.linphone.org SIP/2.0 
Call-ID: [email protected] 
CSeq: 1 REGISTER 
From: <sip:[email protected]>;tag=-1427592833 
To: <sip:vks[email protected]> 
Max-Forwards: 70 
Via: SIP/2.0/TCP 223.1.1.128:5060;branch=z9hG4bK-323532-2a454f4ec2a4213f6d6928eba479521d 
Contact: <sip:[email protected];transport=tcp> 
Content-Length: 0 

現在讓我們看看如何建立基於NIST SIP棧 上述要求。

第一步是創建一個實現SIPListener的類。使 確保您的SIP堆棧正在初始化NIST JAIN SIP堆棧。

  1. 創建Call-ID頭

    CallIdHeader callIdHeader = this.sipProvider.getNewCallId();

  2. 創建Cseq頭

    CSeqHeader cSeqHeader = this.headerFactory.createCSeqHeader(Cseq的, " REGISTER ");

  3. 創建From頭

    地址FROMADDRESS = addressFactory。createAddress(「sip:」+ username +'@'+ server); FromHeader fromHeader = this.headerFactory.createFromHeader(fromAddress, String.valueOf(this.tag));

  4. 創建To頭

    ToHeader toHeader = this.headerFactory.createToHeader(FROMADDRESS,NULL);

  5. 創建最大-Forwards頭

    MaxForwardsHeader maxForwardsHeader = this.headerFactory.createMaxForwardsHeader(70);

  6. 創建一個Via頭部

    ArrayList的viaHeaders =新的ArrayList(); ViaHeader viaHeader = this.headerFactory.createViaHeader(this.ip,this.port,「tcp」,null); viaHeaders.add(viaHeader);

  7. 創建聯繫報頭

    this.contactAddress = this.addressFactory.createAddress( 「SIP:」 + this.username + '@' + this.ip + 「運輸= TCP」);

    //創建用於所有SIP消息的聯繫人標題。 012.this.contactHeader = this.headerFactory.createContactHeader(contactAddress);

一旦創建了所有標題,就可以創建請求 本身。現在

request = this.messageFactory.createRequest("REGISTER sip:" + server + "SIP/2.0\r\n\r\n"); 
request.addHeader(callIdHeader); 
request.addHeader(cSeqHeader); 
request.addHeader(fromHeader); 
request.addHeader(toHeader); 
request.addHeader(maxForwardsHeader); 
request.addHeader(viaHeader); 
request.addHeader(contactHeader); 

該請求對象與所有必要的頭 創建,是時候發送請求。

inviteTid = sipProvider.getNewClientTransaction(request); // send the request out. 
inviteTid.sendRequest(); 

一旦請求被髮送成功的響應將被傳遞到 使用SIPListener的processResponse回調該應用程序。

public void processResponse(ResponseEvent responseEvent) { 
    int statusCode = responseEvent.getResponse().getStatusCode(); 
} 

代碼

public void register(Response response) { 
    try { 
    cseq++; 
    ArrayList viaHeaders = new ArrayList(); 
    ViaHeader viaHeader = this.headerFactory.createViaHeader(this.ip, 
    this.port, "tcp", null); 
    viaHeaders.add(viaHeader); 
    // The "Max-Forwards" header. 
    MaxForwardsHeader maxForwardsHeader = this.headerFactory 
    .createMaxForwardsHeader(70); 
    // The "Call-Id" header. 
    CallIdHeader callIdHeader = this.sipProvider.getNewCallId(); 
    // The "CSeq" header. 
    CSeqHeader cSeqHeader = this.headerFactory.createCSeqHeader(cseq, 
    "REGISTER"); 

    Address fromAddress = addressFactory.createAddress("sip:" 
    + username + '@' + server); 

    FromHeader fromHeader = this.headerFactory.createFromHeader(
    fromAddress, String.valueOf(this.tag)); 
    // The "To" header. 
    ToHeader toHeader = this.headerFactory.createToHeader(fromAddress, 
    null); 

    // this.contactHeader = this.headerFactory 
    // .createContactHeader(contactAddress); 

    request = this.messageFactory.createRequest("REGISTER sip:" 
    + server + " SIP/2.0\r\n\r\n"); 
    request.addHeader(callIdHeader); 
    request.addHeader(cSeqHeader); 
    request.addHeader(fromHeader); 
    request.addHeader(toHeader); 
    request.addHeader(maxForwardsHeader); 
    request.addHeader(viaHeader); 
    request.addHeader(contactHeader); 
    if (response != null) { 
    retry = true; 
    AuthorizationHeader authHeader = Utils.makeAuthHeader(headerFactory, response, 
    request, username, password); 
    request.addHeader(authHeader); 
    } 
    inviteTid = sipProvider.getNewClientTransaction(request); 
    // send the request out. 
    inviteTid.sendRequest(); 
    this.dialog = inviteTid.getDialog(); 
    // Send the request statelessly through the SIP provider. 
    //   this.sipProvider.sendRequest(request); 

    // Display the message in the text area. 
    logger.debug("Request sent:\n" + request.toString() + "\n\n"); 
    } catch (Exception e) { 
    // If an error occurred, display the error. 
    e.printStackTrace(); 
    logger.debug("Request sent failed: " + e.getMessage() + "\n"); 
    } 
} 

您還可以查看驗證here基準柱。 這裏,如果萬一鏈接乾涸,一片天的要點:

在SIP請求,如果服務器401代理 需要認證或401未經授權的響應,則意味着客戶端 有重播再次提出與MD5挑戰相同的請求。

客戶端應該使用響應頭中的nonce值 WWW-Authenticate。

WWW-Authenticate:Digest realm =「sip.linphone。組織」, 現時= 「JbAO1QAAAAA3aDI0AADMobiT7toAAAAA」,不透明= 「+ GNywA ==」, 算法MD5 =,QOP = 「權威性」

客戶端應該使用隨機數生成MD5挑戰,並重新做 原始請求與授權頭

步驟來創建MD5挑戰

  1. 創建使用用戶名+第一MD5哈希值「:」 +境界+「:」 +密碼

    String a1 = username +「:」+ realm +「:」+ password; String ha1 = toHexString(mdigest.digest(a1.getBytes()));

  2. 創建使用REQUEST_METHOD +第二MD5哈希「:」 + REQUEST_URI

    字符串A2 = request_method.toUpperCase()+ 「:」 + REQUEST_URI; String ha2 = toHexString(mdigest.digest(a2.getBytes()));

  3. 如果響應頭中的qop是「auth」,那麼使用步驟3a計算最終的MD5散列值,否則如果未定義或爲空,請參閱步驟 3b。

3a。創建使用HA1 +最後的MD5字符串「:」 +現時+「:」 + nonceCount +「:」 + cNonce +「:」 + QOP +「:」 + HA2

String finalStr = ha1 + ":" + nonce + ":" + nonceCount + ":" + cNonce + ":" + qop + ":" + ha2; 
String response = toHexString(mdigest.digest(finalStr.getBytes())); 

3B。創建使用HA1 +最後的MD5字符串「:」 +隨機數+「:」 + HA2

String finalStr = ha1 + ":" + nonce + ":" + ha2; 
String response = toHexString(mdigest.digest(finalStr.getBytes())); 
+0

當我嘗試從這篇文章使用的代碼我收到NPE 行: 'VIAHEADER VIAHEADER = this.headerFactory.createViaHeader(this.ip, this.port, 「TCP」,NULL);' – skywalker

+0

@ johndaw16你的headerFactory是否爲null?你必須創建它。例如:SipFactory sipFactory = SipFactory.getInstance(); sipFactory.setPathName( 「gov.nist」); headerFactory = sipFactory.createHeaderFactory(); – 11101101b

+0

'ViaHeader viaHeader = this.headerFactory.createViaHeader(this.ip,this.port,「tcp」,null)'最後一個參數應該是branchID字符串。試試這種方式。 – Bobzone

2

你可能也想看看它封裝了上述步驟ClientAuthenticationHelper類:見包裝GOV .nist.javax.sip.clientauthutils

我相信在代碼庫中有一個使用示例。