2012-10-23 15 views
7

Ich arbeite mit der Jain Sip-Bibliothek und versuche, eine Verbindung zu einem Asterisk-Server herzustellen. Ich habe mit der Textclient-Beispiel-App von dieser Seite gearbeitet: http://www.oracle.com/technetwork/articles/entarch/introduction-jain-sip-090386.htmlJain-Sip-Authentifizierung

, aber das authentifiziert sich nicht tatsächlich mit dem Server. Ich kann Nachrichten an Benutzer auf dem Server senden, aber normalerweise benötige ich eine Benutzer-/Kennwortauthentifizierung auf dem Server.

Soweit ich das beurteilen kann, muss ich die Eigenschaft "javax.sip.OUTBOUND_PROXY" verwenden, aber ich kann keine Dokumentation finden, wie man einen Benutzernamen oder ein Passwort einstellt. Hat sonst noch jemand Erfolg damit gehabt?

Antwort

7

Das beste Beispiel habe ich besser dran, gefunden auf Registrierung wurde gefunden here. Hier ist der Kern, wenn nur für den Fall der Link-up trocknet einen Tag:

Register Anfrage verwendet wird, um den aktuellen Standort eines Benutzers auf der Registrar-Server zu aktualisieren. Die Anwendung sendet eine REGISTER-Nachricht informiert den Server seinen aktuellen Standort, die wiederum in Location Server gespeichert ist. Wenn ein Anrufer einen Benutzer anruft, verwendet der Proxy-Server diese Informationen, um den Standort des Angerufenen zu finden.

Registeranforderung sollte regelmäßig vom Client gesendet werden. Die Gültigkeit der REGISTER-Anfrage wird durch den Expires-Header bestimmt.

Fluss

image

Musteranfrage

REGISTER sip:sip.linphone.org SIP/2.0 
Call-ID: [email protected] 
CSeq: 1 REGISTER 
From: <sip:[email protected]>;tag=-1427592833 
To: <sip:[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 

kann nun sehen, wie die obige Anfrage mit den NIST SIP Stapeln zu konstruieren.

In einem ersten Schritt erstellen Sie eine Klasse, die den SIPListener implementiert. Machen Sie sicher, dass Ihr SIP-Stack NIST JAIN SIP Stack initialisiert.

  1. erstellen Call-ID-Header

    CallIdHeader callIdHeader = this.sipProvider.getNewCallId();

  2. erstellen CSeq Kopf

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

  3. Aus-Header erstellen

    Adresse FROMADDRESS = ADDRESS.createAddress ("sip:" + Benutzername + '@' + Server); FromHeader fromHeader = this.headerFactory.createFromHeader (fromAdresse, String.valueOf (this.tag));

  4. erstellen To-Header

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

  5. erstellen Max-Forwards Header

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

  6. Erstellen einer Viaheader

    Arraylist viaHeaders = new Arraylist(); ViaHeader viaHeader = this.headerFactory.createViaHeader (this.ip, this.port, "tcp", null); viaHeaders.add (viaHeader);

  7. Kontakt Header erstellen

    this.contactAddress = this.addressFactory.createAddress ("sip:" + this.username + '@' + this.ip + "transport = tcp");

    // Erstellen Sie den Kontaktkopf, der für alle SIP-Nachrichten verwendet wird. this.contactHeader = this.headerFactory.createContactHeader (Kontaktadresse);

Sobald alle Header erstellt werden, ist es Zeit, die Anfrage selbst zu erstellen.

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

Nun, da das Request-Objekt mit allen notwendigen Header erstellt wird, ist es Zeit, um die Anfrage zu senden.

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

Sobald die Anforderung erfolgreich gesendet wird, wird die Antwort auf übergeben werden, um die Anwendung des Process Rückruf in SIPListener verwenden.

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

-Code

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

Sie können auch die Referenz Post auf Authentifizierung here. Hier ist der Kern, wenn nur für den Fall des Link trocknet-up eines Tag:

Während einer SIP-Anfrage, wenn der Server antwortet mit 401 Proxy Authentifizierung erforderlich oder 401 Unauthorized dann bedeutet es, die Client hat replay die gleiche Anfrage erneut mit MD5-Challenge.

Der Client sollte Nonce-Wert aus dem Antwortheader WWW-Authenticate verwenden.

WWW-Authentifizierung: Digest realm = "sip.linphone.org“, nonce = "JbAO1QAAAAA3aDI0AADMobiT7toAAAAA", opak = "+ GNywA ==", Algorithmus = MD5, qop = "auth"

Der Kunde sollte nonce verwenden, um die MD5 Herausforderung zu erzeugen und die ursprüngliche Anforderung wieder machen mit dem Authorization-Header

Schritte des MD5-Challenge-

  1. erstellen ersten MD5-Hash + mit Benutzername zu erstellen. „:“ + Reich + „:“ + Passwort

    String a1 = Benutzername + ":" + Realm + ":" + Passwort; Zeichenfolge ha1 = toHexString (mdigest.digest (a1.getBytes()));

  2. Erstellen zweiten MD5 Hash unter Verwendung REQUEST_METHOD + „:“ + REQUEST_URI

    String a2 = request_method.toUpperCase() + ":" + REQUEST_URI; Zeichenfolge ha2 = toHexString (mdigest.digest (a2.getBytes()));

  3. Wenn Qop im Antwortheader "auth" ist, dann wird der endgültige MD5-Hash mit Schritt 3a berechnet, ansonsten, wenn er undefiniert oder leer ist, siehe Schritt 3b.

3a. Erstellen Sie die endgültige MD5-String mit HA1 + „:“ + nonce + „:“ + nonceCount + „:“ + cNonce + „:“ + qop + „:“ + HA2

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

3b. Erstellen Sie die endgültige MD5-String mit HA1 + „:“ + nonce + „:“ + HA2

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

Wenn ich versuche, den Code von diesem Posten zu verwenden, erhalte ich NPE line: 'ViaHeader viaHeader = this.headerFactory.createViaHeader (this.ip, this.port "tcp", null);' – skywalker

+0

@ johndaw16 ist deine headerFactory null? Sie müssen es erstellen. Zum Beispiel: SipFactory sipFactory = SipFactory.getInstance(); sipFactory.setPathName ("gov.nist"); headerFactory = sipFactory.createHeaderFactory(); – 11101101b

+0

'ViaHeader viaHeader = this.headerFactory.createViaHeader (this.ip, this.port," tcp ", null)' Der letzte Parameter sollte eine Verzweigungs-ID sein. Versuche es so. – Bobzone

2

Vielleicht haben Sie auch einen Blick auf die ClientAuthenticationHelper Klasse nehmen wollen, die die oben genannten Schritte kapselt: Das Paket gov .nist.javax.sip.clientauthutils

Ich glaube, es gibt ein Beispiel der Verwendung in der Codebasis.