2011-03-15 20 views
10

Estoy tratando de hacer un chat de Facebook en Android con la biblioteca Smack. He leído el Chat API de Facebook, pero no puedo entender cómo tengo que autenticarme con Facebook usando esta biblioteca.XMPP con biblioteca Java Asmack compatible con X-FACEBOOK-PLATFORM

¿Alguien me puede decir cómo lograr esto?

Actualización: Según la respuesta no.good.at.coding, tengo este código adaptado a la biblioteca Asmack. Todo funciona bien excepto que recibo como respuesta al inicio de sesión: no autorizado. Aquí está el código que utilizo:

public class SASLXFacebookPlatformMechanism extends SASLMechanism 
{ 

    private static final String NAME    = "X-FACEBOOK-PLATFORM"; 

    private String    apiKey   = ""; 
    private String    applicationSecret = ""; 
    private String    sessionKey  = ""; 

    /** 
    * Constructor. 
    */ 
    public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication) 
    { 
     super(saslAuthentication); 
    } 

    @Override 
    protected void authenticate() throws IOException, XMPPException 
    { 

     getSASLAuthentication().send(new AuthMechanism(NAME, "")); 
    } 

    @Override 
    public void authenticate(String apiKeyAndSessionKey, String host, 
      String applicationSecret) throws IOException, XMPPException 
    { 
     if (apiKeyAndSessionKey == null || applicationSecret == null) 
     { 
      throw new IllegalArgumentException("Invalid parameters"); 
     } 

     String[] keyArray = apiKeyAndSessionKey.split("\\|", 2); 
     if (keyArray.length < 2) 
     { 
      throw new IllegalArgumentException(
        "API key or session key is not present"); 
     } 

     this.apiKey = keyArray[0]; 
     Log.d("API_KEY", apiKey); 
     this.applicationSecret = applicationSecret; 
     Log.d("SECRET_KEY", applicationSecret); 
     this.sessionKey = keyArray[1]; 
     Log.d("SESSION_KEY", sessionKey); 

     this.authenticationId = sessionKey; 
     this.password = applicationSecret; 
     this.hostname = host; 

     String[] mechanisms = { "DIGEST-MD5" }; 
     Map<String, String> props = new HashMap<String, String>(); 
     this.sc = 
       Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, 
         this); 
     authenticate(); 
    } 

    @Override 
    protected String getName() 
    { 
     return NAME; 
    } 

    @Override 
    public void challengeReceived(String challenge) throws IOException 
    { 
     byte[] response = null; 

     if (challenge != null) 
     { 
      String decodedChallenge = new String(Base64.decode(challenge)); 
      Log.d("DECODED", decodedChallenge); 
      Map<String, String> parameters = getQueryMap(decodedChallenge); 

      String version = "1.0"; 
      String nonce = parameters.get("nonce"); 
      String method = parameters.get("method"); 

      long callId = new GregorianCalendar().getTimeInMillis()/1000L; 

      String sig = 
        "api_key=" + apiKey + "call_id=" + callId + "method=" 
          + method + "nonce=" + nonce + "session_key=" 
          + sessionKey + "v=" + version + applicationSecret; 

      try 
      { 
       sig = md5(sig); 
       sig = sig.toUpperCase(); 
      } catch (NoSuchAlgorithmException e) 
      { 
       throw new IllegalStateException(e); 
      } 

      String composedResponse = 
        "api_key=" + URLEncoder.encode(apiKey, "utf-8") 
          + "&call_id=" + callId + "&method=" 
          + URLEncoder.encode(method, "utf-8") + "&nonce=" 
          + URLEncoder.encode(nonce, "utf-8") 
          + "&session_key=" 
          + URLEncoder.encode(sessionKey, "utf-8") + "&v=" 
          + URLEncoder.encode(version, "utf-8") + "&sig=" 
          + URLEncoder.encode(sig, "utf-8"); 

      Log.d("COMPOSED", composedResponse); 

      response = composedResponse.getBytes("utf-8"); 
     } 

     String authenticationText = ""; 

     if (response != null) 
     { 
      authenticationText = 
        Base64.encodeBytes(response, Base64.DONT_BREAK_LINES); 
     } 

     // Send the authentication to the server 
     getSASLAuthentication().send(new Response(authenticationText)); 
    } 

    private Map<String, String> getQueryMap(String query) 
    { 
     Map<String, String> map = new HashMap<String, String>(); 
     String[] params = query.split("\\&"); 

     for (String param : params) 
     { 
      String[] fields = param.split("=", 2); 
      map.put(fields[0], (fields.length > 1 ? fields[1] : null)); 
     } 

     return map; 
    } 

    private String md5(String text) throws NoSuchAlgorithmException, 
      UnsupportedEncodingException 
    { 
     MessageDigest md = MessageDigest.getInstance("MD5"); 
     md.update(text.getBytes("utf-8"), 0, text.length()); 
     return convertToHex(md.digest()); 
    } 

    private String convertToHex(byte[] data) 
    { 
     StringBuilder buf = new StringBuilder(); 
     int len = data.length; 

     for (int i = 0; i < len; i++) 
     { 
      int halfByte = (data[i] >>> 4) & 0xF; 
      int twoHalfs = 0; 

      do 
      { 
       if (0 <= halfByte && halfByte <= 9) 
       { 
        buf.append((char) ('0' + halfByte)); 
       } 
       else 
       { 
        buf.append((char) ('a' + halfByte - 10)); 
       } 
       halfByte = data[i] & 0xF; 
      } while (twoHalfs++ < 1); 
     } 

     return buf.toString(); 
    } 
} 

Y esto, es la comunicación con el servidor con los mensajes enviados y recibidos:

PM SENT (1132418216): <stream:stream to="chat.facebook.com" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0"> 


PM RCV (1132418216): <?xml version="1.0"?><stream:stream id="C62D0F43" from="chat.facebook.com" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xml:lang="en"><stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-FACEBOOK-PLATFORM</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features> 


PM SENT (1132418216): <auth mechanism="X-FACEBOOK-PLATFORM" xmlns="urn:ietf:params:xml:ns:xmpp-sasl"></auth> 


PM RCV (1132418216): <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dmVyc2lvbj0xJm1ldGhvZD1hdXRoLnhtcHBfbG9naW4mbm9uY2U9NzFGNkQ3Rjc5QkIyREJCQ0YxQTkwMzA0QTg3OTlBMzM=</challenge> 


PM SENT (1132418216): <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">YXBpX2tleT0zMWYzYjg1ZjBjODYwNjQ3NThiZTZhOTQyNjVjZmNjMCZjYWxsX2lkPTEzMDA0NTYxMzUmbWV0aG9kPWF1dGgueG1wcF9sb2dpbiZub25jZT03MUY2RDdGNzlCQjJEQkJDRjFBOTAzMDRBODc5OUEzMyZzZXNzaW9uX2tleT0yNjUzMTg4ODNkYWJhOGRlOTRiYTk4ZDYtMTAwMDAwNTAyNjc2Nzc4JnY9MS4wJnNpZz04RkRDRjRGRTgzMENGOEQ3QjgwNjdERUQyOEE2RERFQw==</response> 


PM RCV (1132418216): <failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure> 

Como se lee en el developers Facebook forum, es necesario desactivar el " Desactive la configuración de "Métodos de autenticación en desuso" en la página de configuración de Facebook de su aplicación. Pero, incluso haciendo eso, no puedo iniciar sesión. Y la clave de sesión es la segunda parte del token de OAuth en el formato AAA | BBB | CCC, quiero decir, BBB.

+0

java.security.KeyStoreException: aplicación de KeyStore jks no encontrado –

+1

no utilice it.Facebook de chat XMPP no estará disponible a partir de abril de 2015. 30o https://developers.facebook.com/docs/apps/changelog –

Respuesta

14

Por último, gracias al código no.good.at.coding y la sugerencia de harism, he sido capaz de conectarse al chat de Facebook. Este código es el mecanismo para la biblioteca Asmack (el puerto Smack para Android). Para la biblioteca Smack es necesario utilizar el mecanismo no.good.at.coding.

