Smack 4.1 Android anonymous registration to Openfi

2020-02-11 07:42发布

问题:

I want connect anonymously to openfire server with Android Smack 4.1 client and register the new user (username = "wq", password="wq") with AccountManager, and then disconnect and login as non-anonymous registered user.

3.1.1 Registration with a Server

Special care must be taken when an unregistered entity interacts with a server rather than a service. Normally, a server enables in-band registration so that entities can "bootstrap" their participation in the Jabber network; this bootstrapping happens when an unregistered and unauthenticated entity opens a TCP connection to a server and immediately completes the registration use case with the server, then authenticates using the newly-registered identity. As noted, when a server receives an IQ-get for registration information, it SHOULD assume that the requesting entity is unregistered unless the entity has already authenticated. Depending on local service provisioning, a server MAY return a stanza error if an unregistered entity attempts to register too many times before authenticating or if an entity attempts to register a second identity after successfully completing the registration use case; a server MAY also return a stream error if the unregistered entity waits too long before authenticating or attempts to complete a task other than authentication after successfully completing the registration use case.

connection builder looks like:

xmpptcpConnection = new XMPPTCPConnection(XMPPTCPConnectionConfiguration.builder()
        .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
        .setResource(resource)
        .setHost(localhost) 
        .setServiceName(serviceName)
        .setPort(port)
        .setDebuggerEnabled(true)
        .setSendPresence(true)
        .build()
);

And registration:

        if (password != null && username != null) {
            AccountManager accountManager = AccountManager.getInstance(xmpptcpConnection);
            accountManager.sensitiveOperationOverInsecureConnection(true);
            accountManager.createAccount(username, password);
        }
        else {
            smackError("Username or password wrong");
        }

But I got bad-request error

