Not logged in. · Lost password · Register
Forum: MatriX and XmppDotNet RSS
Avatar
girish venkata #1
User title: Girish Venkata
Member since Nov 2017 · 5 posts
Group memberships: Members
Show profile · Link to this post
Subject: oAuth in Matrix vNext
Hey Alex is it possible to do oAuth in Matrix vNext with ejabbered ? If yes please provide snippet. Thank you.
Avatar
Alex #2
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Yes, you have to do the following:

  • Write you custom AuthProcessor class which implements ISaslProcessor
  • Write you own authentication handler which implements IAuthenticate and responsible for selecting you new AuthProcessor
  • Set your authentication handler in XmppClient.SalsHandler

Here are 2 sample classes:

  1. using System.Text;
  2. using System.Threading.Tasks;
  3. using Matrix.Xml;
  4. using Matrix.Xmpp.Sasl;
  5. using System.Threading;
  6.  
  7. namespace Matrix.Sasl.Plain
  8. {
  9.     public class PlainProcessor : ISaslProcessor
  10.     {
  11.         public async Task<XmppXElement> AuthenticateClientAsync(XmppClient xmppClient, CancellationToken cancellationToken)
  12.         {
  13.             var authMessage = new Auth(SaslMechanism.Plain, GetMessage(xmppClient));
  14.  
  15.             return
  16.                 await xmppClient.SendAsync<Success, Failure>(authMessage, cancellationToken);
  17.         }
  18.  
  19.         private string GetMessage(XmppClient xmppClient)
  20.         {
  21.             // NULL Username NULL Password
  22.             var sb = new StringBuilder();
  23.             sb.Append((char)0);
  24.             sb.Append(xmppClient.Username);
  25.             sb.Append((char)0);
  26.             sb.Append(xmppClient.Password);
  27.             byte[] msg = Encoding.UTF8.GetBytes(sb.ToString());
  28.             return Convert.ToBase64String(msg, 0, msg.Length);
  29.         }
  30.     }
  31. }

  1. using System.Threading.Tasks;
  2. using Matrix.Sasl.Digest;
  3. using Matrix.Sasl.Plain;
  4. using Matrix.Sasl.Scram;
  5. using Matrix.Xml;
  6. using Matrix.Xmpp.Sasl;
  7. using System.Threading;
  8.  
  9. namespace Matrix.Sasl
  10. {
  11.     public class DefaultSaslHandler : IAuthenticate
  12.     {
  13.         public async Task<XmppXElement> AuthenticateAsync(Mechanisms mechanisms, XmppClient xmppClient, CancellationToken cancellationToken)
  14.         {
  15.             ISaslProcessor saslProc = null;
  16.             if (mechanisms.SupportsMechanism(SaslMechanism.ScramSha1))
  17.                 saslProc = new ScramSha1Processor();
  18.  
  19.             else if (mechanisms.SupportsMechanism(SaslMechanism.DigestMd5))
  20.                 saslProc = new DigestMd5Processor();
  21.  
  22.             else if (mechanisms.SupportsMechanism(SaslMechanism.Plain))
  23.                 saslProc = new PlainProcessor();
  24.  
  25.             return await saslProc.AuthenticateClientAsync(xmppClient, cancellationToken);
  26.         }
  27.     }
  28. }
Avatar
girish venkata #3
User title: Girish Venkata
Member since Nov 2017 · 5 posts
Group memberships: Members
Show profile · Link to this post
Subject: oAuth error in Matrix vNext
Hi Alex thanks for the snippet. I have modfied the classes which you have provided. Below is my classes and Code where i am assiging XmppClient.SalsHandler.
But i am getting below error at  XmppXElement x  = await saslProc.AuthenticateClientAsync(xmppClient, cancellationToken);.
Please let me know if i am doing it wrong.

  1. using System.Threading.Tasks;
  2. using Matrix.Sasl.Digest;
  3. using Matrix.Sasl.Plain;
  4. using Matrix.Sasl.Scram;
  5. using Matrix.Xml;
  6. using Matrix.Xmpp.Sasl;
  7. using System.Threading;
  8. using Matrix.Sasl;
  9. using Matrix;
  10.  
  11. namespace com.Helpers
  12. {
  13.     public class MyDefaultSaslHandler : IAuthenticate
  14.     {
  15.         public async Task<XmppXElement> AuthenticateAsync(Mechanisms mechanisms, XmppClient xmppClient, CancellationToken cancellationToken)
  16.         {
  17.             MyPlainProcessor saslProc = new MyPlainProcessor();
  18.             XmppXElement x  = await saslProc.AuthenticateClientAsync(xmppClient, cancellationToken);
  19.             return x;
  20.         }
  21.     }
  22. }


  1. using System.Text;
  2. using System.Threading.Tasks;
  3. using Matrix.Xml;
  4. using Matrix.Xmpp.Sasl;
  5. using System.Threading;
  6. using Matrix.Sasl;
  7. using Matrix;
  8. using System;
  9.  
  10. namespace com.Helpers
  11. {
  12.     public class MyPlainProcessor : ISaslProcessor
  13.     {
  14.         public async Task<XmppXElement> AuthenticateClientAsync(XmppClient xmppClient, CancellationToken cancellationToken)
  15.         {
  16.             try
  17.             {
  18.                 var authMessage = new Auth(SaslMechanism.XOauth2, GetMessage(xmppClient));
  19.                 Success success = new Success();
  20.                 Failure failure = new Failure();
  21.                 XmppXElement x = await xmppClient.SendAsync<Success, Failure>(authMessage);
  22.                 return x;
  23.             }
  24.             catch (Exception ex)
  25.             {
  26.                 return null;
  27.             }
  28.         }
  29.  
  30.         private string GetMessage(XmppClient xmppClient)
  31.         {
  32.             // NULL Username NULL Password
  33.             var sb = new StringBuilder();
  34.             sb.Append((char)0);
  35.             sb.Append(xmppClient.Username);
  36.             sb.Append((char)0);
  37.             sb.Append(xmppClient.Password);
  38.             byte[] msg = Encoding.UTF8.GetBytes(sb.ToString());
  39.             return Convert.ToBase64String(msg, 0, msg.Length);
  40.         }
  41.     }
  42. }

