2014-02-17 3 views
1

JAIN-SIP를 사용하여 Asterisk 서버에 등록하고 다른 SIP 소프트 폰과 통화를 시작합니다. Asterisk의 경우 일부 확장 (SIP 사용자)이 추가 된 http://www.raspberry-asterisk.org/의 기본 구성을 실행하고 있습니다.별표/JAIN-SIP 왜 여러 번 인증해야합니까?

Asterisk에 REGISTER 메시지를 보내면 (별표) 서버가 예상대로 인증 시도를 되돌려 보냅니다. 내 문제는 일단이 문제에 응답하면 Asterisk는 같은 인증을 다시 요구합니다. 두 번째 인증 응답 후에는 최종적으로 승인됩니다. 왜 이런 식으로 작동하는지 이해할 수 없으므로, 나는 아주 근본적으로 잘못된 것을 가지고 있어야한다고 생각합니다.

예제 코드 : 당신이 볼 수 있듯이

Sent request: 
REGISTER sip:192.168.1.171:5060 SIP/2.0 
Call-ID: [email protected] 
CSeq: 1 REGISTER 
From: "2" <sip:[email protected]>;tag=fgdfdf 
To: "2" <sip:[email protected]> 
Max-Forwards: 5 
Contact: "2" <sip:[email protected]:5060> 
Expires: 300 
Via: SIP/2.0/UDP 192.168.1.152:5060;branch=z9hG4bK-373634-2421c1e13c920e5a75f69f9a3f80f8d8 
Content-Length: 0 


Response received: 
SIP/2.0 401 Unauthorized 
Via: SIP/2.0/UDP 192.168.1.152:5060;branch=z9hG4bK-373634-2421c1e13c920e5a75f69f9a3f80f8d8;received=192.168.1.152 
From: "2" <sip:[email protected]>;tag=fgdfdf 
To: "2" <sip:[email protected]>;tag=as42a729fa 
Call-ID: [email protected] 
CSeq: 1 REGISTER 
Server: FPBX-2.11.0(11.6.0) 
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH 
Supported: replaces,timer 
WWW-Authenticate: Digest algorithm=MD5,realm="asterisk",nonce="5bdc425c" 
Content-Length: 0 


Sent request with authentication info: 
REGISTER sip:192.168.1.171:5060;maddr=192.168.1.171 SIP/2.0 
Call-ID: [email protected] 
CSeq: 2 REGISTER 
From: "2" <sip:[email protected]>;tag=fgdfdf 
To: "2" <sip:[email protected]> 
Max-Forwards: 5 
Contact: "2" <sip:[email protected]:5060> 
Expires: 300 
Via: SIP/2.0/UDP 192.168.1.152:5060;branch=z9hG4bK-373634-18fc265c4d5854f9a970d7545facd464 
Authorization: Digest username="2",realm="asterisk",nonce="5bdc425c",uri="sip:192.168.1.171:5060;maddr=192.168.1.171",response="6dc54ff9338920a9b6d7d8755ce719cc",algorithm=MD5 
Content-Length: 0 


Response received: 
SIP/2.0 401 Unauthorized 
Via: SIP/2.0/UDP 192.168.1.152:5060;branch=z9hG4bK-373634-18fc265c4d5854f9a970d7545facd464;received=192.168.1.152 
From: "2" <sip:[email protected]>;tag=fgdfdf 
To: "2" <sip:[email protected]>;tag=as46d30f80 
Call-ID: [email protected] 
CSeq: 2 REGISTER 
Server: FPBX-2.11.0(11.6.0) 
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH 
Supported: replaces,timer 
WWW-Authenticate: Digest algorithm=MD5,realm="asterisk",nonce="75ac799b" 
Content-Length: 0 


