esl / MongooseIM

MongooseIM is Erlang Solutions' robust, scalable and efficient XMPP server, aimed at large installations. Specifically designed for enterprise purposes, it is fault-tolerant and can utilise the resources of multiple clustered machines.
Other
1.67k stars 427 forks source link

Can not authen with access_token #915

Closed emnvn closed 8 years ago

emnvn commented 8 years ago

MongooseIM version: 2.0.0-beta1 Installed from: source Erlang/OTP version: Erlang/OTP 17 [erts-6.4] [source] [64-bit] [async-threads:10] [hipe] [kernel-poll:false]

I have tried to use access token and refresh token to authenticate to XMPP server. After login by user/pass I requested this pair of token by seeing this xml stanza

<iq from='test01@dtsc.com.vn' to='test01@dtsc.com.vn/87B0EA7F1BEE07C01469778484314618' id='55850c43-e9e7-4508-b4e6-fc10a40f4c8b:sendIQ' type='result' xmlns='jabber:client'>
<items xmlns='erlang-solutions.com:xmpp:token-auth:0'>
<access_token xmlns='erlang-solutions.com:xmpp:token-auth:0'>YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi84N0IwRUE3RjFCRUUwN0MwMTQ2OTc3ODQ4NDMxNDYxOAA2MzYzNzAwMzQ1MQAwMmRlYzM0MTQyNzczOTY5ZTFlMjQzOGM2OGNhZDA4MGVjZjMzMjViNTIzOTZkMmE0YTU0ZjMyNDJlNmJhZjRlZTUzMTI2NDc3NWM5MWM0MmViMTNmMTRjOTQ3ZDhlOTM=</access_token>`
<refresh_token xmlns='erlang-solutions.com:xmpp:token-auth:0'>cmVmcmVzaAB0ZXN0MDFAZHRzYy5jb20udm4vODdCMEVBN0YxQkVFMDdDMDE0Njk3Nzg0ODQzMTQ2MTgANjM2MzcwODYyNTEAMQBiOTE2NGUwNDc1MGExNDFlZTVlZjVhNWJjNGFmZmU3ODc2Mzc4MzFiZDY1MmZiYjZjMjE4NWU4ZGM5OWU0NjI2ZDdhNzJkODA2YWNlYjU4OGY0NTY5ZTE4OWVkZmY3Y2U=
> </refresh_token>
</items>
</iq>

Then I use the access token to authenticate with xmpp server, I sent this xml stanza

<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-OAUTH'>YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi84N0IwRUE3RjFCRUUwN0MwMTQ2OTc3ODQ4NDMxNDYxOAA2MzYzNzAwMzQ1MQAwMmRlYzM0MTQyNzczOTY5ZTFlMjQzOGM2OGNhZDA4MGVjZjMzMjViNTIzOTZkMmE0YTU0ZjMyNDJlNmJhZjRlZTUzMTI2NDc3NWM5MWM0MmViMTNmMTRjOTQ3ZDhlOTM=</auth>

But I can't receive any response from xmpp server. I saw this message which is received by xmpp server. 2016-08-10 09:39:29.439 [debug] <0.686.0>@mod_websockets:websocket_handle:182 Received: <<"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-OAUTH'>YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi84N0IwRUE3RjFCRUUwN0MwMTQ2OTc3ODQ4NDMxNDYxOAA2MzYzNzAwMzQ1MQAwMmRlYzM0MTQyNzczOTY5ZTFlMjQzOGM2OGNhZDA4MGVjZjMzMjViNTIzOTZkMmE0YTU0ZjMyNDJlNmJhZjRlZTUzMTI2NDc3NWM5MWM0MmViMTNmMTRjOTQ3ZDhlOTM=</auth>">>

This is my config file

%%%
%%%               ejabberd configuration file
%%%
%%%'

%%% The parameters used in this configuration file are explained in more detail
%%% in the ejabberd Installation and Operation Guide.
%%% Please consult the Guide in case of doubts, it is included with
%%% your copy of ejabberd, and is also available online at
%%% http://www.process-one.net/en/ejabberd/docs/

%%% This configuration file contains Erlang terms.
%%% In case you want to understand the syntax, here are the concepts:
%%%
%%%  - The character to comment a line is %
%%%
%%%  - Each term ends in a dot, for example:
%%%      override_global.
%%%
%%%  - A tuple has a fixed definition, its elements are
%%%    enclosed in {}, and separated with commas:
%%%      {loglevel, 4}.
%%%
%%%  - A list can have as many elements as you want,
%%%    and is enclosed in [], for example:
%%%      [http_poll, web_admin, tls]
%%%
%%%    Pay attention that list elements are delimited with commas,
%%%    but no comma is allowed after the last list element. This will
%%%    give a syntax error unlike in more lenient languages (e.g. Python).
%%%
%%%  - A keyword of ejabberd is a word in lowercase.
%%%    Strings are enclosed in "" and can contain spaces, dots, ...
%%%      {language, "en"}.
%%%      {ldap_rootdn, "dc=example,dc=com"}.
%%%
%%%  - This term includes a tuple, a keyword, a list, and two strings:
%%%      {hosts, ["jabber.example.net", "im.example.com"]}.
%%%
%%%  - This config is preprocessed during release generation by a tool which
%%%    interprets double curly braces as substitution markers, so avoid this
%%%    syntax in this file (though it's valid Erlang).
%%%
%%%    So this is OK (though arguably looks quite ugly):
%%%      { {s2s_addr, "example-host.net"}, {127,0,0,1} }.
%%%
%%%    And I can't give an example of what's not OK exactly because
%%%    of this rule.
%%%

%%%.   =======================
%%%'   OVERRIDE STORED OPTIONS

%%
%% Override the old values stored in the database.
%%

%%
%% Override global options (shared by all ejabberd nodes in a cluster).
%%
%%override_global.

%%
%% Override local options (specific for this particular ejabberd node).
%%
%%override_local.

%%
%% Remove the Access Control Lists before new ones are added.
%%
%%override_acls.

%%%.   =========
%%%'   DEBUGGING

%%
%% loglevel: Verbosity of log files generated by ejabberd.
%% 0: No ejabberd log at all (not recommended)
%% 1: Critical
%% 2: Error
%% 3: Warning
%% 4: Info
%% 5: Debug
%%
{loglevel, 3}.

%%
%% alarms: an optional alarm handler, subscribed to system events
%% long_gc: minimum GC time in ms for long_gc alarm
%% large_heap: minimum process heap size for large_heap alarm
%% handlers: a list of alarm handlers
%%   - alarms_basic_handler:  logs alarms and stores a brief alarm summary
%%   - alarms_folsom_handler: stores alarm details in folsom metrics
%%
%% Example:
%% {alarms,
%%  [{long_gc, 10000},
%%   {large_heap, 1000000},
%%   {handlers, [alarms_basic_handler,
%%               alarms_folsom_handler]}]
%% }.

%%

%%%.   ================
%%%'   SERVED HOSTNAMES

%%
%% hosts: Domains served by ejabberd.
%% You can define one or several, for example:
%% {hosts, ["example.net", "example.com", "example.org"]}.
%%
{hosts, ["dtsc.com.vn"] }.

%%
%% route_subdomains: Delegate subdomains to other XMPP servers.
%% For example, if this ejabberd serves example.org and you want
%% to allow communication with an XMPP server called im.example.org.
%%
%%{route_subdomains, s2s}.

%%%.   ===============
%%%'   LISTENING PORTS

%%
%% listen: The ports ejabberd will listen on, which service each is handled
%% by and what options to start it with.
%%
{listen,
 [
  %% BOSH and WS endpoints over HTTP
  { 5280, ejabberd_cowboy, [
      {num_acceptors, 10},
      {max_connections, 1024},
      {modules, [
          {"_", "/http-bind", mod_bosh},
          {"_", "/ws-xmpp", mod_websockets, [
          %% Uncomment to enable connection dropping or/and server-side pings
          %{timeout, 600000}, {ping_rate, 2000}
          ]}
          %% Uncomment to serve static files
          %{"_", "/static/[...]", cowboy_static,
          %  {dir, "/var/www", [{mimetypes, cow_mimetypes, all}]}
          %},

          %% Example usage of mod_revproxy

          %% {"_", "/[...]", mod_revproxy, [{timeout, 5000},
          %%                                % time limit for upstream to respond
          %%                                {body_length, 8000000},
          %%                                % maximum body size (may be infinity)
          %%                                {custom_headers, [{<<"header">>,<<"value">>}]}
          %%                                % list of extra headers that are send to upstream
          %%                               ]}

          %% Example usage of mod_cowboy

          %% {"_", "/[...]", mod_cowboy, [{http, mod_revproxy,
          %%                                [{timeout, 5000},
          %%                                 % time limit for upstream to respond
          %%                                 {body_length, 8000000},
          %%                                 % maximum body size (may be infinity)
          %%                                 {custom_headers, [{<<"header">>,<<"value">>}]}
          %%                                 % list of extra headers that are send to upstream
          %%                                ]},
          %%                               {ws, xmpp, mod_websockets}
          %%                             ]}
      ]}
  ]},

  %% BOSH and WS endpoints over HTTPS
  { 5285, ejabberd_cowboy, [
        {num_acceptors, 10},
        {max_connections, 1024},
        {cert, "priv/ssl/fake_cert.pem"}, {key, "priv/ssl/fake_key.pem"}, {key_pass, ""},
        {modules, [
            {"_", "/http-bind", mod_bosh},
            {"_", "/ws-xmpp", mod_websockets, [
            %% Uncomment to enable connection dropping or/and server-side pings
            %{timeout, 600000}, {ping_rate, 60000}
            ]}
            %% Uncomment to serve static files
            %{"_", "/static/[...]", cowboy_static,
            %  {dir, "/var/www", [{mimetypes, cow_mimetypes, all}]}
            %},
        ]}
    ]},

  %% MongooseIM HTTP API it's important to start it on localhost
  %% or some private interface only (not accessible from the outside)
  %% At least start it on different port which will be hidden behind firewall

  { {5288, "127.0.0.1"} , ejabberd_cowboy, [
      {num_acceptors, 10},
      {max_connections, 1024},
      {modules, [
          {"localhost", "/api", mongoose_api, [{handlers, [mongoose_api_metrics,
                                                           mongoose_api_users]}]}
      ]}
  ]},

  { 5222, ejabberd_c2s, [

            %%
            %% If TLS is compiled in and you installed a SSL
            %% certificate, specify the full path to the
            %% file and uncomment this line:
            %%
                        {certfile, "priv/ssl/fake_server.pem"}, starttls,
                        {zlib, 10000},
            %% https://www.openssl.org/docs/apps/ciphers.html#CIPHER_STRINGS
            %% {ciphers, "DEFAULT:!EXPORT:!LOW:!SSLv2"},
            {access, c2s},
            {shaper, c2s_shaper},
            {max_stanza_size, 65536}
               ]},

  { 5223, ejabberd_c2s, [
    {zlib, 4096},
    {access, c2s},
        {shaper, c2s_shaper},
        {max_stanza_size, 65536}
    ]},

  %%
  %% To enable the old SSL connection method on port 5223:
  %%
  %%{5223, ejabberd_c2s, [
  %%            {access, c2s},
  %%            {shaper, c2s_shaper},
  %%            {certfile, "/path/to/ssl.pem"}, tls,
  %%            {max_stanza_size, 65536}
  %%               ]},

  { 5269, ejabberd_s2s_in, [
               {shaper, s2s_shaper},
               {max_stanza_size, 131072}
              ]}

  %%
  %% ejabberd_service: Interact with external components (transports, ...)
  %%
  %%{8888, ejabberd_service, [
  %%                {access, all},
  %%                {shaper_rule, fast},
  %%                {ip, {127, 0, 0, 1}},
  %%                {hosts, ["icq.example.org", "sms.example.org"],
  %%                 [{password, "secret"}]
  %%                }
  %%               ]},

  %%
  %% ejabberd_stun: Handles STUN Binding requests
  %%
  %%{ {3478, udp}, ejabberd_stun, []}

 ]}.

%%
%% s2s_use_starttls: Enable STARTTLS + Dialback for S2S connections.
%% Allowed values are: false optional required required_trusted
%% You must specify a certificate file.
%%
{s2s_use_starttls, optional}.
%%
%% s2s_certfile: Specify a certificate file.
%%
{s2s_certfile, "priv/ssl/fake_server.pem"}.

%% https://www.openssl.org/docs/apps/ciphers.html#CIPHER_STRINGS
%% {s2s_ciphers, "DEFAULT:!EXPORT:!LOW:!SSLv2"}.

%%
%% domain_certfile: Specify a different certificate for each served hostname.
%%
%%{domain_certfile, "example.org", "/path/to/example_org.pem"}.
%%{domain_certfile, "example.com", "/path/to/example_com.pem"}.

%%
%% S2S whitelist or blacklist
%%
%% Default s2s policy for undefined hosts.
%%
{s2s_default_policy, allow }.

%%
%% Allow or deny communication with specific servers.
%%
%%{ {s2s_host, "goodhost.org"}, allow}.
%%{ {s2s_host, "badhost.org"}, deny}.

{outgoing_s2s_port, 5279 }.

%%
%% IP addresses predefined for specific hosts to skip DNS lookups.
%% Ports defined here take precedence over outgoing_s2s_port.
%% Examples:
%%
%% { {s2s_addr, "example-host.net"}, {127,0,0,1} }.
%% { {s2s_addr, "example-host.net"}, { {127,0,0,1}, 5269 } }.
{ {s2s_addr, "localhost2"}, {127,0,0,1} }.

%%
%% Outgoing S2S options
%%
%% Preferred address families (which to try first) and connect timeout
%% in milliseconds.
%%
%%{outgoing_s2s_options, [ipv4, ipv6], 10000}.

%%%.   ==============
%%%'   SESSION BACKEND

%%{sm_backend, {mnesia, []}}.

%%{sm_backend, {redis, [{pool_size, 3}, {worker_config, [{host, "localhost"}, {port, 6379}]}]}}.
{sm_backend, {mnesia, []} }.

%%%.   ==============
%%%'   AUTHENTICATION

%%
%% auth_method: Method used to authenticate the users.
%% The default method is the internal.
%% If you want to use a different method,
%% comment this line and enable the correct ones.
%%
{auth_method, internal }.
{auth_opts, [
             %% Store the plain passwords or hashed for SCRAM:
             %% {password_format, plain} % default
             %% {password_format, scram}

             %% {scram_iterations, 4096} % default

             %%
             %% For auth_http:
             %% {host, IP | Hostname}
             %% {connection_pool_size, 10} % default
             %% {connection_opts, Opts}
             %% {basic_auth, "user:password"}
             %% {path_prefix, "/"} % default
             %%
             %% For auth_external
             %%{extauth_program, "/path/to/authentication/script"}.
            ]}.

%%
%% Authentication using external script
%% Make sure the script is executable by ejabberd.
%%
%%{auth_method, external}.

%%
%% Authentication using ODBC
%% Remember to setup a database in the next section.
%%
%%{auth_method, odbc}.

%%
%% Authentication using LDAP
%%
%%{auth_method, ldap}.
%%

%% List of LDAP servers:
%%{ldap_servers, ["localhost"]}.
%%
%% Encryption of connection to LDAP servers:
%%{ldap_encrypt, none}.
%%{ldap_encrypt, tls}.
%%
%% Port to connect to on LDAP servers:
%%{ldap_port, 389}.
%%{ldap_port, 636}.
%%
%% LDAP manager:
%%{ldap_rootdn, "dc=example,dc=com"}.
%%
%% Password of LDAP manager:
%%{ldap_password, "******"}.
%%
%% Search base of LDAP directory:
%%{ldap_base, "dc=example,dc=com"}.
%%
%% LDAP attribute that holds user ID:
%%{ldap_uids, [{"mail", "%u@mail.example.org"}]}.
%%
%% LDAP filter:
%%{ldap_filter, "(objectClass=shadowAccount)"}.

%%
%% Anonymous login support:
%%   auth_method: anonymous
%%   anonymous_protocol: sasl_anon | login_anon | both
%%   allow_multiple_connections: true | false
%%
%%{host_config, "public.example.org", [{auth_method, anonymous},
%%                                     {allow_multiple_connections, false},
%%                                     {anonymous_protocol, sasl_anon}]}.
%%
%% To use both anonymous and internal authentication:
%%
%%{host_config, "public.example.org", [{auth_method, [internal, anonymous]}]}.
%%{host_config, "anonymous.localhost", [{auth_method, anonymous},
%%                                        {allow_multiple_connections, true},
%%                                        {anonymous_protocol, both}]}.

%%%.   ==============
%%%'   DATABASE SETUP

%% ejabberd by default uses the internal Mnesia database,
%% so you do not necessarily need this section.
%% This section provides configuration examples in case
%% you want to use other database backends.
%% Please consult the ejabberd Guide for details on database creation.

%%
%% MySQL server:
%%
%% {odbc_server, {mysql, "localhost", 3306, "database", "username", "password"}}.
%%
%% If you want to specify the port:
%%{odbc_server, {mysql, "server", 1234, "database", "username", "password"}}.

%%
%% PostgreSQL server:
%%
{odbc_server, {pgsql, "10.12.10.140", "mongooseim_v200beta1", "mongooseim", "mongooseim"}}.
%%
%% If you want to specify the port:
%%{odbc_server, {pgsql, "server", 1234, "database", "username", "password"}}.
%%
%% If you use PostgreSQL, have a large database, and need a
%% faster but inexact replacement for "select count(*) from users"
%%
%%{pgsql_users_number_estimate, true}.

%%
%% ODBC compatible or MSSQL server:
%%
%%{odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}.

%% Specifies what database is used over the ODBC layer
%% Can take values odbc, pgsql, mysql
%% In some cases (for example for MAM with pgsql) it is required to set proper value.
%% {odbc_server_type, odbc}.
%%
%% Number of connections to open to the database for each virtual host
%%
%%{odbc_pool_size, 10}.

%%% ====================
%%% RIAK SETUP
%%% ====================

%%{riak_server, [{pool_size, 20}, {address, "127.0.0.1"}, {port, 8087}, {riak_pb_socket_opts, []}]}.

%%
%% Interval to make a dummy SQL request to keep the connections to the
%% database alive. Specify in seconds: for example 28800 means 8 hours
%%
%%{odbc_keepalive_interval, undefined}.

%%%.   ===============
%%%'   TRAFFIC SHAPERS

%%
%% The "normal" shaper limits traffic speed to 1000 B/s
%%
{shaper, normal, {maxrate, 1000}}.

%%
%% The "fast" shaper limits traffic speed to 50000 B/s
%%
{shaper, fast, {maxrate, 50000}}.

%%
%% This option specifies the maximum number of elements in the queue
%% of the FSM. Refer to the documentation for details.
%%
{max_fsm_queue, 1000}.

%%%.   ====================
%%%'   ACCESS CONTROL LISTS

%%
%% The 'admin' ACL grants administrative privileges to XMPP accounts.
%% You can put here as many accounts as you want.
%%
%{acl, admin, {user, "alice", "localhost"}}.
%{acl, admin, {user, "a", "localhost"}}.

%%
%% Blocked users
%%
%%{acl, blocked, {user, "baduser", "example.org"}}.
%%{acl, blocked, {user, "test"}}.

%%
%% Local users: don't modify this line.
%%
{acl, local, {user_regexp, ""}}.

%%
%% More examples of ACLs
%%
%%{acl, jabberorg, {server, "jabber.org"}}.
%%{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
%%{acl, test, {user_regexp, "^test"}}.
%%{acl, test, {user_glob, "test*"}}.

%%
%% Define specific ACLs in a virtual host.
%%
%%{host_config, "localhost",
%% [
%%  {acl, admin, {user, "bob-local", "localhost"}}
%% ]
%%}.

%%%.   ============
%%%'   ACCESS RULES

%% Maximum number of simultaneous sessions allowed for a single user:
{access, max_user_sessions, [{10, all}]}.

%% Maximum number of offline messages that users can have:
{access, max_user_offline_messages, [{5000, admin}, {100, all}]}.

%% This rule allows access only for local users:
{access, local, [{allow, local}]}.

%% Only non-blocked users can use c2s connections:
{access, c2s, [{deny, blocked},
           {allow, all}]}.

%% For C2S connections, all users except admins use the "normal" shaper
{access, c2s_shaper, [{none, admin},
              {normal, all}]}.

%% All S2S connections use the "fast" shaper
{access, s2s_shaper, [{fast, all}]}.

%% Admins of this server are also admins of the MUC service:
{access, muc_admin, [{allow, admin}]}.

%% Only accounts of the local ejabberd server can create rooms:
{access, muc_create, [{allow, local}]}.

%% All users are allowed to use the MUC service:
{access, muc, [{allow, all}]}.

%% In-band registration allows registration of any possible username.
%% To disable in-band registration, replace 'allow' with 'deny'.
{access, register, [{allow, all}]}.

%% By default the frequency of account registrations from the same IP
%% is limited to 1 account every 10 minutes. To disable, specify: infinity
{registration_timeout, infinity}.

%% Default settings for MAM.
%% To set non-standard value, replace 'default' with 'allow' or 'deny'.
%% Only user can access his/her archive by default.
%% An online user can read room's archive by default.
%% Only an owner can change settings and purge messages by default.
%% Empty list (i.e. `[]`) means `[{deny, all}]`.
{access, mam_set_prefs, [{default, all}]}.
{access, mam_get_prefs, [{default, all}]}.
{access, mam_lookup_messages, [{default, all}]}.
{access, mam_purge_single_message, [{default, all}]}.
{access, mam_purge_multiple_messages, [{default, all}]}.

%% 1 command of the specified type per second.
{shaper, mam_shaper, {maxrate, 1}}.
%% This shaper is primeraly for Mnesia overload protection during stress testing.
%% The limit is 1000 operations of each type per second.
{shaper, mam_global_shaper, {maxrate, 1000}}.

{access, mam_set_prefs_shaper, [{mam_shaper, all}]}.
{access, mam_get_prefs_shaper, [{mam_shaper, all}]}.
{access, mam_lookup_messages_shaper, [{mam_shaper, all}]}.
{access, mam_purge_single_message_shaper, [{mam_shaper, all}]}.
{access, mam_purge_multiple_messages_shaper, [{mam_shaper, all}]}.

{access, mam_set_prefs_global_shaper, [{mam_global_shaper, all}]}.
{access, mam_get_prefs_global_shaper, [{mam_global_shaper, all}]}.
{access, mam_lookup_messages_global_shaper, [{mam_global_shaper, all}]}.
{access, mam_purge_single_message_global_shaper, [{mam_global_shaper, all}]}.
{access, mam_purge_multiple_messages_global_shaper, [{mam_global_shaper, all}]}.

%%
%% Define specific Access Rules in a virtual host.
%%
%%{host_config, "localhost",
%% [
%%  {access, c2s, [{allow, admin}, {deny, all}]},
%%  {access, register, [{deny, all}]}
%% ]
%%}.

%%%.   ================
%%%'   DEFAULT LANGUAGE

%%
%% language: Default language used for server messages.
%%
{language, "en"}.

%%
%% Set a different default language in a virtual host.
%%
%%{host_config, "localhost",
%% [{language, "ru"}]
%%}.

%%%.   =======
%%%'   MODULES

%%
%% Modules enabled in all ejabberd virtual hosts.
%% For list of possible modules options, check documentation.
%%
{modules,
 [

  %% The format for a single route is as follows:
  %% {Host, Path, Method, Upstream}
  %%
  %% "_" can be used as wildcard for Host, Path and Method
  %% Upstream can be either host (just http(s)://host:port) or uri
  %% The difference is that host upstreams append whole path while
  %% uri upstreams append only remainder that follows the matched Path
  %% (this behaviour is similar to nginx's proxy_pass rules)
  %%
  %% Bindings can be used to match certain parts of host or path.
  %% They will be later overlaid with parts of the upstream uri.
  %%
  %% {mod_revproxy,
  %%    [{routes, [{"www.erlang-solutions.com", "/admin", "_",
  %%                "https://www.erlang-solutions.com/"},
  %%               {":var.com", "/:var", "_", "http://localhost:8080/"},
  %%               {":domain.com", "/", "_", "http://localhost:8080/:domain"}]
  %%     }]},

    {mod_adhoc, []},

  {mod_disco, []},
  {mod_last, []},
  {mod_stream_management, [
                           % default 100
                           % size of a buffer of unacked messages
                           % {buffer_max, 100}

                           % default 1 - server sends the ack request after each stanza
                           % {ack_freq, 1}

                           % default: 600 seconds
                           % {resume_timeout, 600}
                          ]},
  %% {mod_muc_light, [{host, "muclight.@HOST@"}]},
  %% {mod_muc, [{host, "muc.@HOST@"},
  %%            {access, muc},
  %%            {access_create, muc_create}
  %%           ]},
  %% {mod_muc_log, [
  %%                {outdir, "/tmp/muclogs"},
  %%                {access_log, muc}
  %%               ]},
  {mod_offline, [{access_max_user_messages, max_user_offline_messages}]},
  {mod_privacy, [{backend,odbc}]},
  {mod_blocking, []},
  {mod_private, [{backend,odbc}]},
% {mod_private, [{backend, mnesia}]},
% {mod_private, [{backend, odbc}]},
  {mod_register, [
          %%
          %% Set the minimum informational entropy for passwords.
          %%
          %%{password_strength, 32},

          %%
          %% After successful registration, the user receives
          %% a message with this subject and body.
          %%
          {welcome_message, {""}},

          %%
          %% When a user registers, send a notification to
          %% these XMPP accounts.
          %%
                  %{registration_watchers, ["admin@localhost"]},

          %%
          %% Only clients in the server machine can register accounts
          %%
          {ip_access, [{allow, "127.0.0.0/8"},
                   {deny, "0.0.0.0/0"}]},

          %%
          %% Local c2s or remote s2s users cannot register accounts
          %%
          %%{access_from, deny},

          {access, register}
         ]},
  {mod_roster, []},
  {mod_sic, []},
  {mod_vcard, [%{matches, 1},
%{search, true},
%{ldap_search_operator, 'or'}, %% either 'or' or 'and'
%{ldap_binary_search_fields, [<<"PHOTO">>]},
%% list of binary search fields (as in vcard after mapping)
%{host, directory.@HOST@}
]},
  {mod_bosh, []},
  {mod_websockets, []},
  {mod_carboncopy, []},

  %%
  %% Message Archive Management (MAM) for registered users.
  %%

  %% A module for storing preferences in RDBMS (used by default).
  %% Enable for private message archives.
% {mod_mam_odbc_prefs, [pm]},
  %% Enable for multiuser message archives.
% {mod_mam_odbc_prefs, [muc]},
  %% Enable for both private and multiuser message archives.
% {mod_mam_odbc_prefs, [pm, muc]},

  %% A module for storing preferences in Mnesia (recommended).
  %% This module will be called each time, as a message is routed.
  %% That is why, Mnesia is better for this job.
% {mod_mam_mnesia_prefs, [pm, muc]},

  %% Mnesia back-end with optimized writes and dirty synchronious writes.
% {mod_mam_mnesia_dirty_prefs, [pm, muc]},

  %% A back-end for storing messages.
  %% Synchronious writer (used by default).
  %% This writer is easy to debug, but writing performance is low.
% {mod_mam_odbc_arch, [pm]},

  %% Enable the module with a custom writer.
% {mod_mam_odbc_arch, [no_writer, pm]},

  %% A pool of asynchronious writers (recommended).
  %% Messages will be grouped together based on archive id.
% {mod_mam_odbc_async_pool_writer, [pm]},

  %% A module for converting an archive id to an integer.
  %% Extract information using ODBC.
% {mod_mam_odbc_user, [pm, muc]},

  %% Cache information about users (recommended).
  %% Requires mod_mam_odbc_user or alternative.
% {mod_mam_cache_user, [pm, muc]},

  %% Enable MAM.
% {mod_mam, []},

  %%
  %% Message Archive Management (MAM) for multi-user chats (MUC).
  %% Enable XEP-0313 for "muc.@HOST@".
  %%

  %% A back-end for storing messages (default for MUC).
  %% Modules mod_mam_muc_* are optimized for MUC.
  %%
  %% Synchronious writer (used by default for MUC).
  %% This module is easy to debug, but performance is low.
% {mod_mam_muc_odbc_arch, []},
% {mod_mam_muc_odbc_arch, [no_writer]},

  %% Asynchronious writer for RDBMS (recommended for MUC).
  %% Messages will be grouped and inserted all at once.
% {mod_mam_muc_odbc_async_pool_writer, []},

  %% Load mod_mam_odbc_user too.

  %% Enable MAM for MUC
% {mod_mam_muc, [{host, "muc.@HOST@"}]}

  %%
  %% MAM configuration examples
  %%

  %% Only MUC, no user-defined preferences, good performance.
% {mod_mam_odbc_user, [muc]},
% {mod_mam_cache_user, [muc]},
% {mod_mam_muc_odbc_arch, [no_writer]},
% {mod_mam_muc_odbc_async_pool_writer, []},
% {mod_mam_muc, [{host, "muc.@HOST@"}]}

  %% Only archives for c2c messages, good performance.
 {mod_mam_odbc_user, [pm]},
 {mod_mam_cache_user, [pm]},
% {mod_mam_mnesia_dirty_prefs, [pm]},
 {mod_mam_odbc_arch, [pm]},
% {mod_mam_odbc_async_pool_writer, [pm]},
 {mod_mam, []},

  %% Basic configuration for c2c messages, bad performance, easy to debug.
% {mod_mam_odbc_user, [pm]},
% {mod_mam_odbc_prefs, [pm]},
% {mod_mam_odbc_arch, [pm]},
% {mod_mam, []}

  %% Cassandra c2c conversations.
  %% All queries MUST contain "with" element.
  %% No custom settings supported (always archive).
% {mod_mam_odbc_user, [pm]},
% {mod_mam_cache_user, [pm]},
% {mod_mam_con_ca_arch, [pm]},
% {mod_mam, []}

  %% Cassandra muc conversations.
  %% No custom settings supported (always archive).
% {mod_mam_odbc_user, [muc]},
% {mod_mam_cache_user, [muc]},
% {mod_mam_muc_ca_arch, []},
% {mod_mam_muc, [{host, "muc.@HOST@"}]},
%% Ephemeral / persistent key storage

  %% Ephemeral / persistent key storage
  {mod_keystore, [{keys, [
                          {token_secret, ram},
                          {provision_pre_shared, ram}
                         ]}]},

  %% Token based authentication, require mod_keystore
  {mod_auth_token, [{ {validity_period, access}, {60, minutes} },
                    { {validity_period, refresh}, {1, days} }]
  }

 ]}.

%%
%% Enable modules with custom options in a specific virtual host
%%
%%{host_config, "localhost",
%% [{ {add, modules},
%%   [
%%    {mod_some_module, []}
%%   ]
%%  }
%% ]}.

%%%.
%%%'

%%% $Id$

%%% Local Variables:
%%% mode: erlang
%%% End:
%%% vim: set filetype=erlang tabstop=8 foldmarker=%%%',%%%. foldmethod=marker:
%%%.

I don't know what is my mistake ? Hope that someone can help me.

Thanks.

michalwski commented 8 years ago

Hi @emnvn,

All looks correct at first glance. Could you trace the mod_auth_token and send as the captured trace?

emnvn commented 8 years ago

Hello @michalwski ,

I enable DEBUG LOG but I can't see anny error. I run MongooseIM on a VirtualBox CentOS 6.4. Can you remote to my computer to check log ? This is my full debug logs:

(mongooseim@localhost)2> 2016-08-17 00:23:14.689 [debug] <0.693.0>@mod_websockets:websocket_handle:182 Received: <<"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-OAUTH'>YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi8yRjM2ODM2QzVEQ0ExMjMxMTQ3MTM2ODE1ODQ3MTk0NgA2MzYzODU5MDk2NQBiOGE0NDUyZDdmYjU2ZmIzMzU4NWI2ODQyZDg0OTE3OWU2ZjAxNzIxMzEyZDE1ZGFjMmNjMDI2NWZlMDdjN2ZkMTg1YzE2ZDI3YmZlNjU2MmM0Yzc0NjdhM2FkNTgzMTk=</auth>">>
2016-08-17 00:23:14.690 [debug] <0.693.0>@mod_websockets:handle_text:247 handle_text2 Text: <<"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-OAUTH'>YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi8yRjM2ODM2QzVEQ0ExMjMxMTQ3MTM2ODE1ODQ3MTk0NgA2MzYzODU5MDk2NQBiOGE0NDUyZDdmYjU2ZmIzMzU4NWI2ODQyZDg0OTE3OWU2ZjAxNzIxMzEyZDE1ZGFjMmNjMDI2NWZlMDdjN2ZkMTg1YzE2ZDI3YmZlNjU2MmM0Yzc0NjdhM2FkNTgzMTk=</auth>">>, Req: {http_req,#Port<0.5909>,ranch_tcp,keepalive,<0.693.0>,<<"GET">>,'HTTP/1.1',{{10,32,52,247},60538},<<"10.32.52.156">>,undefined,5280,<<"/ws-xmpp/">>,undefined,<<>>,undefined,[],[{<<"host">>,<<"10.32.52.156:5280">>},{<<"user-agent">>,<<"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0">>},{<<"accept">>,<<"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8">>},{<<"accept-language">>,<<"en-US,en;q=0.5">>},{<<"accept-encoding">>,<<"gzip, deflate">>},{<<"sec-websocket-version">>,<<"13">>},{<<"origin">>,<<"http://localhost">>},{<<"sec-websocket-protocol">>,<<"xmpp">>},{<<"sec-websocket-extensions">>,<<"permessage-deflate">>},{<<"sec-websocket-key">>,<<"whheyqcxzZ4+4htjwQqXWA==">>},{<<"connection">>,<<"keep-alive, Upgrade">>},{<<"pragma">>,<<"no-cache">>},{<<"cache-control">>,<<"no-cache">>},{<<"upgrade">>,<<"websocket">>}],[{<<"sec-websocket-extensions">>,[{<<"permessage-deflate">>,[]}]},{<<"upgrade">>,[<<"websocket">>]},{<<"connection">>,[<<"keep-alive">>,<<"upgrade">>]}],undefined,[{websocket_version,13},{websocket_compress,false}],waiting,<<>>,undefined,false,done,[],<<>>,undefined}, State: {ws_state,<0.696.0>,open,{parser,<<>>,{config,true,true},[]},[],none} 
2016-08-17 00:23:14.690 [debug] <0.693.0>@mod_websockets:handle_text:250 handle_text2 NewParser: {parser,<<>>,{config,true,true},[]}, Elements: [{xmlel,<<"auth">>,[{<<"xmlns">>,<<"urn:ietf:params:xml:ns:xmpp-sasl">>},{<<"mechanism">>,<<"X-OAUTH">>}],[{xmlcdata,<<"YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi8yRjM2ODM2QzVEQ0ExMjMxMTQ3MTM2ODE1ODQ3MTk0NgA2MzYzODU5MDk2NQBiOGE0NDUyZDdmYjU2ZmIzMzU4NWI2ODQyZDg0OTE3OWU2ZjAxNzIxMzEyZDE1ZGFjMmNjMDI2NWZlMDdjN2ZkMTg1YzE2ZDI3YmZlNjU2MmM0Yzc0NjdhM2FkNTgzMTk=">>}]}], State1: {ws_state,<0.696.0>,open,{parser,<<>>,{config,true,true},[]},[],none} 
2016-08-17 00:23:14.690 [debug] <0.693.0>@mod_websockets:handle_text:253 case maybe_start_fsm: Req1 {http_req,#Port<0.5909>,ranch_tcp,keepalive,<0.693.0>,<<"GET">>,'HTTP/1.1',{{10,32,52,247},60538},<<"10.32.52.156">>,undefined,5280,<<"/ws-xmpp/">>,undefined,<<>>,undefined,[],[{<<"host">>,<<"10.32.52.156:5280">>},{<<"user-agent">>,<<"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0">>},{<<"accept">>,<<"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8">>},{<<"accept-language">>,<<"en-US,en;q=0.5">>},{<<"accept-encoding">>,<<"gzip, deflate">>},{<<"sec-websocket-version">>,<<"13">>},{<<"origin">>,<<"http://localhost">>},{<<"sec-websocket-protocol">>,<<"xmpp">>},{<<"sec-websocket-extensions">>,<<"permessage-deflate">>},{<<"sec-websocket-key">>,<<"whheyqcxzZ4+4htjwQqXWA==">>},{<<"connection">>,<<"keep-alive, Upgrade">>},{<<"pragma">>,<<"no-cache">>},{<<"cache-control">>,<<"no-cache">>},{<<"upgrade">>,<<"websocket">>}],[{<<"sec-websocket-extensions">>,[{<<"permessage-deflate">>,[]}]},{<<"upgrade">>,[<<"websocket">>]},{<<"connection">>,[<<"keep-alive">>,<<"upgrade">>]}],undefined,[{websocket_version,13},{websocket_compress,false}],waiting,<<>>,undefined,false,done,[],<<>>,undefined}, State2: {ws_state,<0.696.0>,open,{parser,<<>>,{config,true,true},[]},[],none} 
2016-08-17 00:23:14.690 [debug] <0.693.0>@mod_websockets:process_client_stream_start:366 EMNVN process_client_stream_start 0 OpenTag: open Elements: [{xmlel,<<"auth">>,[{<<"xmlns">>,<<"urn:ietf:params:xml:ns:xmpp-sasl">>},{<<"mechanism">>,<<"X-OAUTH">>}],[{xmlcdata,<<"YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi8yRjM2ODM2QzVEQ0ExMjMxMTQ3MTM2ODE1ODQ3MTk0NgA2MzYzODU5MDk2NQBiOGE0NDUyZDdmYjU2ZmIzMzU4NWI2ODQyZDg0OTE3OWU2ZjAxNzIxMzEyZDE1ZGFjMmNjMDI2NWZlMDdjN2ZkMTg1YzE2ZDI3YmZlNjU2MmM0Yzc0NjdhM2FkNTgzMTk=">>}]}] 
2016-08-17 00:23:14.690 [debug] <0.693.0>@mod_websockets:send_to_fsm:269 EMNVN send_to_fsm FSM: <0.696.0>, StreamElement: {xmlstreamelement,{xmlel,<<"auth">>,[{<<"xmlns">>,<<"urn:ietf:params:xml:ns:xmpp-sasl">>},{<<"mechanism">>,<<"X-OAUTH">>}],[{xmlcdata,<<"YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi8yRjM2ODM2QzVEQ0ExMjMxMTQ3MTM2ODE1ODQ3MTk0NgA2MzYzODU5MDk2NQBiOGE0NDUyZDdmYjU2ZmIzMzU4NWI2ODQyZDg0OTE3OWU2ZjAxNzIxMzEyZDE1ZGFjMmNjMDI2NWZlMDdjN2ZkMTg1YzE2ZDI3YmZlNjU2MmM0Yzc0NjdhM2FkNTgzMTk=">>}]}}

Thanks for your help.

michalwski commented 8 years ago

I was referring to the Erlang dbg. Let's make it ass simple as possible. Could you do the following?

  1. Connect to MongooseIM node:

    mongoseim debg
  2. Run the command (mind the ending dot .)

    recon_trace:calls({mod_auth_token, '_', fun(_) -> return_trace() end}, 100).

    This should return number grater than 0.

  3. Try to authenticate with token and send us the trace messages displayed on your console.
emnvn commented 8 years ago

Hi @michalwski,

I have execute there your steps:

  1. It connected to MongooseIM
  2. I saw the "18" number in console
  3. When I get tokens I can see this log from debug session:
14:3:05.295091 <0.1193.0> mod_auth_token:process_iq({jid,<<"test01">>,<<"dtsc.com.vn">>,<<"6E8B7ED679985E941471503772393947">>,
     <<"test01">>,<<"dtsc.com.vn">>,<<"6E8B7ED679985E941471503772393947">>}, {jid,<<"test01">>,<<"dtsc.com.vn">>,<<>>,<<"test01">>,<<"dtsc.com.vn">>,<<>>}, {iq,<<"f4504073-6774-4976-8436-99c09cc1e6b0:sendIQ">>,get,
    <<"erlang-solutions.com:xmpp:token-auth:0">>,<<>>,
    {xmlel,<<"query">>,
           [{<<"xmlns">>,<<"erlang-solutions.com:xmpp:token-auth:0">>}],
           []}})
14:3:05.384769 <0.1193.0> mod_auth_token:process_iq/3 --> {iq,
                                                           <<"f4504073-6774-4976-8436-99c09cc1e6b0:sendIQ">>,
                                                           result,
                                                           <<"erlang-solutions.com:xmpp:token-auth:0">>,
                                                           <<>>,
                                                           [{xmlel,
                                                             <<"items">>,
                                                             [{<<"xmlns">>,
                                                               <<"erlang-solutions.com:xmpp:token-auth:0">>}],
                                                             [{xmlel,
                                                               <<"access_token">>,
                                                               [{<<"xmlns">>,
                                                                 <<"erlang-solutions.com:xmpp:token-auth:0">>}],
                                                               [{xmlcdata,
                                                                 <<"YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi82RThCN0VENjc5OTg1RTk0MTQ3MTUwMzc3MjM5Mzk0NwA2MzYzODcyNjU4NQA4MThhODcxMGVhNzlmMGZlYTQ1YWZkNjE5MjA5MDMxN2ZhNDM4YjY5Y2M0NDA4MTMyYTY4YmM4MGFiOWE2ZmExOGNmMGU0NGM1OGQ4MDRmZGE0MzBjNjQwZTgxYTc3N2I=">>}]},
                                                              {xmlel,
                                                               <<"refresh_token">>,
                                                               [{<<"xmlns">>,
                                                                 <<"erlang-solutions.com:xmpp:token-auth:0">>}],
                                                               [{xmlcdata,
                                                             <<"cmVmcmVzaAB0ZXN0MDFAZHRzYy5jb20udm4vNkU4QjdFRDY3OTk4NUU5NDE0NzE1MDM3NzIzOTM5NDcANjM2Mzg4MDkzODUAMQA4ZTA4Zjk2NGFkMjY3YTA3ZDNmZjg0OGFhNzQ2NjdkNzQ5NWJlZTFiZjE3ZDZmNTA1NDFiNzMyY2I4MDZhYWVhZTdjNDU1NzNjODMyNTM2YTYzOWUxY2VkMWFiMjRjNzM=">>}]}]}]}

(mongooseim@localhost)2>

When I try to authenticate with token, I can't see any log in console. But If I attach from mongoose sesession I can see logs which is similar to logs that I have pasted in the issue:

(mongooseim@localhost)2> 2016-08-18 14:04:58.238 [debug] <0.1192.0>@mod_websockets:websocket_handle:182 Received: <<"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-OAUTH'>YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi82RThCN0VENjc5OTg1RTk0MTQ3MTUwMzc3MjM5Mzk0NwA2MzYzODcyNjU4NQA4MThhODcxMGVhNzlmMGZlYTQ1YWZkNjE5MjA5MDMxN2ZhNDM4YjY5Y2M0NDA4MTMyYTY4YmM4MGFiOWE2ZmExOGNmMGU0NGM1OGQ4MDRmZGE0MzBjNjQwZTgxYTc3N2I=</auth>">>
2016-08-18 14:04:58.239 [debug] <0.1192.0>@mod_websockets:handle_text:247 handle_text2 Text: <<"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-OAUTH'>YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi82RThCN0VENjc5OTg1RTk0MTQ3MTUwMzc3MjM5Mzk0NwA2MzYzODcyNjU4NQA4MThhODcxMGVhNzlmMGZlYTQ1YWZkNjE5MjA5MDMxN2ZhNDM4YjY5Y2M0NDA4MTMyYTY4YmM4MGFiOWE2ZmExOGNmMGU0NGM1OGQ4MDRmZGE0MzBjNjQwZTgxYTc3N2I=</auth>">>, Req: {http_req,#Port<0.6927>,ranch_tcp,keepalive,<0.1192.0>,<<"GET">>,'HTTP/1.1',{{10,12,10,140},54290},<<"10.12.10.89">>,undefined,5280,<<"/ws-xmpp/">>,undefined,<<>>,undefined,[],[{<<"host">>,<<"10.12.10.89:5280">>},{<<"user-agent">>,<<"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0">>},{<<"accept">>,<<"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8">>},{<<"accept-language">>,<<"en-US,en;q=0.5">>},{<<"accept-encoding">>,<<"gzip, deflate">>},{<<"sec-websocket-version">>,<<"13">>},{<<"origin">>,<<"http://localhost">>},{<<"sec-websocket-protocol">>,<<"xmpp">>},{<<"sec-websocket-extensions">>,<<"permessage-deflate">>},{<<"sec-websocket-key">>,<<"RpfKWo65pp/Ad2ak1ovTow==">>},{<<"connection">>,<<"keep-alive, Upgrade">>},{<<"pragma">>,<<"no-cache">>},{<<"cache-control">>,<<"no-cache">>},{<<"upgrade">>,<<"websocket">>}],[{<<"sec-websocket-extensions">>,[{<<"permessage-deflate">>,[]}]},{<<"upgrade">>,[<<"websocket">>]},{<<"connection">>,[<<"keep-alive">>,<<"upgrade">>]}],undefined,[{websocket_version,13},{websocket_compress,false}],waiting,<<>>,undefined,false,done,[],<<>>,undefined}, State: {ws_state,<0.1193.0>,open,{parser,<<>>,{config,true,true},[]},[],none} 
2016-08-18 14:04:58.240 [debug] <0.1192.0>@mod_websockets:handle_text:250 handle_text2 NewParser: {parser,<<>>,{config,true,true},[]}, Elements: [{xmlel,<<"auth">>,[{<<"xmlns">>,<<"urn:ietf:params:xml:ns:xmpp-sasl">>},{<<"mechanism">>,<<"X-OAUTH">>}],[{xmlcdata,<<"YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi82RThCN0VENjc5OTg1RTk0MTQ3MTUwMzc3MjM5Mzk0NwA2MzYzODcyNjU4NQA4MThhODcxMGVhNzlmMGZlYTQ1YWZkNjE5MjA5MDMxN2ZhNDM4YjY5Y2M0NDA4MTMyYTY4YmM4MGFiOWE2ZmExOGNmMGU0NGM1OGQ4MDRmZGE0MzBjNjQwZTgxYTc3N2I=">>}]}], State1: {ws_state,<0.1193.0>,open,{parser,<<>>,{config,true,true},[]},[],none} 
2016-08-18 14:04:58.241 [debug] <0.1192.0>@mod_websockets:handle_text:253 case maybe_start_fsm: Req1 {http_req,#Port<0.6927>,ranch_tcp,keepalive,<0.1192.0>,<<"GET">>,'HTTP/1.1',{{10,12,10,140},54290},<<"10.12.10.89">>,undefined,5280,<<"/ws-xmpp/">>,undefined,<<>>,undefined,[],[{<<"host">>,<<"10.12.10.89:5280">>},{<<"user-agent">>,<<"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0">>},{<<"accept">>,<<"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8">>},{<<"accept-language">>,<<"en-US,en;q=0.5">>},{<<"accept-encoding">>,<<"gzip, deflate">>},{<<"sec-websocket-version">>,<<"13">>},{<<"origin">>,<<"http://localhost">>},{<<"sec-websocket-protocol">>,<<"xmpp">>},{<<"sec-websocket-extensions">>,<<"permessage-deflate">>},{<<"sec-websocket-key">>,<<"RpfKWo65pp/Ad2ak1ovTow==">>},{<<"connection">>,<<"keep-alive, Upgrade">>},{<<"pragma">>,<<"no-cache">>},{<<"cache-control">>,<<"no-cache">>},{<<"upgrade">>,<<"websocket">>}],[{<<"sec-websocket-extensions">>,[{<<"permessage-deflate">>,[]}]},{<<"upgrade">>,[<<"websocket">>]},{<<"connection">>,[<<"keep-alive">>,<<"upgrade">>]}],undefined,[{websocket_version,13},{websocket_compress,false}],waiting,<<>>,undefined,false,done,[],<<>>,undefined}, State2: {ws_state,<0.1193.0>,open,{parser,<<>>,{config,true,true},[]},[],none} 
2016-08-18 14:04:58.243 [debug] <0.1192.0>@mod_websockets:process_client_stream_start:366 EMNVN process_client_stream_start 0 OpenTag: open Elements: [{xmlel,<<"auth">>,[{<<"xmlns">>,<<"urn:ietf:params:xml:ns:xmpp-sasl">>},{<<"mechanism">>,<<"X-OAUTH">>}],[{xmlcdata,<<"YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi82RThCN0VENjc5OTg1RTk0MTQ3MTUwMzc3MjM5Mzk0NwA2MzYzODcyNjU4NQA4MThhODcxMGVhNzlmMGZlYTQ1YWZkNjE5MjA5MDMxN2ZhNDM4YjY5Y2M0NDA4MTMyYTY4YmM4MGFiOWE2ZmExOGNmMGU0NGM1OGQ4MDRmZGE0MzBjNjQwZTgxYTc3N2I=">>}]}] 
2016-08-18 14:04:58.243 [debug] <0.1192.0>@mod_websockets:send_to_fsm:269 EMNVN send_to_fsm FSM: <0.1193.0>, StreamElement: {xmlstreamelement,{xmlel,<<"auth">>,[{<<"xmlns">>,<<"urn:ietf:params:xml:ns:xmpp-sasl">>},{<<"mechanism">>,<<"X-OAUTH">>}],[{xmlcdata,<<"YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi82RThCN0VENjc5OTg1RTk0MTQ3MTUwMzc3MjM5Mzk0NwA2MzYzODcyNjU4NQA4MThhODcxMGVhNzlmMGZlYTQ1YWZkNjE5MjA5MDMxN2ZhNDM4YjY5Y2M0NDA4MTMyYTY4YmM4MGFiOWE2ZmExOGNmMGU0NGM1OGQ4MDRmZGE0MzBjNjQwZTgxYTc3N2I=">>}]}} 

Hope that you can show me the problems, Thanks.

michalwski commented 8 years ago

Thanks @emnvn, that helps. I need you to trace module cyrsasl_oauth (similar steps as before, just change the recon_trace:calls accordingly) which is responsible for the token auth method. In the end it should call mod_auth_token to check the provided token but I don't see this in the trace you provided.

Also, it would be very helpful if you could provide all the WebSocket packets your client app sends to the server in your test.

emnvn commented 8 years ago

Hello @michalwski,

First Thanks for your response soon. I have make steps as you described but I can't see any log which relate to cyrsasl_oauth.

After run recon_trace:calls with cyrsasl_oauth I saw the response number of "6"

I have attached the wireshark capture files where 10.12.10.140 is my xmpp client IP 10.12.10.89 is my xmpp server IP

Thanks very much for your help! mod_auth_token_trace.zip

emnvn commented 8 years ago

Hi @ludwikbukowski ,

Do you know what is the root cause ?

Thanks!

ludwikbukowski commented 8 years ago

@emnvn yes, you have to reset stream before authentication with token. You cannot authenticate when you're already logged in :)

emnvn commented 8 years ago

Hello @ludwikbukowski,

I have used strophejs as a websocket client I have tried these options but the result is still the problem:

<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-OAUTH'>YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi9GQ0NCODJEQTZDQkNGQTBEMTQ3MTQzMjQ3NjEzNDgyADYzNjM4NjU1MjgyAGQyYWZmM2I0MjE1NjkzZjBmMTllMTIwN2FiMDA5YTVmOTM3OTBlMDY0MTgxN2RiZjY5MmZlN2UwMWVkODcwNDk3ZmVlNWRmYWE4OGM3Y2I4ZDc4Njk2MTY0NjYyNDhmNw==</auth>

The result still the same, server don't response any message.

Thanks &Best regards.

ludwikbukowski commented 8 years ago

Can you provide me more Mongooseim logs? e.g logs from whole session, not only when the <auth> stanza is sent?

emnvn commented 8 years ago

Hi @ludwikbukowski,

I can only see these logs

(mongooseim@localhost)2> 2016-08-18 14:04:58.238 [debug] <0.1192.0>@mod_websockets:websocket_handle:182 Received: <<"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-OAUTH'>YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi82RThCN0VENjc5OTg1RTk0MTQ3MTUwMzc3MjM5Mzk0NwA2MzYzODcyNjU4NQA4MThhODcxMGVhNzlmMGZlYTQ1YWZkNjE5MjA5MDMxN2ZhNDM4YjY5Y2M0NDA4MTMyYTY4YmM4MGFiOWE2ZmExOGNmMGU0NGM1OGQ4MDRmZGE0MzBjNjQwZTgxYTc3N2I=</auth>">>
2016-08-18 14:04:58.239 [debug] <0.1192.0>@mod_websockets:handle_text:247 handle_text2 Text: <<"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-OAUTH'>YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi82RThCN0VENjc5OTg1RTk0MTQ3MTUwMzc3MjM5Mzk0NwA2MzYzODcyNjU4NQA4MThhODcxMGVhNzlmMGZlYTQ1YWZkNjE5MjA5MDMxN2ZhNDM4YjY5Y2M0NDA4MTMyYTY4YmM4MGFiOWE2ZmExOGNmMGU0NGM1OGQ4MDRmZGE0MzBjNjQwZTgxYTc3N2I=</auth>">>, Req: {http_req,#Port<0.6927>,ranch_tcp,keepalive,<0.1192.0>,<<"GET">>,'HTTP/1.1',{{10,12,10,140},54290},<<"10.12.10.89">>,undefined,5280,<<"/ws-xmpp/">>,undefined,<<>>,undefined,[],[{<<"host">>,<<"10.12.10.89:5280">>},{<<"user-agent">>,<<"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0">>},{<<"accept">>,<<"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8">>},{<<"accept-language">>,<<"en-US,en;q=0.5">>},{<<"accept-encoding">>,<<"gzip, deflate">>},{<<"sec-websocket-version">>,<<"13">>},{<<"origin">>,<<"http://localhost">>},{<<"sec-websocket-protocol">>,<<"xmpp">>},{<<"sec-websocket-extensions">>,<<"permessage-deflate">>},{<<"sec-websocket-key">>,<<"RpfKWo65pp/Ad2ak1ovTow==">>},{<<"connection">>,<<"keep-alive, Upgrade">>},{<<"pragma">>,<<"no-cache">>},{<<"cache-control">>,<<"no-cache">>},{<<"upgrade">>,<<"websocket">>}],[{<<"sec-websocket-extensions">>,[{<<"permessage-deflate">>,[]}]},{<<"upgrade">>,[<<"websocket">>]},{<<"connection">>,[<<"keep-alive">>,<<"upgrade">>]}],undefined,[{websocket_version,13},{websocket_compress,false}],waiting,<<>>,undefined,false,done,[],<<>>,undefined}, State: {ws_state,<0.1193.0>,open,{parser,<<>>,{config,true,true},[]},[],none} 
2016-08-18 14:04:58.240 [debug] <0.1192.0>@mod_websockets:handle_text:250 handle_text2 NewParser: {parser,<<>>,{config,true,true},[]}, Elements: [{xmlel,<<"auth">>,[{<<"xmlns">>,<<"urn:ietf:params:xml:ns:xmpp-sasl">>},{<<"mechanism">>,<<"X-OAUTH">>}],[{xmlcdata,<<"YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi82RThCN0VENjc5OTg1RTk0MTQ3MTUwMzc3MjM5Mzk0NwA2MzYzODcyNjU4NQA4MThhODcxMGVhNzlmMGZlYTQ1YWZkNjE5MjA5MDMxN2ZhNDM4YjY5Y2M0NDA4MTMyYTY4YmM4MGFiOWE2ZmExOGNmMGU0NGM1OGQ4MDRmZGE0MzBjNjQwZTgxYTc3N2I=">>}]}], State1: {ws_state,<0.1193.0>,open,{parser,<<>>,{config,true,true},[]},[],none} 
2016-08-18 14:04:58.241 [debug] <0.1192.0>@mod_websockets:handle_text:253 case maybe_start_fsm: Req1 {http_req,#Port<0.6927>,ranch_tcp,keepalive,<0.1192.0>,<<"GET">>,'HTTP/1.1',{{10,12,10,140},54290},<<"10.12.10.89">>,undefined,5280,<<"/ws-xmpp/">>,undefined,<<>>,undefined,[],[{<<"host">>,<<"10.12.10.89:5280">>},{<<"user-agent">>,<<"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0">>},{<<"accept">>,<<"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8">>},{<<"accept-language">>,<<"en-US,en;q=0.5">>},{<<"accept-encoding">>,<<"gzip, deflate">>},{<<"sec-websocket-version">>,<<"13">>},{<<"origin">>,<<"http://localhost">>},{<<"sec-websocket-protocol">>,<<"xmpp">>},{<<"sec-websocket-extensions">>,<<"permessage-deflate">>},{<<"sec-websocket-key">>,<<"RpfKWo65pp/Ad2ak1ovTow==">>},{<<"connection">>,<<"keep-alive, Upgrade">>},{<<"pragma">>,<<"no-cache">>},{<<"cache-control">>,<<"no-cache">>},{<<"upgrade">>,<<"websocket">>}],[{<<"sec-websocket-extensions">>,[{<<"permessage-deflate">>,[]}]},{<<"upgrade">>,[<<"websocket">>]},{<<"connection">>,[<<"keep-alive">>,<<"upgrade">>]}],undefined,[{websocket_version,13},{websocket_compress,false}],waiting,<<>>,undefined,false,done,[],<<>>,undefined}, State2: {ws_state,<0.1193.0>,open,{parser,<<>>,{config,true,true},[]},[],none} 
2016-08-18 14:04:58.243 [debug] <0.1192.0>@mod_websockets:process_client_stream_start:366 EMNVN process_client_stream_start 0 OpenTag: open Elements: [{xmlel,<<"auth">>,[{<<"xmlns">>,<<"urn:ietf:params:xml:ns:xmpp-sasl">>},{<<"mechanism">>,<<"X-OAUTH">>}],[{xmlcdata,<<"YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi82RThCN0VENjc5OTg1RTk0MTQ3MTUwMzc3MjM5Mzk0NwA2MzYzODcyNjU4NQA4MThhODcxMGVhNzlmMGZlYTQ1YWZkNjE5MjA5MDMxN2ZhNDM4YjY5Y2M0NDA4MTMyYTY4YmM4MGFiOWE2ZmExOGNmMGU0NGM1OGQ4MDRmZGE0MzBjNjQwZTgxYTc3N2I=">>}]}] 
2016-08-18 14:04:58.243 [debug] <0.1192.0>@mod_websockets:send_to_fsm:269 EMNVN send_to_fsm FSM: <0.1193.0>, StreamElement: {xmlstreamelement,{xmlel,<<"auth">>,[{<<"xmlns">>,<<"urn:ietf:params:xml:ns:xmpp-sasl">>},{<<"mechanism">>,<<"X-OAUTH">>}],[{xmlcdata,<<"YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi82RThCN0VENjc5OTg1RTk0MTQ3MTUwMzc3MjM5Mzk0NwA2MzYzODcyNjU4NQA4MThhODcxMGVhNzlmMGZlYTQ1YWZkNjE5MjA5MDMxN2ZhNDM4YjY5Y2M0NDA4MTMyYTY4YmM4MGFiOWE2ZmExOGNmMGU0NGM1OGQ4MDRmZGE0MzBjNjQwZTgxYTc3N2I=">>}]}} 

It if is not enough, can you show me how to see those logs ?

Thanks.

ludwikbukowski commented 8 years ago

just before websocket_handle:182 Received: <<"<auth (...) log you should be able to see following line:

[debug] <0.1157.0>@mod_websockets:websocket_handle:182 Received: <<"<open xmlns='urn:ietf:params:xml:ns:xmpp-framing' to='localhost' version='1.0'/>">>

If you don't have it it means that your client didn't reset the stream. Basically, the scenario for acquiring the access token and authentication with it should look like:

(client already connected)

Client: 
<iq to='geralt_s@localhost' type='get' id='1bdc3eb1f89e28810f93b147e4870a90'>
<query xmlns='erlang-solutions.com:xmpp:token-auth:0'/>
</iq>

Server: 
<iq from='geralt_s@localhost' to='geralt_s@localhost/res'
 id='55850c43-e9e7-4508-b4e6-fc10a40f4c8b:sendIQ' type='result' xmlns='jabber:client'>
<items xmlns='erlang-solutions.com:xmpp:token-auth:0'>
<access_token xmlns='erlang-solutions.com:xmpp:token-auth:0'>
YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi84N0IwRUE3RjFCRUUwN0MwMTQ2OTc3ODQ4NDMxNDYxOAA2MzYzNzAwMzQ1MQAwMmRlYzM0MTQyNzczOTY5ZTFlMjQzOGM2OGNhZDA4MGVjZjMzMjViNTIzOTZkMmE0YTU0ZjMyNDJlNmJhZjRlZTUzMTI2NDc3NWM5MWM0MmViMTNmMTRjOTQ3ZDhlOTM=
</access_token>
<refresh_token xmlns='erlang-solutions.com:xmpp:token-auth:0'>
cmVmcmVzaAB0ZXN0MDFAZHRzYy5jb20udm4vODdCMEVBN0YxQkVFMDdDMDE0Njk3Nzg0ODQzMTQ2MTgANjM2MzcwODYyNTEAMQBiOTE2NGUwNDc1MGExNDFlZTVlZjVhNWJjNGFmZmU3ODc2Mzc4MzFiZDY1MmZiYjZjMjE4NWU4ZGM5OWU0NjI2ZDdhNzJkODA2YWNlYjU4OGY0NTY5ZTE4OWVkZmY3Y2U=
> </refresh_token>
</items>
</iq>

C:
<close xmlns='urn:ietf:params:xml:ns:xmpp-framing'/>

S:
<close xmlns='urn:ietf:params:xml:ns:xmpp-framing'/>

(now client reset the websocket stream)

C: 
<open xmlns='urn:ietf:params:xml:ns:xmpp-framing' to='localhost' version='1.0'/>

S: 
<open version='1.0' xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-framing' 
id='839F0854209050BC' from='localhost'/>

S: 
<features xmlns='http://etherx.jabber.org/streams'>
<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
<mechanism>PLAIN</mechanism>
<mechanism>X-OAUTH</mechanism>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>SCRAM-SHA-1</mechanism>
</mechanisms>
<register xmlns='http://jabber.org/features/iq-register'/>
<sm xmlns='urn:xmpp:sm:3'/>
</features>

C: 
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-OAUTH'>YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi9GQ0NCODJEQTZDQkNGQTBEMTQ3MTQzMjQ3NjEzNDgyADYzNjM4NjU1MjgyAGQyYWZmM2I0MjE1NjkzZjBmMTllMTIwN2FiMDA5YTVmOTM3OTBlMDY0MTgxN2RiZjY5MmZlN2UwMWVkODcwNDk3ZmVlNWRmYWE4OGM3Y2I4ZDc4Njk2MTY0NjYyNDhmNw==</auth>

S:
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
emnvn commented 8 years ago

Hi @ludwikbukowski,

I have tested with your flow, Token Authen work now. But there is some issues which related it, I will try to solve it.

Thanks @ludwikbukowski and @michalwski for your help.

Best Regards,

ludwikbukowski commented 8 years ago

@emnvn I'm glad that you managed it, if you have any other questions, do not hesitate to ask here! if not, please close the issue.

vkatsuba commented 6 years ago

Hi all, I have a problem after authorization. I have a feeling that I'm doing something wrong, if you can, please help sort it out. So, after authorization

C: 
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-OAUTH'>YWNjZXNzAHRlc3QwMUBkdHNjLmNvbS52bi9GQ0NCODJEQTZDQkNGQTBEMTQ3MTQzMjQ3NjEzNDgyADYzNjM4NjU1MjgyAGQyYWZmM2I0MjE1NjkzZjBmMTllMTIwN2FiMDA5YTVmOTM3OTBlMDY0MTgxN2RiZjY5MmZlN2UwMWVkODcwNDk3ZmVlNWRmYWE4OGM3Y2I4ZDc4Njk2MTY0NjYyNDhmNw==</auth>

S:
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>

When I try send any other XML packet, by eg: message, I get second response

S:
<error xmlns='http://etherx.jabber.org/streams'><xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/></error>

After some investigation I see that my package always falls into ejabberd_c2s:wait_for_stream/2

...
wait_for_stream({xmlstreamelement, _S}, StateData) ->
    c2s_stream_error(?INVALID_XML_ERR, StateData);
...

But I don't understand why... please help me with this problem, thanks!

fenek commented 6 years ago

Hi @vkatsuba

Please do not resurrect old, closed issues. :) Please open a new ticket for your problem.

vkatsuba commented 6 years ago

Hi @fenek, I see, sorry for this. I created a new ticket https://github.com/esl/MongooseIM/issues/1840 Regards