Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GUACAMOLE-103: Implement SAML Authentication Extension #254

Merged
merged 12 commits into from
Jun 24, 2020

Conversation

necouchman
Copy link
Contributor

Initial cut at a SAML authentication extension. Plenty of room for improvement, I'm sure - I welcome all comments/suggestions/changes. I'll kick off my own review, here, shortly.

Copy link
Contributor Author

@necouchman necouchman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's my initial self-review...appreciate any comments...

Copy link
Contributor Author

@necouchman necouchman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some licensing changes.

@UbuntuEvangelist
Copy link

@necouchman how i can get Guacamole working with CAS for SAML authentication

@necouchman
Copy link
Contributor Author

@saydulk http://guacamole.apache.org/support/

@Saphirim
Copy link

Hello,

out of interest: what are the latest plans to integrate SAML into a official release of guacamole?
We would evaluate guacamole for enterpriese usage, but SSO would be a really relevant feature here.

Thx & Regards,

Michael

@necouchman
Copy link
Contributor Author

@Saphirim As you can see, this is still in the works - it needs to be reviewed and probably has some work to do on it before it's ready. Should be pretty close, but we've also got some high-priority items we're trying to work for the next release, so not certain it will make it.

SSO is already available via other extensions - CAS, OpenID, and Header modules - so you have some options, but if you require SAML you'll have to wait for this 😄.

@tuxcrafter
Copy link

I would like to donate some money to speed up the SAML SSO and SLO support for guacamole. I am waiting to upgrade my pam auth with SLO and SSO. I am using an ipsilon SAML IdP and I would like to test the new extension when ready. If you need a test infrastructure you can contact me and I will share some accounts and an IdP and SP setup.

@necouchman
Copy link
Contributor Author

@tuxcrafter: You're welcome to go ahead and try the extension, now. It does not support SLO, yet, but should work with version 1.0.0 for logging in.

@tuxcrafter
Copy link

tuxcrafter commented Apr 26, 2019

@tuxcrafter: You're welcome to go ahead and try the extension, now. It does not support SLO, yet, but should work with version 1.0.0 for logging in.

@necouchman We compiled and install the saml extension but I can not figure out how to configure the saml settings.

I probably need to configure the following settings somewhere:

idp-entityId (metadata)
idp-singleLogoutService.url
idp-singleSignOnService.url
idp-x509cert
sp-privateKey
sp-x509cert

And have the extension generate the correct metadata file for guacamole saml, to be used in the idp.

Then it would be good to have a mapping options for the username and groups.

@LeBrad
Copy link

LeBrad commented May 17, 2019

@necouchman Could we get a sample configuration file for the saml extension? It would enable us to start hacking on our saml/guacamole setup.

@necouchman
Copy link
Contributor Author

@LeBrad @tuxcrafter
It's been a little while since I did any testing on this, but this is what I have in my guacamole.properties file for configuring the extension from when I wrote it a while back:

saml-idp-metadata: /etc/guacamole/saml-idp-metadata.xml
saml-entity-id: https://1.2.3.4/guacamole/api/tokens
saml-idp-url: https://4.3.2.1/cas/idp/profile/SAML2/Redirect/SSO
saml-callback-url: https://1.2.3.4/guacamole
saml-logout-url: https://4.3.2.1/cas/logout
saml-keystore-file: /etc/guacamole/saml-keystore
saml-keystore-password: secret
saml-pkey-password: secret

Note that if you have an XML metadata file from your SAML IDP, you should not need the rest of those details - all of those configuration items should be in the XML file. Anyway, test away, feel free to let me know if you run into any issues with it. I do need to rebase it against the latest master repo and redo some of the testing and make sure it's still good, but not sure when I'll get to that.

@LeBrad
Copy link

LeBrad commented May 17, 2019

Thanks for the properties.

  1. Where do we place the certificate for the IdP?
  2. Where do we place the certificates for the guacamole saml server, public and private?
  3. Where do we get the metadata of the guacamole saml server?
  4. How's the single log-out support coming?

Here's my config at the moment:

