0

I'm in desperate need of help! I've been wrestling with Strophe.js for OAuth authentication, and I'm at my wit's end. I've scoured the documentation and examples, but I just can't get the OAuth mechanism to work.

I receive the message from JS: INVALID TOKEN!!!!!!!

I'm on the brink of insanity here! My brain is melting. Here's the code snippet that's driving me crazy:

const xmppServer = 'my-chat.de';
const xmppUsername = 'admin';
const oauthToken = 'XXXXXXXXXXXXXXXXXiUQJZ8jrziUn8Qd';
const boshEndpoint = `https://${xmppServer}/bosh`;

const from = `${xmppUsername}@${xmppServer}`;
const to = 'test@my-chat.de';

// Connection to bosh.
const connection = new Strophe.Connection(boshEndpoint);
const saslOAuthBearer = new Strophe.SASLMechanism(connection);

saslOAuthBearer.priority = 30; // Also tried 40
saslOAuthBearer.isClientFirst = false;

saslOAuthBearer.test = function() {
    return true;
};

connection.rawInput = function(data) {
    console.log("RECEIVED:", data);
};

connection.rawOutput = function(data) {
    console.log("SENT:", data);
};

connection.connect(from, oauthToken, (status, condition) => {
    // Zuerst registrierst du den Mechanismus
    if (status === Strophe.Status.CONNECTING) {
        console.log('Connecting to XMPP server...');
    } else if (status === Strophe.Status.CONNFAIL) {
        console.log('XMPP connection attempt failed.');
    } else if (status === Strophe.Status.AUTHENTICATING) {
        console.log('Authenticating...');
    } else if (status === Strophe.Status.AUTHFAIL) {
        console.log('XMPP authentication failed.');
    } else if (status === Strophe.Status.CONNECTED) {
        console.log('XMPP connection established.');
    } else if (status === Strophe.Status.DISCONNECTED) {
        console.log('XMPP connection disconnected.');
    } else if (status === Strophe.Status.DISCONNECTING) {
        console.log('Disconnecting from XMPP server...');
    } else if (status === Strophe.Status.REDIRECT) {
        console.log('XMPP connection redirected.');
    } else if (status === Strophe.Status.CONNTIMEOUT) {
        console.log('XMPP connection timeout.');
    } else {
        console.log('Unknown XMPP connection status:', status);
    }

},
    null,
    null,
    xmppServer,
    {
    mechanism: 'X-OAUTH2',
    oauth_token: oauthToken
});

I'm at my breaking point! It's like Strophe.js is mocking my every attempt. Can someone please throw me a lifeline and help me figure out what dark magic is preventing the OAuth mechanism from kicking in?

Strophe.js Version: 1.6.0 XMPP Server: 23.05

OAuth Token (SEND Log):

SENT: <body rid="1534767099" sid="cfbc87bd0068b53002a98048d7cd86d3853e03fa" xmlns="http://jabber.org/protocol/httpbind"><auth mechanism="X-OAUTH2" xmlns="urn:ietf:params:xml:ns:xmpp-sasl">AGFkbWluQGxpZWJlcy1jaGF0LmRlADhMOFNUd1BQV1Fxxxxxxxxxxxxxxxxxxxxxxxx</auth></body>
RECEIVED: <body xmlns="http://jabber.org/protocol/httpbind"><failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/><text xml:lang="en">Invalid token</text></failure></body>

tokens

root@xyz:/opt/ejabberd/conf# ejabberdctl oauth_list_tokens
XXXXXXXXXXXXXXXXXPUMWUrWxi7gikDN        admin@my-chat.de    [<<"ejabberd:user">>]   3567104 seconds
XXXXXXXXXXXXXXXXXKjRErde70gWwTR1        admin@my-chat.de    [<<"ejabberd:user">>]   3568566 seconds
XXXXXXXXXXXXXXXXXiUQJZ8jrziUn8Qd        admin@my-chat.de    [<<"ejabberd:admin">>]  3564705 seconds
XXXXXXXXXXXXXXXXXjBwhau0C4nXvEpt        testuser@my-chat.de [<<"sasl_auth">>]       269402 seconds
XXXXXXXXXXXXXXXXX5QFXDaY89qcN7iA        testuser@my-chat.de [<<"ejabberd:admin">>]  269342 seconds
XXXXXXXXXXXXXXXXXtwZnjqzHPM4fZYv        testuser@my-chat.de [<<"sasl_auth">>,<<"get_roster">>]      269411 seconds

