【问题标题】:Gtalk XMPP SASL authentication failed using mechanism X-OAUTH2?使用机制 X-OAUTH2 的 Gtalk XMPP SASL 身份验证失败?
【发布时间】:2013-03-09 04:50:47
【问题描述】:

我在我的应用程序中使用 GoogleTalk XMPP 进行聊天。无法通过将用户名和 AuthToken 与 Google authentication 一起使用来创建 XMPP 连接。

现在我将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 进行身份验证?

【问题讨论】:

    标签: android xmpp google-oauth


    【解决方案1】:

    我在使用 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());
    }
    

    如果您有任何疑问,请告诉我

    【讨论】:

    • 我的问题与谷歌机制 X-OAUTH2 有关,我可以使用用户名和密码创建 xmpp 连接。但我想用谷歌身份验证创建这个 xmpp 连接..
    【解决方案2】:

    这是一个适用于我的版本,使用 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 = "destination@gmail.com";
                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
        }
    
    }
    

    【讨论】:

    • 您在顶部发布的网址无效..请发布相关的有效网址。
    • 为什么我有时会收到此错误“使用机制 PLAIN 的 SASL 身份验证失败:”
    • @RajaReddyPolamReddy :此 URL 不是链接,它是 OAUTH 范围
    • 当我第一次登录时它工作正常,当我重新打开我的应用程序时,我无法登录到具有相同凭据的 xmpp 帐户第一次登录。这是我得到的例外。 “使用机制 PLAIN 的 SASL 身份验证失败:”
    • @Erik 您可以从此developers.google.com/accounts/docs/OAuth2InstalledApp 获取这些值,您必须创建所有 url 并让这些值传递给 XMPP login.by 使用上述身份验证机制..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 1970-01-01
    相关资源
    最近更新 更多