Sent request with authentication info: 
REGISTER sip:192.168.1.171:5060;maddr=192.168.1.171 SIP/2.0 
Call-ID: [email protected] 
CSeq: 3 REGISTER 
From: "2" <sip:[email protected]>;tag=fgdfdf 
To: "2" <sip:[email protected]> 
Max-Forwards: 5 
Contact: "2" <sip:[email protected]:5060> 
Expires: 300 
Via: SIP/2.0/UDP 192.168.1.152:5060;branch=z9hG4bK-373634-64f022399c1ad437b6fffa21782c9376 
Authorization: Digest username="2",realm="asterisk",nonce="75ac799b",uri="sip:192.168.1.171:5060;maddr=192.168.1.171",response="cd18746b954cfca05a65c04a23be4e77",algorithm=MD5 
Content-Length: 0 


Response received: 
SIP/2.0 200 OK 
Via: SIP/2.0/UDP 192.168.1.152:5060;branch=z9hG4bK-373634-64f022399c1ad437b6fffa21782c9376;received=192.168.1.152 
From: "2" <sip:[email protected]>;tag=fgdfdf 
To: "2" <sip:[email protected]>;tag=as46d30f80 
Call-ID: [email protected] 
CSeq: 3 REGISTER 
Server: FPBX-2.11.0(11.6.0) 
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH 
Supported: replaces,timer 
Expires: 300 
Contact: <sip:[email protected]:5060>;expires=300 
Date: Mon, 17 Feb 2014 20:27:02 GMT 
Content-Length: 0 

, 나는 두 번 다시 401 권한 얻을 : 나는 그것을 실행하면

package sip.test.example; 

import gov.nist.javax.sip.SipStackExt; 
import gov.nist.javax.sip.clientauthutils.*; 

import javax.sip.*; 
import javax.sip.address.*; 
import javax.sip.header.*; 
import javax.sip.message.*; 
import java.util.*; 

public class WhyDoesThisAuthenticateTwice { 
    private SipStackExt sipStack; 
    private HeaderFactory header; 
    private SipProvider udp; 
    private final String sipId = "2"; 
    private final String myIp = "192.168.1.152"; 
    private final int myPort = 5060; 
    private final String myPw = "password22"; 
    private final String realm = "asterisk"; 
    private final String asteriskIp = "192.168.1.171"; 
    private final int asteriskPort = 5060; 
    private final String tag = "fgdfdf"; 

    public static void main(String[] args) throws Exception { 
    new WhyDoesThisAuthenticateTwice().register(); 
    } 

    public void register() throws Exception { 
    SipFactory sipFactory = SipFactory.getInstance(); 
    sipFactory.setPathName("gov.nist"); 
    Properties properties = new Properties(); 

    properties.setProperty("javax.sip.STACK_NAME", "test-phone"); 
    properties.setProperty("javax.sip.OUTBOUND_PROXY", asteriskIp+":"+asteriskPort+"/udp"); 

    this.sipStack = (SipStackExt) sipFactory.createSipStack(properties); 
    header = sipFactory.createHeaderFactory(); 
    AddressFactory address = sipFactory.createAddressFactory(); 
    MessageFactory message = sipFactory.createMessageFactory(); 

    ListeningPoint udpPoint = sipStack.createListeningPoint(myIp, myPort, "udp"); 

    MySIPListener listener = new MySIPListener(); 

    udp = sipStack.createSipProvider(udpPoint); 
    udp.addSipListener(listener); 

    SipURI myRealmURI = address.createSipURI(sipId, realm); 
    Address fromAddress = address.createAddress(myRealmURI); 
    fromAddress.setDisplayName(sipId); 
    FromHeader fromHeader = header.createFromHeader(fromAddress, tag); 

    SipURI myURI = address.createSipURI(sipId, myIp); 
    myURI.setPort(myPort); 
    Address contactAddress = address.createAddress(myURI); 
    contactAddress.setDisplayName(sipId); 
    ContactHeader contactHeader = header.createContactHeader(contactAddress); 

    MaxForwardsHeader maxForwards = header.createMaxForwardsHeader(5); 

    List<ViaHeader> viaHeaders = new ArrayList<>(); 
    CallIdHeader callIdHeader = udp.getNewCallId(); 
    long seq = 1; 
    CSeqHeader cSeqHeader = header.createCSeqHeader(seq++, Request.REGISTER); 
    ToHeader toHeader = header.createToHeader(fromAddress, null); 
    URI requestURI = address.createURI("sip:"+asteriskIp+":"+asteriskPort); 

    Request request = message.createRequest(requestURI, Request.REGISTER, callIdHeader, 
      cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwards); 
    request.addHeader(contactHeader); 
    ExpiresHeader eh = header.createExpiresHeader(300); 
    request.addHeader(eh); 
    ClientTransaction transaction = udp.getNewClientTransaction(request); 
    transaction.sendRequest(); 
    System.out.println("Sent request:"); 
    System.out.println(request); 
    } 