saml-idp-metadata: /etc/guacamole/saml-idp-metadata.xml
saml-entity-id: https://guacamole.example/guacamole/api/tokens                      
saml-idp-url: https://ipsilon03.mctest.nl/idp/saml2/SSO/Redirect                           
saml-callback-url: https://guacamole.example/guacamole                              
saml-logout-url: https://ipsilon03.mctest.nl/idp/logout

@necouchman
Copy link
Contributor Author

Here are the answers...I think...

  1. Where the certificate is placed will depend on whether you're configuring it with a Metadata file or with individual parameters. If you have a metadata file, all of the certificates should be in the metadata file. If you configure with individual parameters, then it'll be in the keystore file.
  2. Would imagine this is the same as item 1.
  3. The metadata file is generated by the IdP, so where you get it will depend on the IdP. It's been a while since I did it with the CAS system, but I think there was a URL that was accessed that triggered the generation onto the filesystem. Other IdPs probably have varying methods of generating it - I'd suggest consulting the documentation for the IdP. I also found a few online metadata generators that will do most of the work for you if the IdP doesn't do it.
  4. Ummmmmmmmm...slow. Haven't had much time to work on this, sadly - what's even sadder (more sad?) is that I haven't had much time to work on anything Guacamole-related lately ☹️

@Tyler-
Copy link

Tyler- commented Jun 22, 2019

Hi, I pulled this, and was attempting to test the SAML auth extension.

everything seems to be building / deploying fine. but the issue I have is with setting the configuration.

I specified the idp xml file :

saml-idp-metadata: /etc/guacamole/sample-saml.xml

I'm running with tomcat 7, and regardless of how I specify the saml-idp-metadata, or where I put the .xml file, i always get the same error :

ERROR c.o.saml2.settings.IdPMetadataParser - XML file'/etc/guacamole/sample-saml.xml' cannot be loaded.XML file '/etc/guacamole/sample-saml.xml' not found in the classpath

I've tried specifying it in relative / absolute paths

I've tried putting it in /etc/guacamole, $TOMCAT_HOME, $TOMCAT_BASE, $TOMCAT_HOME/lib, $TOMCAT_BASE/lib, the resources folder in the source code to get into the .jar extension. I added /etc/guacamole to the catalina properties common.loader, and shared.loader

if anyone has any ideas, I'd love to hear them.

thanks

@spaceone
Copy link

Adding myself to the CC list.

@mike-jumper mike-jumper changed the base branch from master to staging/1.2.0 February 22, 2020 02:02
@necouchman necouchman force-pushed the GUACAMOLE-103 branch 4 times, most recently from 5dde4bf to b16535f Compare March 19, 2020 19:24
@necouchman necouchman force-pushed the GUACAMOLE-103 branch 2 times, most recently from 8ffbc64 to 925af02 Compare April 2, 2020 03:27
@necouchman
Copy link
Contributor Author

Okay, quite a bit of refactoring done, here, and I've tested successfully against the CAS implementation of SAML.

@necouchman
Copy link
Contributor Author

Well, that was fun. Should all be rebased on the current staging/1.2.0 branch with the new field. Going to do some testing and review of the code to make sure it's all good, because that rebase was no fun. Lesson learned.

@mike-jumper
Copy link
Contributor

What happened that made this rebase particularly hairy?

@necouchman
Copy link
Contributor Author

What happened that made this rebase particularly hairy?

The changes to implement the common RedirectField class were intertwined at various stages along the way throughout the rest of the changes. In retrospect, I should have developed that separately from the other changes and then rebased.

Also, this has been going on for 18 months or so, now, I think - maybe 2 years at this point - so there were lots of version updates and license changes along the way. Extracting the RedirectField and squashing down the other changes was interesting :-).

@mike-jumper
Copy link
Contributor

Code-Refactoring

@necouchman
Copy link
Contributor Author

Yeah, pretty much.

Includes implementation of executor shutdown, and correctly removing
items from the shared response map.
Copy link
Contributor

@mike-jumper mike-jumper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I've re-reviewed things in their entirety. I find only two things which for sure should be fixed:

  • Unsafe use of remove() while iterating a Collection
  • A minor typo

and there are two things which may need to be fixed, depending on your view and technical reasoning behind the current approach:

  • Prompting the user for a standard username/password when an error is encountered with SAML, rather than presenting an error screen.
  • Generating parameter tokens without canonicalizing and prefixing the names.

Exception handling within the SAML extension has been updated such that
exceptions generate a Guacamole Error rather than a username/password
login.  Tokens now are canonicalized with a standard prefix.  Now using
an Iterator to handle SAMLResponseMap cleanup.
@necouchman
Copy link
Contributor Author

One additional thing I'm seeing in the SAML client - when the IdP redirects back to the Guacamole Client and the login completes successfully, the responseHash URL parameter is still on the URL. As long as the user navigates to another page this isn't a problem, as the navigation removes the parameter; however, if the user reloads the page or tries to go to logout, an error is received because it tries to process the responseHash parameter and cannot find it in the SAMLResponseMap.

Is there something I should do (similar to the OpenID extension, maybe?) to remove this after a successful login?

@mike-jumper
Copy link
Contributor

I don't think the OpenID extension removes this, either, but it handles the presence of an invalid token identically to the total absence of a token. You could do the same - log at the info or debug level that an invalid hash was received and then move forward requesting a new SAML response?

@necouchman
Copy link
Contributor Author

Ah, okay, yes - I've tweaked it so that it should behave that way - I'll verify when I get a moment to recompile and test.

@necouchman
Copy link
Contributor Author

Okay, redirect appears to be working okay, now. One more issue I need to fix, though - when you try to specify the saml-idp-metadata option with a metadata file it throws an error:

ERROR c.o.saml2.settings.IdPMetadataParser - XML file'/etc/guacamole/saml-idp-metadata.xml' cannot be loaded.XML file '/etc/guacamole/saml-idp-metadata.xml' not found in the classpath

I guess whatever method I've used to load the file doesn't accept absolutely paths, or requires a URI or something like that.

@necouchman
Copy link
Contributor Author

Okay, I switched the saml-idp-metadata parameter to be a URIGuacamoleProperty instead of FileGuacamoleProperty and this seems to have done the trick. It makes configuration a little bit nuanced, but actually provides the flexibility to have it pull metadata from either a local file (via a file:// URI) or a remote URI.

Copy link
Contributor

@mike-jumper mike-jumper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alrighty - odd that parseFileXML() is restricted to the classpath and does not touch the filesystem, but leveraging URLs and possible retrieval of remote XML seems a fine solution.

Given that the property now accepts a URL, I think it should be given a -url suffix to stay consistent with the other URL properties. Other than that, if your testing shows things are now working correctly, I'm good with these changes.

@necouchman
Copy link
Contributor Author

I've tested successfully with the CAS SAML provider, both with a metadata file (using a file:// URI) and with manually specifying the parameter for accessing the server. If I can find another SAML provider or two to test with I will try to get that done, but I don't have ready access to any aside from CAS.

Copy link
Contributor

@mike-jumper mike-jumper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

I'll try to test verify against G Suite's SAML, as well, but I think things are very well confirmed at this point.

@mike-jumper mike-jumper merged commit 1813501 into apache:staging/1.2.0 Jun 24, 2020
@puneetshukla-siemens
Copy link

@necouchman Hello can you provide information how to provide connection to user logged in with saml authentication?

@necouchman
Copy link
Contributor Author

@puneetshukla-siemens: This is a closed pull request, and is not intended to be a support forum. Please subscribe to the mailing list and ask your question, there:

http://guacamole.apache.org/support/

@JPedroGon
Copy link

I tried with OKTA pulling the metadata from a file. Problem I get is an endless loop between OKTA and the url callback. Somehow after OKTA authenticates successfully, Guacamole is not capturing that.

@necouchman
Copy link
Contributor Author

@JPedroGon: Please post your questions to the mailing list. This is a closed/merged pull request and is not designed to be a support forum.

http://guacamole.apache.org/support/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
10 participants