1

JAIN-SIP を使用して Asterisk サーバーに登録し、別の SIP ソフトフォンで通話を開始しています。アスタリスクについては、 http://www.raspberry-asterisk.org/のデフォルト構成を実行しており、いくつかの拡張機能 (SIP ユーザー) が追加されています。

REGISTER メッセージを Asterisk に送信すると、(Asterisk) サーバーは期待どおりに認証チャレンジを返します。私の問題は、このチャレンジに応答すると、アスタリスクが同じ認証を再度要求することです。2 番目の認証応答の後、最終的に受け入れられます。なぜこのように機能するのか理解できないので、非常に基本的な問題があるに違いないと思います。

コード例:

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; }
      };
    }
  }
}

実行すると、次のようになります。

Sent request:
REGISTER sip:192.168.1.171:5060 SIP/2.0
Call-ID: 6a1cb516446a3d66806d8750334b8d50@192.168.1.152
CSeq: 1 REGISTER
From: "2" <sip:2@asterisk>;tag=fgdfdf
To: "2" <sip:2@asterisk>
Max-Forwards: 5
Contact: "2" <sip:2@192.168.1.152: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:2@asterisk>;tag=fgdfdf
To: "2" <sip:2@asterisk>;tag=as42a729fa
Call-ID: 6a1cb516446a3d66806d8750334b8d50@192.168.1.152
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: 6a1cb516446a3d66806d8750334b8d50@192.168.1.152
CSeq: 2 REGISTER
From: "2" <sip:2@asterisk>;tag=fgdfdf
To: "2" <sip:2@asterisk>
Max-Forwards: 5
Contact: "2" <sip:2@192.168.1.152: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:2@asterisk>;tag=fgdfdf
To: "2" <sip:2@asterisk>;tag=as46d30f80
Call-ID: 6a1cb516446a3d66806d8750334b8d50@192.168.1.152
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: 6a1cb516446a3d66806d8750334b8d50@192.168.1.152
CSeq: 3 REGISTER
From: "2" <sip:2@asterisk>;tag=fgdfdf
To: "2" <sip:2@asterisk>
Max-Forwards: 5
Contact: "2" <sip:2@192.168.1.152: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:2@asterisk>;tag=fgdfdf
To: "2" <sip:2@asterisk>;tag=as46d30f80
Call-ID: 6a1cb516446a3d66806d8750334b8d50@192.168.1.152
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:2@192.168.1.152:5060>;expires=300
Date: Mon, 17 Feb 2014 20:27:02 GMT
Content-Length: 0

ご覧のとおり、401 Unauthorized が 2 回返されます。どちらの場合も、認証応答が含まれる REGISTER が再度送信されます。

だから私の質問は、なぜ認証が最初に受け入れられず、2回目に受け入れられるのですか? まったく同じコードで実行されます。

INVITE メッセージの送信に関して、少し似た問題があります。REGISTER に成功した後、INVITE を送信すると、Asterisk は再度認証するよう要求します。上記の MySIPListener コードはこれも処理し、必要な INVITE と認証応答を生成します。ただし、これで見つけたすべての例は、既に認証されているはずなので、常に直接招待が機能していることを示しています。おそらく同じ問題に関連していますか?

それで、私は何を間違っていますか?

4

1 に答える 1

0

最初の試行のリクエスト URI は、にsip:192.168.1.171:5060基づいてチャレンジ レスポンスを送信している間sip:192.168.1.171:5060;maddr=192.168.1.171であり、次の試行でのみ更新されます。

于 2014-02-17T23:03:04.630 に答える