    private class MySIPListener implements SipListener { 
    @Override 
    public void processRequest(RequestEvent requestEvent) {} 
    @Override 
    public void processResponse(ResponseEvent event) { 
     try { 
     Response response = event.getResponse(); 
     System.out.println("Response received:"); 
     System.out.println(response); 
     if (response.getStatusCode() != 401) return; 
     ClientTransaction tid = event.getClientTransaction(); 
     AccountManagerImpl manager = new AccountManagerImpl(); 
     AuthenticationHelper helper = sipStack.getAuthenticationHelper(manager, header); 
     ClientTransaction transaction = helper.handleChallenge(response, tid, udp, 5); 
     transaction.sendRequest(); 
     Request request = transaction.getRequest(); 
     System.out.println("Sent request with authentication info:"); 
     System.out.println(request); 
     } catch (SipException e) { e.printStackTrace(); } 
    } 

    @Override 
    public void processTimeout(TimeoutEvent timeoutEvent) {} 
    @Override 
    public void processIOException(IOExceptionEvent exceptionEvent) {} 
    @Override 
    public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {} 
    @Override 
    public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {} 
    } 

    private class AccountManagerImpl implements AccountManager { 
    @Override 
    public UserCredentials getCredentials(ClientTransaction clientTransaction, String s) { 
     return new UserCredentials() { 
     @Override 
     public String getUserName() { return sipId; } 
     @Override 
     public String getPassword() { return myPw; } 
     @Override 
     public String getSipDomain() { return realm; } 
     }; 
    } 
    } 
} 

, 이것은 내가 무엇을 얻을 수 있습니다. 두 번 모두 REGISTER는 인증 응답을 포함하여 다시 전송됩니다.

내 질문에, 왜 처음에는 인증이 받아 들여지지 않지만 두 번째는 받아 들여지지 않습니까? 정확히 동일한 코드로 수행됩니다.

INVITE 메시지를 보내는 데 약간 비슷한 문제가 있습니다. 성공적으로 REGISTER를 수행 한 후, INVITE를 보내면 Asterisk는 다시 인증을 받아야합니다. 위의 MySIPListener 코드는이 코드도 처리하고 인증 응답과 함께 필수 INVITE를 생성합니다. 그러나이 예제에서 발견 한 모든 예제는 직접 인증을 받아야하기 때문에 항상 직접 초대를 보여줍니다. 아마도 같은 문제와 관련이 있을까요?

그래서 내가 뭘 잘못하고 있니?

답변

0

sip:192.168.1.171:5060;maddr=192.168.1.171에 기반하여 요청 응답을 제출하는 동안 첫 번째 시도의 요청 URI는 sip:192.168.1.171:5060이며 그 요청은 다음 시도에서만 업데이트됩니다.

+0

좋습니다. 감사합니다. 첫 번째 URI에 maddr = 192.168.1.171을 추가하면이 문제가 해결되었습니다. JAIN-SIP의 AuthenticationHelper 클래스가 항상 거기에 추가되어서 거기에 maddr 매개 변수를 넣지 않으면 사용할 수없는 것처럼 보입니다. 이제 내 INVITE가 왜 똑같이되지만 다른 문제인지 파악해야합니다. –

관련 문제