Assiging SalsHandler

  1. CancellationToken cancellationToken = new CancellationToken();
  2. App.xmppClient.Username = "girish";
  3. App.xmppClient.XmppDomain = "server.com";
  4. App.xmppClient.Password = "password";
  5. App.xmppClient.HostnameResolver = new StaticNameResolver(IPAddress.Parse("x.x.x.x"), 5222);
  6. App.xmppClient.Port = 5222;              
  7. App.xmppClient.CertificateValidator = new AlwaysAcceptCertificateValidator();
  8.  
  9.  
  10. Matrix.Xmpp.Sasl.Mechanisms mechanisms = new Matrix.Xmpp.Sasl.Mechanisms();
  11. mechanisms.AddMechanism(Matrix.Xmpp.Sasl.SaslMechanism.XOauth2);
  12. MyDefaultSaslHandler myDefaultSaslHandler = new MyDefaultSaslHandler();
  13. App.xmppClient.SalsHandler = myDefaultSaslHandler;
  14. XmppXElement x = await myDefaultSaslHandler.AuthenticateAsync(mechanisms, xmppClient, cancellationToken);


ERROR -

  at Matrix.Network.Handlers.XmppStanzaHandler.<SendAsync>d__33.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Matrix.Network.Handlers.XmppStanzaHandler.<SendAsync>d__52`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Matrix.Network.Handlers.XmppStanzaHandler.<SendAsync>d__44`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Matrix.Network.Handlers.XmppStanzaHandler.<SendAsync>d__42`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Matrix.XmppConnection.<SendAsync>d__50`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Matrix.XmppConnection.<SendAsync>d__49`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at com.Helpers.MyPlainProcessor.<AuthenticateClientAsync>d__0.MoveNext()
This post was edited 3 times, last on 2017-11-16, 09:34 by Alex.
Edit reason: fixed code formatting
Avatar
Alex #4
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
In you last code snippet: you don't need line 10-14, remove it and just open the connection. MatriX should use you custom Sasl mechanism then automatically during login. You cannot call AuthenticateClientAsync yourself.

You have not implemented OAuth in MyPlainProcessor yet. You just copied GetMessage from my SASL PLAIN example, which is building a SASL PLAIN authentication message, not an OAUTH authentication message.
Avatar
girish venkata #5
User title: Girish Venkata
Member since Nov 2017 · 5 posts
Group memberships: Members
Show profile · Link to this post
Hey Alex thanks for the reply as per your last comments i have modified my code it working fine with SASL PLAIN. It would be great if you provide sample for oAuth.
Avatar
Alex #6
Member since Feb 2003 · 4449 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
you have to look in the ejabberd docs how the OAUTH authentication message should look.
Other servers we worked with in the past expexted a message like this:

base64("\0" + user_name + "\0" + oauth_token)

  1. private string GetMessage()
  2. {
  3.     var sb = new StringBuilder();
  4.     sb.Append( (char) 0 );
  5.     sb.Append(xmppClient.Username);
  6.     sb.Append( (char) 0 );
  7.     sb.Append(AuthorizationCode);
  8.            
  9.     byte[] msg = Encoding.UTF8.GetBytes(sb.ToString());
  10.     return Convert.ToBase64String(msg, 0, msg.Length)
  11. }

The AuthorizationCode code has be requested over HTTP APIs which is out of the scope of MatriX. Of course you can build that into your custom Auth classes.
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters: