Enable ADFS OAUTH2 for Mattermost 3.0

Mattermost

Since Mattermost released a new version with a lot of bug fixes, features and security enchantments i decided to release a second version for Mattermost with ADFS integration. This is a modified version of the May 17, 2016 stable Mattermost release v3.0.2

 

The advantages of using ADFS over other methods:

  • True SSO
  • Much more secure then LDAP or gitlab with LDAP
  • Proven for Enterprise

We have also made sure that the following features are available:

  • Other domains and forest can also use Mattermost if invited and a trusts exists
  • Authentication is based on AD SID so if a user is deleted or leaves the company a new user with the same domain username will get a new account with a different username. This is very important as it insures that users are unique and that even if you have two users with the same usernames in different domains they will each get there unique username and not effect one another.
  • Please note that emails do need to be unique, if a user tries to register with an email which is already in the system they will get an error informing them that a user already exists.
  • Visual error message if user is denied access from ADFS (Added on 21/06/2016)

Here is the guide on where to get it and how to configure it:

adfsm10adfsm9  adfsm3 adfsm4ADFS_Error_Mattermost

You will first need to download/compile and install the new version which can be found below:

You can download the compiled version from form https://github.com/lubenk/platform/releases or here:

Linux: https://gi-architects.co.uk/wp-content/uploads/2016/05/mattermost-team-linux-amd64.tar.gz
OSX: https://gi-architects.co.uk/wp-content/uploads/2016/05/mattermost-team-osx-amd64.tar.gz
Windows: https://gi-architects.co.uk/wp-content/uploads/2016/05/mattermost-team-windows-amd64.tar.gz

You can get the code from: https://github.com/lubenk/platform/tree/ADFS-3.0.2

 

Now that you have a working copy it’s time to configure ADFS 3.0 for OAUTH2.0 please use the instructions on : https://gi-architects.co.uk/2016/04/setup-oauth2-on-adfs-3-0/

with the following additions notes:

ClientID : Just generate one at https://www.guidgenerator.com/online-guid-generator.aspx (please make sure this guid is either more then or less then 26 characters).
Redirect URI : https://mattermost.local/signup/adfs/complete (where mattermost.local is the dns address of your mattermost app)
Relaying party identifier: you can just use your dns address of your mattermost app

The following Claim setup, please make sure the claims are exact, the rules name can be anything:

adfsm7

adfsm5

adfsm8

adfsm6

 

Once you setup adfs you need to configure mattermost, you can either do this via the config.json or via the admin interface as show below:

adfsm4

Please make sure you copy the public key of the ADFS root CA of your Service Communications Certificate in PEM format (the format that has —-BEGIN CERTIFICATE—- in it) into /usr/local/share/ca-certificates and name it with a .crt file extension, then run “sudo update-ca-certificates”.

You also need the public key of the signing certificate in PEM format somewhere on the server which you will need to reference in the settings.

And that is it you should have a working version with ADFS

 

Additional Update (21/06/2016)

I have coded in an error checking method if you deny access from the ADFS side so now it will display a nice message as show above.

If you want to configure ADFS to deny access for users based on group or email or other variables you can easily do by:

Go into you Mattermost reply party and edit the claims, once in go to Issuance Authorization Rules and delete the default one which permits access for everyone.

adfs_issuance_authorization1

Once deleted add a new Rule based on “Permit or Deny Users Based on an Incoming Claim”

adfs_issuance_authorization2

And chose the type of filtering for example i chose based on group membership and then allow.

adfs_issuance_authorization3

You can create multiple rules as well as create deny rule, just make sure you order them correctly.