SASLXFacebookPlatformMechanism.java:

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.net.URLEncoder; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.util.GregorianCalendar; 
import java.util.HashMap; 
import java.util.Map; 

import org.apache.harmony.javax.security.auth.callback.CallbackHandler; 
import org.apache.harmony.javax.security.sasl.Sasl; 
import org.jivesoftware.smack.SASLAuthentication; 
import org.jivesoftware.smack.XMPPException; 
import org.jivesoftware.smack.sasl.SASLMechanism; 
import org.jivesoftware.smack.util.Base64; 

public class SASLXFacebookPlatformMechanism extends SASLMechanism 
{ 

    private static final String NAME    = "X-FACEBOOK-PLATFORM"; 

    private String    apiKey   = ""; 
    private String    applicationSecret = ""; 
    private String    sessionKey  = ""; 

    /** 
    * Constructor. 
    */ 
    public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication) 
    { 
     super(saslAuthentication); 
    } 

    @Override 
    protected void authenticate() throws IOException, XMPPException 
    { 

     getSASLAuthentication().send(new AuthMechanism(NAME, "")); 
    } 

    @Override 
    public void authenticate(String apiKeyAndSessionKey, String host, 
      String applicationSecret) throws IOException, XMPPException 
    { 
     if (apiKeyAndSessionKey == null || applicationSecret == null) 
     { 
      throw new IllegalArgumentException("Invalid parameters"); 
     } 

     String[] keyArray = apiKeyAndSessionKey.split("\\|", 2); 
     if (keyArray.length < 2) 
     { 
      throw new IllegalArgumentException(
        "API key or session key is not present"); 
     } 

     this.apiKey = keyArray[0]; 
     this.applicationSecret = applicationSecret; 
     this.sessionKey = keyArray[1]; 

     this.authenticationId = sessionKey; 
     this.password = applicationSecret; 
     this.hostname = host; 

     String[] mechanisms = { "DIGEST-MD5" }; 
     Map<String, String> props = new HashMap<String, String>(); 
     this.sc = 
       Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, 
         this); 
     authenticate(); 
    } 

    @Override 
    public void authenticate(String username, String host, CallbackHandler cbh) 
      throws IOException, XMPPException 
    { 
     String[] mechanisms = { "DIGEST-MD5" }; 
     Map<String, String> props = new HashMap<String, String>(); 
     this.sc = 
       Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, 
         cbh); 
     authenticate(); 
    } 

    @Override 
    protected String getName() 
    { 
     return NAME; 
    } 

    @Override 
    public void challengeReceived(String challenge) throws IOException 
    { 
     byte[] response = null; 

     if (challenge != null) 
     { 
      String decodedChallenge = new String(Base64.decode(challenge)); 
      Map<String, String> parameters = getQueryMap(decodedChallenge); 

      String version = "1.0"; 
      String nonce = parameters.get("nonce"); 
      String method = parameters.get("method"); 

      long callId = new GregorianCalendar().getTimeInMillis(); 

      String sig = 
        "api_key=" + apiKey + "call_id=" + callId + "method=" 
          + method + "nonce=" + nonce + "session_key=" 
          + sessionKey + "v=" + version + applicationSecret; 

      try 
      { 
       sig = md5(sig); 
      } catch (NoSuchAlgorithmException e) 
      { 
       throw new IllegalStateException(e); 
      } 

      String composedResponse = 
        "api_key=" + URLEncoder.encode(apiKey, "utf-8") 
          + "&call_id=" + callId + "&method=" 
          + URLEncoder.encode(method, "utf-8") + "&nonce=" 
          + URLEncoder.encode(nonce, "utf-8") 
          + "&session_key=" 
          + URLEncoder.encode(sessionKey, "utf-8") + "&v=" 
          + URLEncoder.encode(version, "utf-8") + "&sig=" 
          + URLEncoder.encode(sig, "utf-8"); 

      response = composedResponse.getBytes("utf-8"); 
     } 

     String authenticationText = ""; 

     if (response != null) 
     { 
      authenticationText = 
        Base64.encodeBytes(response, Base64.DONT_BREAK_LINES); 
     } 

     // Send the authentication to the server 
     getSASLAuthentication().send(new Response(authenticationText)); 
    } 

    private Map<String, String> getQueryMap(String query) 
    { 
     Map<String, String> map = new HashMap<String, String>(); 
     String[] params = query.split("\\&"); 

     for (String param : params) 
     { 
      String[] fields = param.split("=", 2); 
      map.put(fields[0], (fields.length > 1 ? fields[1] : null)); 
     } 

     return map; 
    } 

    private String md5(String text) throws NoSuchAlgorithmException, 
      UnsupportedEncodingException 
    { 
     MessageDigest md = MessageDigest.getInstance("MD5"); 
     md.update(text.getBytes("utf-8"), 0, text.length()); 
     return convertToHex(md.digest()); 
    } 

    private String convertToHex(byte[] data) 
    { 
     StringBuilder buf = new StringBuilder(); 
     int len = data.length; 

     for (int i = 0; i < len; i++) 
     { 
      int halfByte = (data[i] >>> 4) & 0xF; 
      int twoHalfs = 0; 

      do 
      { 
       if (0 <= halfByte && halfByte <= 9) 
       { 
        buf.append((char) ('0' + halfByte)); 
       } 
       else 
       { 
        buf.append((char) ('a' + halfByte - 10)); 
       } 
       halfByte = data[i] & 0xF; 
      } while (twoHalfs++ < 1); 
     } 

     return buf.toString(); 
    } 
} 

utilizarlo:

ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222); 
config.setSASLAuthenticationEnabled(true); 
XMPPConnection xmpp = new XMPPConnection(config); 
try 
{ 
    SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM", SASLXFacebookPlatformMechanism.class); 
    SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0); 
    xmpp.connect(); 
    xmpp.login(apiKey + "|" + sessionKey, sessionSecret, "Application"); 
} catch (XMPPException e) 
{ 
    xmpp.disconnect(); 
    e.printStackTrace(); 
} 

apikey es la clave de la API dado en la página de configuración de la aplicación en Facebook. sessionKey es la segunda parte del token de acceso. Si el token está en esta forma, AAA | BBB | CCC, BBB es la clave de sesión. sessionSecret se obtiene utilizando la antigua API REST con el método auth.promoteSession. Para usarlo, se necesita hacer un HTTP GET a la siguiente dirección:

https://api.facebook.com/method/auth.promoteSession?access_token=yourAccessToken

A pesar de la documentación Facebook Chat dice que se necesita para usar su clave secreta aplicación, sólo cuando utilicé la llave que regresó esa Método REST Pude hacer que funcione. Para que ese método funcione, debe desactivar la opción Deshabilitar métodos de autenticación en desuso en la ficha Avanzado en la configuración de la aplicación.

+0

Gracias por su respuesta. ¿A qué access_token te estás refiriendo? Mi token de acceso, obtenido usando el Facebook Graph SDK para Android, no tiene ningún canal, así que no estoy seguro de cómo obtener la clave de sesión. Traté de usar todo access_token, pero recibo una excepción XMPP que no estoy autenticado. –

+0

No sé cómo se parece a su token de acceso, pero intente utilizar URLDecoder.decode (access_token). Quizás ahora puedas ver las tuberías. – Adrian

+1

De acuerdo, estoy bastante seguro de que funcionó. Todo lo que tuve que hacer fue esto: xmpp.login (, sessionSecret, "Application"); ¡Muchas gracias! ¡Gran código, voto! –

0

¿Qué desea hacer?

Si solo desea iniciar sesión en el chat FB, se conecta a FB al igual que cualquier otro servidor XMPP.

Me gustaría ver y utilizar "Autenticación con Nombre de usuario/Contraseña" de Chat API, que es compatible con Smack. A menos que me gustaría escribir una aplicación FaceBook. Luego, intentaré iniciar sesión con "Autenticación con la plataforma de Facebook".

Por lo tanto, simplemente utilice Smack para conectarse al chat FB como lo haría con su cliente Jabber normal.

  1. Para el nombre de usuario, utilice su nombre de usuario de Facebook . (Ver http://www.facebook.com/username/)
  2. para el dominio, uso: chat.facebook.com
  3. Para la contraseña, utilice la contraseña de Facebook
  4. Turn off SSL y TSL
  5. conjunto conectarse a puerto : (que es el valor predeterminado para XMPP)
  6. conjunto conectarse a servidores chat.facebook.com
+0

Gracias por su respuesta. La API de Facebook Chat dice que si su aplicación (estoy programando un cliente de Facebook) tiene una ID de aplicación de Facebook, debe usar la otra autenticación de chat (X-FACEBOOK-PLATFORM). Esa es la razón por la que no uso el mecanismo DIGEST-MD5. ¿Sabes cómo soportar la X-FACEBOOK-PLATFORM en Smack? – Adrian

+1

Lo siento, soy más un programador de cliente XMPP :) Así que no lo he intentado. Pero como escribió, si escribe un cliente de FB, debe usar 'X-FACEBOOK-PLATFORM', ya que sus usuarios no deberían tener que iniciar sesión una vez más desde la página web cuando usan su aplicación. Hay una nueva versión de Smack en el camino que se ha actualizado y debería solucionar algunos errores que podrían ser un problema para usted. Algunos de ellos han sido arreglados por asmack. Se examinaría en 'no.goog.at.solución de codificación, ya que lo consiguió trabajando en un punto. ;-) – Anders

4

Lo había usado hace unos 6 meses con Smack (no asmack) así que no estoy seguro de cómo va a aguantar ahora, pero aquí va, ¡espero que ayude!

Encontré una implementación del mecanismo de autenticación X-FACEBOOK-PLATFORM de Facebook en el Ignite Realtime Smack forum donde alguien lo obtuvo del fbgc project. Encontrarás un ZIP con la fuente SASLXFacebookPlatformMechanism.java en la respuesta a la que me he vinculado. Puede usarlo de la siguiente manera:

public void login() throws XMPPException 
{ 
    SASLAuthentication.registerSASLMechanism(SASLXFacebookPlatformMechanism.NAME, 
      SASLXFacebookPlatformMechanism.class); 
    SASLAuthentication.supportSASLMechanism(SASLXFacebookPlatformMechanism.NAME, 0); 

    ConnectionConfiguration connConfig = new ConnectionConfiguration(host, port); 

    XMPPConnection connection = new XMPPConnection(connConfig); 
    connection.connect(); 
    log.info("XMPP client connected"); 

    connection.login(Utils.FB_APP_ID + "|" + this.user.sessionId, Utils.FB_APP_SECRET, "app_name"); 
    log.info("XMPP client logged in"); 
} 

Estaba haciendo esto en el servidor sin un SDK.No recuerdo los detalles (y la documentación de Facebook no es muy buena) pero por lo que puedo decir de mi código, después de lograr que el usuario autorice la aplicación, recibo una solicitud de devolución de llamada de Facebook con un parámetro code. Abro un URLConnection al https://graph.facebook.com/oauth/access_token?client_id=<app_id>&redirect_uri=http://myserver/context/path/&client_secret=<app_secret>&code=<code>. La respuesta debe ser el token de acceso donde la identificación de sesión es la parte después del | - algo del formulario XXX|<sessionId>.

3

Este es el código que he estado utilizando con éxito para la autenticación. Tal vez esto ayude a pesar de que esto no está relacionado con Smack de ninguna manera. Puedes obtener sessionKey del token de acceso recibido de FB, y para obtener sessionSecret he estado usando la antigua API REST;

http://developers.facebook.com/docs/reference/rest/auth.promoteSession/