05-21 21:34:20.801  19535-19577/com.xmpp D/SMACK﹕ SENT (0): <stream:stream xmlns='jabber:client' to='127.0.0.1' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' xml:lang='en'>
05-21 21:34:20.805  19535-19578/com.xmpp D/SMACK﹕ RECV (0): <?xml version='1.0' encoding='UTF-8'?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="127.0.0.1" id="cafb2f97" xml:lang="en" version="1.0"><stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>ANONYMOUS</mechanism></mechanisms><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><auth xmlns="http://jabber.org/features/iq-auth"/><register xmlns="http://jabber.org/features/iq-register"/></stream:features>
05-21 21:34:20.826  19535-19577/com.xmpp D/SMACK﹕ SENT (0): <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'>=</auth>
05-21 21:34:20.828  19535-19578/com.xmpp D/SMACK﹕ RECV (0): <success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>
05-21 21:34:20.830  19535-19578/com.xmpp D/SMACK﹕ RECV (0): <?xml version='1.0' encoding='UTF-8'?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="127.0.0.1" id="cafb2f97" xml:lang="en" version="1.0"><stream:features><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns="urn:ietf:params:xml:ns:xmpp-session"><optional/></session></stream:features>
05-21 21:34:20.838  19535-19577/com.xmpp D/SMACK﹕ SENT (0): <iq id='h3Bqk-3' type='set'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'></bind></iq>
05-21 21:34:20.841  19535-19578/com.xmpp D/SMACK﹕ RECV (0): <iq type="result" id="h3Bqk-3" to="127.0.0.1/cafb2f97"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>cafb2f97@127.0.0.1/cafb2f97</jid></bind></iq>
05-21 21:34:20.843  19535-19564/com.xmpp D/SMACK﹕ User logged (0): cafb2f97@127.0.0.1:5222/cafb2f97
05-21 21:34:20.843  19535-19564/com.xmpp D/SMACK﹕ XMPPConnection authenticated (0)
05-21 21:34:20.844  19535-19577/com.xmpp D/SMACK﹕ SENT (0): <presence id='h3Bqk-5'><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.igniterealtime.org/projects/smack' ver='NfJ3flI83zSdUDzCEICtbypursw='/></presence>
05-21 21:35:20.531  19535-19577/com.xmpp D/SMACK﹕ SENT (0): <iq to='127.0.0.1' id='h3Bqk-6' type='get'><query xmlns='jabber:iq:register'></query></iq>
05-21 21:35:20.535  19535-19578/com.xmpp D/SMACK﹕ RECV (0): <iq type="result" id="h3Bqk-6" from="127.0.0.1" to="cafb2f97@127.0.0.1/cafb2f97"><query xmlns="jabber:iq:register"><username/><password/><email/><name/><x xmlns="jabber:x:data" type="form"><title>XMPP Client Registration</title><instructions>Please provide the following information</instructions><field var="FORM_TYPE" type="hidden"><value>jabber:iq:register</value></field><field var="username" type="text-single" label="Username"><required/></field><field var="name" type="text-single" label="Full name"/><field var="email" type="text-single" label="Email"/><field var="password" type="text-private" label="Password"><required/></field></x></query></iq>
05-21 21:35:20.537  19535-19577/com.xmpp D/SMACK﹕ SENT (0): <iq to='127.0.0.1' id='h3Bqk-8' type='set'><query xmlns='jabber:iq:register'><username>wq</username><email></email><name></name><password>wq</password></query></iq>
05-21 21:35:20.540  19535-19578/com.xmpp D/SMACK﹕ RECV (0): <iq type="error" id="h3Bqk-8" from="127.0.0.1" to="cafb2f97@127.0.0.1/cafb2f97"><query xmlns="jabber:iq:register"><username>wq</username><email/><name/><password>wq</password></query><error code="400" type="modify"><bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>
05-21 21:35:20.542  19535-19564/com.xmpp W/System.err﹕ org.jivesoftware.smack.XMPPException$XMPPErrorException: XMPPError: bad-request - modify
05-21 21:35:20.542  19535-19564/com.xmpp W/System.err﹕ at org.jivesoftware.smack.PacketCollector.nextResultOrThrow(PacketCollector.java:232)
05-21 21:35:20.542  19535-19564/com.xmpp W/System.err﹕ at org.jivesoftware.smack.PacketCollector.nextResultOrThrow(PacketCollector.java:213)
05-21 21:35:20.542  19535-19564/com.xmpp W/System.err﹕ at org.jivesoftware.smackx.iqregister.AccountManager.createAccount(AccountManager.java:272)
05-21 21:35:20.542  19535-19564/com.xmpp W/System.err﹕ at org.jivesoftware.smackx.iqregister.AccountManager.createAccount(AccountManager.java:244)
05-21 21:35:20.543  19535-19564/com.xmpp W/System.err﹕ at com.xmpp.service.SmackConnection.register(SmackConnection.java:349)
05-21 21:35:20.543  19535-19564/com.xmpp W/System.err﹕ at com.xmpp.service.SmackService$1.run(SmackService.java:119)
05-21 21:35:20.543  19535-19564/com.xmpp W/System.err﹕ at android.os.Handler.handleCallback(Handler.java:739)
05-21 21:35:20.543  19535-19564/com.xmpp W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:95)
05-21 21:35:20.543  19535-19564/com.xmpp W/System.err﹕ at android.os.Looper.loop(Looper.java:135)
05-21 21:35:20.543  19535-19564/com.xmpp W/System.err﹕ at com.xmpp.service.SmackService$2.run(SmackService.java:157)
05-21 21:35:20.543  19535-19564/com.xmpp W/System.err﹕ at java.lang.Thread.run(Thread.java:818)

I am not getting errors if I am connected with non-anonymous account, in connection builder only added :

.setUsernameAndPassword(username, password)

but I don't want to use another already registered account for registering new user to server. Is there any nice solution to pass it this way ?

回答1:

You have to separate connect().login() chain.

        xmpptcpConnection.connect();

        if (anonymous) {
            AccountManager accountManager = AccountManager.getInstance(xmpptcpConnection);
            accountManager.sensitiveOperationOverInsecureConnection(true);
            accountManager.createAccount(username, password)
        }

        xmpptcpConnection.login(); //with old or newly created username, password from shared preferences