27 thoughts on “Enable ADFS OAUTH2 for Mattermost 3.0

  1. Good to see SSO for Mattermost. Thank you.

    Instead of using local Active Directory, is it possible to use Azure ActiveDirectory and Office 365 ?

    1. Hello GitBit,

      Welcome to the site! Your question is very good and the short answer is unfortunately not.
      The long answer is that Azure oauth currently does not send an email claim in it’s token, this is a requirement by mattermost which does not function without a users email address.
      If Microsoft changes it’s claim to include email then it’s very straight forward to get it working, it will require a code change (form my side or who ever has the source) which will take about 30 minutes to implement and compile. I have tested Azure and have successfully connected and obtained the token but as mentioned without the email claim the system does not function.

      One more thing to add, it is possible to spin up ADFS servers in Azure and connect them to the Azure AD/ Office365, as such they will provide the oauth and that will work. Something like this: https://blogs.technet.microsoft.com/canitpro/2014/09/10/step-by-step-enabling-a-primary-ad-fs-server-in-azure-for-office365-single-sign-on/

      Regards,
      Luben

      1. Just to clarify the above is currently true for oauth authentications, for SAML which is available with Azure Premium you can get the email claim and set your own as well.

  2. Hey

    This is an awesome piece of work, great to see ADFS support!

    Did you have any plans to update your base package to Mattermost version 3.4.0? Looks like there has been a few security updates since 3.0.2. I looked at your branch but it looks like you made quite a few changes so wasn’t sure how big of a task that would be!

    Cheers

    1. Hello Dan,

      I am actually looking at upgrading it to 3.4.0 over the next few weeks, looks like there are quite a few changes but i don’t think it should be too hard to integrate it. I might try and make a post for the community regarding my changes so people can do it by themselves.

      Regards,
      Luben

        1. Hello Lamer,

          I have been thinking about getting the newest version and adding this is in but have not had any free time lately.
          Its a shame that they have made the SAML process part of the paid version and not the community one.

          Regards,
          Luben

    1. Hi Lamer,

      You can export the cert from windows (the adfs server) without the private key. Then you can convert it from DER to PEM (https://www.sslshopper.com/ssl-converter.html). The certificate actually requires to be in PEM. Then place it in a text file and you can rename it to .crt or whatever you want just make sure it matches whats in the config.

    1. Hello Lamer,

      Have you enabled the oauth2 endpoint ? By default it’s disabled and you need to enable it.
      Also make sure your oauth 2 app server trusts the root or intermidiate certificate of the adfs comunication certificate.

      Regards,
      Luben

          1. Hello Lamer,

            Looking at the errors specifically the “connection reset by peer”, I think you may have a certificate problem.
            There are two certificates involved with ADFS oauth2.0 communication and for a successful login both need to be working.

            The first is the token signing certificate which ADFS uses to sign the token. You in turn upload this certificate (only the public key) on the mattermost server and specify it’s location in the mattermost config. Make sure the account that Mattermost is running under has access to the certificate location and can read it.

            The second certificate that ADFS uses (and i think this is where your problem is) is the Service Communications certificate. This certificate is used in all TLS communication and it’s entire chain must be trusted. Mattermost and other oauth2 apps need to make a final call to ADFS before a user is allowed to enter to get the claims, this call is initiated on the mattermost server towards the ADFS server over TLS. If you don’t have the entire certificate chain trusted it will not work. You can test it yourself by going to the adfs server URL from the Mattermost server, for Linux just run curl against the https url like “https://adfs.local/adfs/ls/IdpInitiatedSignon.aspx”.

  3. Thank you to answering.

    I sure i got problem in certs, but i dont understand where…

    > You in turn upload this certificate (only the public key) on the mattermost server and specify it’s location in the mattermost config.
    root@mattermost:/etc/webcert# cat /mattermost/config/config.json|grep crt
    “PubKey”: “/etc/webcert/CA.crt”
    > Make sure the account that Mattermost is running under has access to the certificate location and can read it.
    root@mattermost:/etc/webcert# ps awux |grep platform |grep -v grep
    user 1254 0.0 0.9 277360 19376 ? Ssl Nov14 0:21 bin/platform

    root@mattermost:/etc/webcert# ls -l /etc/webcert/
    total 24
    -rw-r–r– 1 user user 4277 Nov 15 11:34 bundle.crt
    -rw-r–r– 1 user user 1956 Nov 14 14:24 CA.crt
    -rw-r–r– 1 user user 1708 Nov 14 14:00 mattermost.key
    -rw-r–r– 1 user user 2321 Nov 14 14:05 mattermost.pem
    -rw-r–r– 1 user user 1033 Nov 14 14:00 mattermost.req

    root@mattermost:/etc/webcert# ls -dl /etc/webcert/
    drwxr-xr-x 2 user user 4096 Nov 15 11:32 /etc/webcert/

    > You can test it yourself by going to the adfs server URL from the Mattermost server, for Linux just run curl against the https url like
    > “https://adfs.local/adfs/ls/IdpInitiatedSignon.aspx”.

    root@mattermost:/etc/webcert# curl “https://adfs.*************/adfs/ls/IdpInitiatedSignon.aspx”

    Вход
    ^C

    Nginx config:
    root@mattermost:/etc/webcert# cat /etc/nginx/sites-enabled/mattermost |grep ssl
    listen 443 ssl;
    ssl on;
    ssl_certificate /etc/webcert/bundle.crt;
    ssl_certificate_key /etc/webcert/mattermost.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ‘EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH’;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    root@mattermost:/etc/webcert#

    bundle.crt is
    # cat mattermost.pem CA.crt>bundle.crt

    CA.crt must be without chain, correct?

    1. user@mattermost:/etc/webcert$ openssl verify -verbose -CAfile CA.crt bundle.crt
      bundle.crt: OK

      and

      openssl x509 -noout -modulus -in bundle.crt | openssl md5
      openssl rsa -noout -modulus -in mattermost.key | openssl md5

      is same

      1. Hey mate,

        you are correct in saying CA.crt must be without chain, your signing certificate look ok and i think it’s not the problem.
        The problem is in my opinion with the Service Communication certificate, i think you are missing it’s chain and TLS cannot be established.

        So download the chain for the Service Communication certificate that’s the one highlighted here: https://gi-architects.co.uk/adfs-communication-cert/. then you need to add it to the trusted root certificate store on the mattremost server. Instructions can be found here: http://kb.kerio.com/product/kerio-connect/server-configuration/ssl-certificates/adding-trusted-root-certificates-to-the-server-1605.html

        1. Exported in der format without private key.

          user@mattermost:/etc/webcert$ openssl x509 -inform der -in adfs.cer -out adfs.crt
          user@mattermost:/etc/webcert$ sudo cp adfs.crt /usr/local/share/ca-certificates/
          user@mattermost:/etc/webcert$ sudo update-ca-certificates
          Updating certificates in /etc/ssl/certs… 1 added, 0 removed; done.
          Running hooks in /etc/ca-certificates/update.d….done.

          rebooted… and got same error :\
          I maked something wrong?

          PS Also while i exported cerificate i looked on strange thing –
          https://s11.postimg.org/psfymvrv7/adfs1.png
          First and second picture – communication cert, token signing and decrypting have error like this picture. It is normal?

          1. Hey mate,

            So in your case you need to export the xxxxx.root.ca (thats the chain) and improted as you did above for adfs.cer on the mattermost server

            As for the error in your screenshot, that happens when you dont trust the certificate chain of the certificate. So when you look into the certification path of a cert every cert above it needs to be added to the trusted root store on the ADFS server like .root.ca . Those errors can cause problems however we dont use encryption for oauth2 so if its only on the encryption cert , that shouldn’t interfear

  4. ouch. One moment please.

    mattermost.key and mattermost.pem – for nginx

    CA.crt – is my domain.ROOT.CA cert.
    adfs.crt – this is service communication certificate, https://gi-architects.co.uk/adfs-communication-cert/

    Also, adfs.crt in Public key location in mattermost ADFS section (was CA.crt, my mistake)

    Both adfs.crt and CA.crt was placed in mattermost server in /usr/local/share/ca-certificates and updated.

    Correct?

    1. I think we are almost there 🙂

      So the CA.cet (domain.ROOT.CA) is in the root store that is correct you dont need to do anything else there.

      The adfs.crt you can remove from the mattermost server as you dont need it there.

      What i see you dont have is the token signing certificate. Thats the last certificate on the screenshot here https://gi-architects.co.uk/adfs-communication-cert// Export it, only the public key, place it in /etc/webcert/ and then modify the mattermost config “PubKey” to point to it. Make sure the user account can read it.

      And that should work

      1. No difference 🙂

        user@mattermost:~$ ll /etc/webcert/
        total 48
        drwxr-xr-x 2 user user 4096 Nov 18 12:36 ./
        drwxr-xr-x 94 root root 4096 Nov 18 12:38 ../
        -rw-rw-r– 1 user user 1978 Nov 18 12:36 adfs.cer
        -rw-rw-r– 1 user user 2736 Nov 18 12:36 adfs.crt
        -rw-r–r– 1 user user 4277 Nov 15 11:34 bundle.crt
        -rw-rw-r– 1 user user 1956 Nov 17 20:24 CA.crt
        -rw-r–r– 1 user user 1708 Nov 14 14:00 mattermost.key
        -rw-r–r– 1 user user 2321 Nov 14 14:05 mattermost.pem
        -rw-r–r– 1 user user 1033 Nov 14 14:00 mattermost.req
        -rw-rw-r– 1 user user 1054 Nov 18 12:34 sig.crt
        -rw-rw-r– 1 user user 738 Nov 18 12:32 signing.cer
        user@mattermost:~$ cat /mattermost/config/config.json|grep sig
        “PubKey”: “/etc/webcert/sig.crt”
        user@mattermost:~$ ls /usr/local/share/ca-certificates/
        adfs.crt bundle.crt CA.crt sig.crt

        and same error
        [EROR] /signup/adfs/complete:AuthorizeOAuthUser code=500 rid=aygr***********ahfubry uid= ip=192.168.100.41 Token request failed [details: Post https://adfs.*********/adfs/oauth2/token: read tcp 192.168.100.60:60257->192.168.100.7:443: read: connection reset by peer]

        192.168.100.60 mattermost
        192.168.100.7 adfs
        192.168.100.41 me ))

Leave a Reply