2013-03-20 52 views
11

我在我的聊天應用程序中使用GoogleTalk XMPP。無法通過使用用戶名和AuthToken與Google authentication創建XMPP連接。使用機制X-OAUTH2的Gtalk XMPP SASL認證失敗?

現在我使用GoogleAuth2代替authentication。我嘗試使用access_token和電子郵件進行身份驗證。通過使用SASLMechanism。但我不能夠連接到XMPP SERV 呃,它給錯誤這樣SASL authentication failed using mechanism X-OAUTH2

ConnectionConfiguration config = new ConnectionConfiguration(server_host, SERVER_PORT, SERVICE_NAME); 
config.setSASLAuthenticationEnabled(true); 
m_connection = new XMPPConnection(config); 

SASLAuthentication.registerSASLMechanism("X-OAUTH2", GoogleConnectSASLMechanism.class); 
SASLAuthentication.supportSASLMechanism("X-OAUTH2", 0); 

config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled); 
try {   
    m_connection.connect();  
} catch (XMPPException e) {   
    e.printStackTrace(); 
} 

這是類我使用SASLMechanism.

public class GoogleConnectSASLMechanism extends SASLMechanism { 

public static final String NAME = "X-OAUTH2"; 

private String username = ""; 
private String sessionKey = ""; 

public GoogleConnectSASLMechanism(SASLAuthentication saslAuthentication) { 
    super(saslAuthentication); 
} 

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

static void enable() { 
} 

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

    final StringBuilder stanza = new StringBuilder(); 
    byte response[] = null; 

    stanza.append("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"" + 
      "mechanism=\"X-OAUTH2\"" + 
      "auth:service=\"oauth2\"" + 
      "xmlns:auth= \"http://www.google.com/talk/protocol/auth\">"); 

    String composedResponse = "\0" + username + "\0" + sessionKey; 
    response = composedResponse.getBytes("UTF-8"); 
    String authenticationText = ""; 
    if (response != null) { 
     authenticationText = Base64.encodeBytes(response, Base64.DONT_BREAK_LINES); 
    } 

    stanza.append(authenticationText); 
    stanza.append("</auth>"); 

    // Send the authentication to the server 
    Packet p=new Packet() { 
     @Override 
     public String toXML() { 
      return stanza.toString(); 
     } 
    }; 
    getSASLAuthentication().send(p); 
} 

public class Auth2Mechanism extends Packet { 
    String stanza; 

    public Auth2Mechanism(String txt) { 
     stanza = txt; 
    } 

    public String toXML() { 
     return stanza; 
    } 
} 

/** 
* Initiating SASL authentication by select a mechanism. 
*/ 
public class AuthMechanism extends Packet { 
    final private String name; 
    final private String authenticationText; 

    public AuthMechanism(String name, String authenticationText) { 
     if (name == null) { 
      throw new NullPointerException(
        "SASL mechanism name shouldn't be null."); 
     } 
     this.name = name; 
     this.authenticationText = authenticationText; 
    } 

    public String toXML() { 
     StringBuilder stanza = new StringBuilder(); 
     stanza.append("<auth mechanism=\"").append(name); 
     stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"); 
     if (authenticationText != null 
       && authenticationText.trim().length() > 0) { 
      stanza.append(authenticationText); 
     } 
     stanza.append("</auth>"); 
     return stanza.toString(); 
    } 
} 
} 

如何使用SASL的Google Auth認證機制?

回答

6

下面是使用OAUTH2令牌爲我工作的版本。 OAUTH2範圍是https://www.googleapis.com/auth/googletalk

此代碼使用Smack XMPP庫。

的OAuth2用戶身份驗證機制:

import java.io.IOException; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.logging.Logger; 

import 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 SALSGTalkOauthMechanism extends SASLMechanism { 
    private static final Logger log = Logger.getLogger(SALSGTalkOauthMechanism.class.getName()); 
    public static final String NAME = "X-OAUTH2"; 


    /** 
    * Constructor. 
    */ 
    public SALSGTalkOauthMechanism(SASLAuthentication saslAuthentication) { 
      super(saslAuthentication); 
      log.info("Creating SASL mechanism for GTalk (X-OAUTH2)"); 
    } 

    @Override 
    public void authenticate(String username, String host, String accessToken) throws IOException, XMPPException { 
     this.hostname = host; 

     log.info("Authenticating to host "+host+" with key "+username); 

     String[] mechanisms = { "X-OAUTH2" }; 
     Map<String, String> props = new HashMap<String, String>(); 
     this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this); 
     getSASLAuthentication().send(new AuthMechanism(getName(), Base64.encodeBytes(('\0'+username+'\0'+accessToken).getBytes()))); 
    } 

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

    } 

和代碼,使其協同工作:

import org.jivesoftware.smack.Chat; 
import org.jivesoftware.smack.ChatManager; 
import org.jivesoftware.smack.Connection; 
import org.jivesoftware.smack.ConnectionConfiguration; 
import org.jivesoftware.smack.SASLAuthentication; 
import org.jivesoftware.smack.XMPPConnection; 
import org.jivesoftware.smack.packet.Message; 
import org.jivesoftware.smack.packet.Presence; 

import revevol.applications.cloudpulse.client.Probe; 
import revevol.applications.cloudpulse.client.ProbeClient; 
import revevol.applications.cloudpulse.client.ProbeClientUtils; 

import com.google.api.client.auth.oauth2.Credential; 

public class GTalkProbe implements Probe { 
    private static final Logger log = Logger.getLogger(GTalkProbe.class.getName()); 
    public static final String PROBE_GTALK_IDENTIFIER = "gtalkprobe"; 

    @Override 
    public void run(ProbeClient client, Properties properties) throws Exception { 
     log.info("Start running GTalkProbe."); 
     long startTimestamp = new Date().getTime(); 
     Exception exception = null; 
     MessageReboundResult result = new MessageReboundResult(); 
     Connection conn1 = null; 

     try { 
      Credential credential = ProbeClientUtils.getOAuth2Credentials(properties); 

      ConnectionConfiguration config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com"); 
      config.setCompressionEnabled(true); 
      config.setSASLAuthenticationEnabled(true); 

      conn1 = new XMPPConnection(config); 

      SASLAuthentication.registerSASLMechanism("X-OAUTH2", SALSGTalkOauthMechanism.class); 
      SASLAuthentication.supportSASLMechanism("X-OAUTH2", 0); 
      conn1.connect(); 

      log.info("Logging in"); 
      conn1.login(ProbeClientUtils.getOAuthConsumerId(properties), credential.getAccessToken()); 

      Presence presence = new Presence(Presence.Type.available); 
      presence.setStatus("My status"); 
      conn1.sendPacket(presence); 

      ChatManager chatmanager = conn1.getChatManager(); 

      String destination = "[email protected]"; 
      log.info("Sending chat message to " + destination); 
      String message = "PING : " + UUID.randomUUID().toString(); 

      Chat chat = chatmanager.createChat(destination, new MessageListener(//TODO : here put your stuff)); 

      Message msg = new Message(destination, Message.Type.chat); 

      msg.setBody(message); 
      chat.sendMessage(msg); 

      //Here you are 
    } 

} 
+0

您發佈在頂部的網址不工作..請發佈相關的工作網址。 – 2013-04-08 06:18:54

+0

謝謝你這就是爲什麼我在某些時候得到這個錯誤做工精細...... – 2013-04-08 07:18:41

+1

「使用機制SASL認證失敗普通紙:」 – 2013-04-08 11:12:16

-2

我在使用XMPP/Openfire服務器聊天應用程序方面做了很多工作。

這裏是連接最簡單的方法/登錄到服務器 -

ConnectionConfiguration connConfig = new ConnectionConfiguration("abc.hostname.com",5222); 
     configure(ProviderManager.getInstance()); 
     connection = new XMPPConnection(connConfig); 
     connection.connect(); 
     connection.login(userName, password); 

要獲得名冊登錄時

roster = connection.getRoster(); 
    roster.setSubscriptionMode(Roster.SubscriptionMode.manual); 

這裏的時間是爲提供程序實例的配置方法

public void configure(ProviderManager pm) { 
    // MUC Admin 
    pm.addIQProvider("query", "http://jabber.org/protocol/muc#admin",new MUCAdminProvider()); 
    // MUC Owner 
    pm.addIQProvider("query", "http://jabber.org/protocol/muc#owner",new MUCOwnerProvider()); 
    pm.addIQProvider("si", "http://jabber.org/protocol/si",new StreamInitiationProvider()); 
    pm.addIQProvider("query","http://jabber.org/protocol/bytestreams", new org.jivesoftware.smackx.provider.BytestreamsProvider()); 
    pm.addIQProvider("query","http://jabber.org/protocol/disco#items", new DiscoverItemsProvider()); 
    pm.addIQProvider("query","http://jabber.org/protocol/disco#info", new DiscoverInfoProvider()); 

    // Delayed Delivery 
    pm.addExtensionProvider("x", "jabber:x:delay",new DelayInformationProvider()); 
    pm.addIQProvider("vCard", "vcard-temp", new VCardProvider()); 

    // Group Chat Invitations 
    pm.addExtensionProvider("x","jabber:x:conference", new GroupChatInvitation.Provider()); 
} 

讓我知道您是否有任何疑問

+0

我的問題是有關谷歌機構X-的oauth2,我能夠創建使用XMPP連接用戶名和密碼。但我想創建這個與谷歌身份驗證xmpp連接.. – 2013-04-04 06:29:26

+0

好吧,讓我爲你搜索一個很好的和相關的答案 – 2013-04-04 06:30:17