I'm using Strophe.js for XMPP communication with an ejabberd server. Everything works fine with username and password, but OAuth authentication is giving me trouble.

I testet my Token via python3 and with a http oauth request to create a token successfully:

This test worked:

test.py

import xmlrpc.client as client

server_url = 'http://my-chat.de:4560/' server = client.ServerProxy(server_url)

LOGIN = {'user': 'admin', 'server': 'my-chat.de', 'token': 'xxxxxxxxxxxxxxxxxxx', 'admin': False}

def calling(command, data): fn = getattr(server, command) return fn(LOGIN, data)

result = server.get_roster(LOGIN, {'user': 'admin', 'server': 'my-chat.de'})

print(result)

ejabbery.yml

Forced to use X-OAUTH2

listen:
  -
    port: 4560
    module: ejabberd_http
    request_handlers:
      ## Handle ejabberd commands using XML-RPC
      "/": ejabberd_xmlrpc
  -
    port: 5222
    ip: "::"
    module: ejabberd_c2s
    max_stanza_size: 262144
    shaper: c2s_shaper
    access: c2s
    starttls_required: true
  -
    port: 5223
    ip: "::"
    tls: true
    module: ejabberd_c2s
    max_stanza_size: 262144
    shaper: c2s_shaper
    access: c2s
    starttls_required: true
  -
    port: 5269
    ip: "::"
    module: ejabberd_s2s_in
    max_stanza_size: 524288
  -
    port: 5443
    ip: "::"
    module: ejabberd_http
    tls: true
    request_handlers:
      "/admin": ejabberd_web_admin
      "/api": mod_http_api
      "/bosh": mod_bosh
      "/captcha": ejabberd_captcha
      "/upload": mod_http_upload
      "/ws": ejabberd_http_ws
      "/oauth": ejabberd_oauth
#      "/xmpp-register": mod_register_web
      "/.well-known/acme-challenge": ejabberd_acme
  -
    port: 5280
    ip: "::"
    module: ejabberd_http
    request_handlers:
      /admin: ejabberd_web_admin
      /.well-known/acme-challenge: ejabberd_acme
#      /oauth: ejabberd_oauth
  -
    port: 3478
    ip: "::"
    transport: udp
    module: ejabberd_stun
    use_turn: true
    ## The server's public IPv4 address:
    # turn_ipv4_address: "203.0.113.3"
    ## The server's public IPv6 address:
    # turn_ipv6_address: "2001:db8::3"
  -
    port: 1883
    ip: "::"
    module: mod_mqtt
    backlog: 1000

s2s_use_starttls: optional


disable_sasl_mechanisms:
  - "SCRAM-SHA-512"
  - "SCRAM-SHA-512-PLUS"
  - "SCRAM-SHA-256"
  - "SCRAM-SHA-256-PLUS"
  - "SCRAM-SHA-1"
  - "DIGEST-MD5"
  - "PLAIN"
oauth_expire: 2592000
oauth_access: all
oauth_client_id_check: db

acl:
  admin:                    
    user:                
      - admin               
    ip:                      
      - <<<<<myipadress>>>>>     
  local:
    user_regexp: ""
  loopback:
    ip:
      - 127.0.0.0/8
      - ::1/128

access_rules:
  local:
    allow: all
  c2s:
    deny: blocked
    allow: all
  announce:
    allow: admin
  configure:
    allow: admin
  muc_create:
    allow: local
  pubsub_createnode:
    allow: local
  trusted_network:
    allow: loopback

api_permissions:
  "console commands":
    from:
      - ejabberd_ctl
    who: all
    what: "*"
  "admin access":
    who:
      access:
        allow:
          - acl: admin
      oauth:
        scope: "ejabberd:admin"
        access:
          allow:
            - acl: admin
    what:
      - "*"
      - "!stop"
      - "!start"
#    from:
#      - mod_http_api
  "public commands":
    who:
      ip: 127.0.0.1/8
    what:
      - status
  "user access":
    who:
      access:
        allow:
          - acl: all
      oauth:
        scope: "ejabberd:user"
        access:
          allow:
            - acl: all
    what:
      - "sasl_auth"
      - "get_roster"
      - "send_message"
      - "send_stanza"
      - "set_last"
      - "get_last"

1 Answers1

0

Now it works, Serverside Problem. I forgot to made a oauth Token with sasl_auth. Now it works.