private final void processChallenge(XmlPullParser parser, Writer writer, 
     String sessionKey, String sessionSecret) throws IOException, 
     NoSuchAlgorithmException, XmlPullParserException { 

    parser.require(XmlPullParser.START_TAG, null, "challenge"); 
    String challenge = new String(Base64.decode(parser.nextText(), 
      Base64.DEFAULT)); 

    String params[] = challenge.split("&"); 
    HashMap<String, String> paramMap = new HashMap<String, String>(); 
    for (int i = 0; i < params.length; ++i) { 
     String p[] = params[i].split("="); 
     p[0] = URLDecoder.decode(p[0]); 
     p[1] = URLDecoder.decode(p[1]); 
     paramMap.put(p[0], p[1]); 
    } 

    String api_key = "YOUR_API_KEY"; 
    String call_id = "" + System.currentTimeMillis(); 
    String method = paramMap.get("method"); 
    String nonce = paramMap.get("nonce"); 
    String v = "1.0"; 

    StringBuffer sigBuffer = new StringBuffer(); 
    sigBuffer.append("api_key=" + api_key); 
    sigBuffer.append("call_id=" + call_id); 
    sigBuffer.append("method=" + method); 
    sigBuffer.append("nonce=" + nonce); 
    sigBuffer.append("session_key=" + sessionKey); 
    sigBuffer.append("v=" + v); 
    sigBuffer.append(sessionSecret); 

    MessageDigest md = MessageDigest.getInstance("MD5"); 
    md.update(sigBuffer.toString().getBytes()); 
    byte[] digest = md.digest(); 

    StringBuffer sig = new StringBuffer(); 
    for (int i = 0; i < digest.length; ++i) { 
     sig.append(Integer.toHexString(0xFF & digest[i])); 
    } 

    StringBuffer response = new StringBuffer(); 
    response.append("api_key=" + URLEncoder.encode(api_key)); 
    response.append("&call_id=" + URLEncoder.encode(call_id)); 
    response.append("&method=" + URLEncoder.encode(method)); 
    response.append("&nonce=" + URLEncoder.encode(nonce)); 
    response.append("&session_key=" + URLEncoder.encode(sessionKey)); 
    response.append("&v=" + URLEncoder.encode(v)); 
    response.append("&sig=" + URLEncoder.encode(sig.toString())); 

    StringBuilder out = new StringBuilder(); 
    out.append("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"); 
    out.append(Base64.encodeToString(response.toString().getBytes(), 
      Base64.NO_WRAP)); 
    out.append("</response>"); 

    writer.write(out.toString()); 
    writer.flush(); 
} 
+0

¡Gracias! ¡Ese método REST hizo el truco! Estaba usando la clave secreta que tengo en la página de configuración de mi aplicación, pero cuando probé el resultado de ese método, la clave de sesión comenzó a funcionar. Como voy a poner el código que funciona con la biblioteca Asmack/Smack, no marcaré su respuesta como aceptada, pero la he votado. Realmente te agradezco tu sugerencia. – Adrian

1

lo siento para hacer nueva respuesta pero tenía que incluir el nuevo código @YShinkarev lo siento por llegar tarde
Mediante la modificación de la respuesta @Adrian hacer challengeReceived podemos utilizar apikey y accessToken todo lo modificado fue el composedResponse

@Override 
public void challengeReceived(String challenge) throws IOException { 
    byte[] response = null; 

    if (challenge != null) { 
     String decodedChallenge = new String(Base64.decode(challenge)); 
     Map<String, String> parameters = getQueryMap(decodedChallenge); 

     String version = "1.0"; 
     String nonce = parameters.get("nonce"); 
     String method = parameters.get("method"); 

     long callId = new GregorianCalendar().getTimeInMillis(); 

     String composedResponse = "api_key=" 
       + URLEncoder.encode(apiKey, "utf-8") + "&call_id=" + callId 
       + "&method=" + URLEncoder.encode(method, "utf-8") 
       + "&nonce=" + URLEncoder.encode(nonce, "utf-8") 
       + "&access_token=" 
       + URLEncoder.encode(access_token, "utf-8") + "&v=" 
       + URLEncoder.encode(version, "utf-8"); 

     response = composedResponse.getBytes("utf-8"); 
    } 

    String authenticationText = ""; 

    if (response != null) { 
     authenticationText = Base64.encodeBytes(response, 
       Base64.DONT_BREAK_LINES); 
    } 

    // Send the authentication to the server 
    getSASLAuthentication().send(new Response(authenticationText)); 
} 
Cuestiones relacionadas