First version of imported doc (#1646)
@ -0,0 +1,225 @@ |
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help |
||||
help: |
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " applehelp to make an Apple Help Book"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " epub3 to make an epub3"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " xml to make Docutils-native XML files"
|
||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
@echo " coverage to run coverage check of the documentation (if enabled)"
|
||||
@echo " dummy to check syntax errors of document sources"
|
||||
|
||||
.PHONY: clean |
||||
clean: |
||||
rm -rf $(BUILDDIR)/*
|
||||
|
||||
.PHONY: html |
||||
html: |
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
.PHONY: dirhtml |
||||
dirhtml: |
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
.PHONY: singlehtml |
||||
singlehtml: |
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
.PHONY: pickle |
||||
pickle: |
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
.PHONY: json |
||||
json: |
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
.PHONY: htmlhelp |
||||
htmlhelp: |
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
.PHONY: qthelp |
||||
qthelp: |
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/LemonLDAPNG.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/LemonLDAPNG.qhc"
|
||||
|
||||
.PHONY: applehelp |
||||
applehelp: |
||||
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
|
||||
@echo
|
||||
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
|
||||
@echo "N.B. You won't be able to view it unless you put it in" \
|
||||
"~/Library/Documentation/Help or install it in your application" \
|
||||
"bundle."
|
||||
|
||||
.PHONY: devhelp |
||||
devhelp: |
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/LemonLDAPNG"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/LemonLDAPNG"
|
||||
@echo "# devhelp"
|
||||
|
||||
.PHONY: epub |
||||
epub: |
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
.PHONY: epub3 |
||||
epub3: |
||||
$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
|
||||
@echo
|
||||
@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
|
||||
|
||||
.PHONY: latex |
||||
latex: |
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
.PHONY: latexpdf |
||||
latexpdf: |
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
.PHONY: latexpdfja |
||||
latexpdfja: |
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
.PHONY: text |
||||
text: |
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
.PHONY: man |
||||
man: |
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
.PHONY: texinfo |
||||
texinfo: |
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
.PHONY: info |
||||
info: |
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
.PHONY: gettext |
||||
gettext: |
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
.PHONY: changes |
||||
changes: |
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
.PHONY: linkcheck |
||||
linkcheck: |
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
.PHONY: doctest |
||||
doctest: |
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
.PHONY: coverage |
||||
coverage: |
||||
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
|
||||
@echo "Testing of coverage in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/coverage/python.txt."
|
||||
|
||||
.PHONY: xml |
||||
xml: |
||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
||||
@echo
|
||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
||||
|
||||
.PHONY: pseudoxml |
||||
pseudoxml: |
||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
||||
@echo
|
||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
||||
|
||||
.PHONY: dummy |
||||
dummy: |
||||
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
|
||||
@echo
|
||||
@echo "Build finished. Dummy builder generates no files."
|
@ -0,0 +1,23 @@ |
||||
Using LemonLDAP::NG with Active-Directory |
||||
========================================= |
||||
|
||||
Authentication with login/password |
||||
---------------------------------- |
||||
|
||||
To use Active Directory as LDAP backend, you must change few things in |
||||
the manager : |
||||
|
||||
- Use "Active Directory" as authentication, userDB and |
||||
passwordDBbackends, |
||||
- Export sAMAccountName in a variable declared in |
||||
:doc:`exported variables<exportedvars>` |
||||
- Change the user attribute to store in Apache logs *("General |
||||
Parameters » Logs » REMOTE_USER")*: use the variable declared above |
||||
|
||||
Authentication with Kerberos |
||||
---------------------------- |
||||
|
||||
- Choose "Apache" as authentication module *("General Parameters » |
||||
Authentication modules » Authentication module")* |
||||
- :doc:`Configure the Apache server<authapache>` that host the portal |
||||
to use the Apache Kerberos authentication module |
@ -0,0 +1,76 @@ |
||||
Applications |
||||
============ |
||||
|
||||
How to integrate |
||||
---------------- |
||||
|
||||
To integrate a Web application in LL::NG, you have the following |
||||
possibilities: |
||||
|
||||
- Protect the application with the Handler, and push user identity |
||||
trough HTTP headers. This is how main Access Manager products, like |
||||
CA SiteMinder, are working. This also how Apache authentication |
||||
modules are working, so if your application is compatible with Apache |
||||
authentication (often called "external authentifcation"), then you |
||||
can use the Handler. |
||||
- Specific Handler: some applications can require a specific Handler, |
||||
to manage preauthentication process for example. |
||||
- CAS: your application is a CAS client, you can configure LL::NG as a |
||||
:doc:`CAS server<idpcas>`. |
||||
- SAML: your application is a SAML Service Provider, you can configure |
||||
LL::NG as a :doc:`SAML Identity Provider<idpsaml>`. |
||||
- OpenID Connect: your application is a OpenID Connect Relying Party, |
||||
you can configure LL::NG as a |
||||
:doc:`OpenID Connect Provider<idpopenidconnect>`. |
||||
|
||||
If none of above methods is available, you can try: |
||||
|
||||
- :doc:`HTTP Auth-Basic<applications/authbasic>`: replay Auth Basic |
||||
authentication |
||||
- :doc:`Form replay<formreplay>`: replay form based authentication |
||||
|
||||
Application list |
||||
---------------- |
||||
|
||||
================================================================= ==================================================== ============ ================ === ==== ==== |
||||
Application Configuration guide HTTP headers Specific Handler CAS SAML OIDC |
||||
================================================================= ==================================================== ============ ================ === ==== ==== |
||||
.. image:: applications/microsoft-adfs.png :doc:`ADFS<applications/adfs>` ✔ |
||||
.. image:: applications/alfresco_logo.png :doc:`Alfresco<applications/alfresco>` ✔ ✔ |
||||
.. image:: applications/logo_amazon_web_services.jpg :doc:`Amazon Web Services<applications/aws>` ✔ |
||||
.. image:: applications/logo-awx.png :doc:`AWX (Ansible Tower)<applications/awx>` ✔ |
||||
.. image:: applications/bugzilla_logo.png :doc:`Bugzilla<applications/bugzilla>` ✔ |
||||
.. image:: applications/csod_logo.png :doc:`Cornerstone<applications/cornerstone>` ✔ |
||||
.. image:: applications/discourse.jpg :doc:`Discourse<applications/discourse>` ✔ ✔ |
||||
.. image:: applications/django_logo.png :doc:`Django<applications/django>` ✔ |
||||
.. image:: applications/dokuwiki_logo.png :doc:`Dokuwiki<applications/dokuwiki>` ✔ |
||||
.. image:: applications/drupal_logo.png :doc:`Drupal<applications/drupal>` ✔ |
||||
.. image:: applications/fusiondirectory-logo.jpg :doc:`FusionDirectory<applications/fusiondirectory>` ✔ |
||||
.. image:: applications/gitlab_logo.png :doc:`Gitlab<applications/gitlab>` ✔ ✔ |
||||
.. image:: applications/glpi_logo.png :doc:`GLPI<applications/glpi>` ✔ |
||||
.. image:: applications/googleapps_logo.png :doc:`Google Apps<applications/googleapps>` ✔ |
||||
.. image:: applications/grafana_logo.png :doc:`Grafana<applications/grafana>` ✔ |
||||
.. image:: applications/grr_logo.png :doc:`GRR<applications/grr>` ✔ |
||||
.. image:: applications/guacamole.png :doc:`Apache Guacamole<applications/guacamole>` ✔ ✔ ✔ |
||||
.. image:: applications/humhub_logo.png :doc:`HumHub<applications/humhub>` ✔ |
||||
.. image:: applications/logo-jitsimeet.png :doc:`Jitsi Meet<applications/jitsimeet>` ✔ |
||||
.. image:: applications/liferay_logo.png :doc:`Liferay<applications/liferay>` ✔ |
||||
.. image:: applications/limesurvey_logo.png :doc:`LimeSurvey<applications/limesurvey>` ✔ |
||||
.. image:: applications/mattermost_logo.png :doc:`Mattermost<applications/mattermost>` ✔ |
||||
.. image:: applications/mediawiki_logo.png :doc:`Mediawiki<applications/mediawiki>` ✔ |
||||
.. image:: applications/nextcloud-logo.png :doc:`NextCloud<applications/nextcloud>` ✔ |
||||
.. image:: applications/obm_logo.png :doc:`OBM<applications/obm>` ✔ |
||||
.. image:: applications/logo_office_365.png :doc:`Office 365<applications/office365>` ✔ |
||||
.. image:: applications/phpldapadmin_logo.png :doc:`phpLDAPAdmin<applications/phpldapadmin>` ✔ |
||||
.. image:: applications/roundcube_logo.png :doc:`Roundcube<applications/roundcube>` ✔ |
||||
.. image:: applications/salesforce-logo.jpg :doc:`SalesForce<applications/salesforce>` ✔ |
||||
.. image:: applications/SAPLogo.gif :doc:`SAP<applications/sap>` ✔ ✔ |
||||
.. image:: applications/simplesamlphp_logo.png :doc:`simpleSAMLphp<applications/simplesamlphp>` ✔ |
||||
.. image:: applications/spring_logo.png :doc:`Spring<applications/spring>` ✔ |
||||
.. image:: applications/symfony_logo.png :doc:`Symfony<applications/symfony>` ✔ |
||||
.. image:: applications/sympa_logo.png :doc:`Sympa<applications/sympa>` ✔ |
||||
.. image:: applications/tomcat_logo.png :doc:`Tomcat<applications/tomcat>` ✔ |
||||
.. image:: applications/wordpress_logo.png :doc:`Wordpress<applications/wordpress>` ✔ |
||||
.. image:: applications/xwiki.png :doc:`XWiki<applications/xwiki>` ✔ |
||||
.. image:: applications/zimbra_logo.png :doc:`Zimbra<applications/zimbra>` ✔ |
||||
================================================================= ==================================================== ============ ================ === ==== ==== |
After Width: | Height: | Size: 538 B |
@ -0,0 +1,37 @@ |
||||
Active Directory Federation Services |
||||
==================================== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
Microsoft ADFS (Active Directory Federation Services) is an |
||||
Identity/Service Provider, compatible with several protocols, including |
||||
SAML 2.0. |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
This documentation does not explains how to setup ADFS, |
||||
but give only tricks to make it works with LL::NG |
||||
|
||||
ADFS as Identity Provider |
||||
------------------------- |
||||
|
||||
When ADFS is declared as an Identity Provider in LemonLDAP::NG, you need |
||||
to take care of the following items: |
||||
|
||||
- HTTPS is mandatory on LL::NG portal |
||||
- You need to use a certificate in LL::NG SAML metadata instead of a |
||||
raw public key |
||||
- Activate option ``Use specific query_string method`` in SAML Service |
||||
- Use SHA1 instead of SHA256 as signature algorithm on ADFS if using a |
||||
Lasso version < 2.5.0 |
||||
- Force SAML response to be sent by POST and not Artifact (signature |
||||
verification fails with Artifact) |
||||
- Enable ``Allow proxy authentication`` in IDP options on LL::NG side |
||||
|
||||
.. |image0| image:: /applications/microsoft-adfs.png |
||||
:class: align-center |
||||
|
@ -0,0 +1,458 @@ |
||||
Alfresco |
||||
======== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Alfresco <https://www.alfresco.com/>`__ is an ECM/BPM software. |
||||
|
||||
Since 4.0 release, it offers an easy way to configure SSO thanks to |
||||
authentication subsystems. |
||||
|
||||
Authentication against LL::NG can be done trough: |
||||
|
||||
- HTTP headers (LL::NG Handler) |
||||
- SAML 2 (LL::NG as SAML2 IDP) |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
Alfresco now recommends SAML2 method |
||||
|
||||
HTTP headers |
||||
------------ |
||||
|
||||
.. _alfresco-1: |
||||
|
||||
Alfresco |
||||
~~~~~~~~ |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
The official documentation can be found here: |
||||
http://docs.alfresco.com/4.0/tasks/auth-alfrescoexternal-sso.html\ |
||||
|
||||
You need to find the following files in your Alfresco installation: |
||||
|
||||
- ``alfresco-global.properties`` (ex: |
||||
``tomcat/shared/classes/alfresco-global.properties``) |
||||
- ``share-config-custom.xml`` (ex: |
||||
``tomcat/shared/classes/alfresco/web-extension/share-config-custom.xml``) |
||||
|
||||
The first will allow one to configure SSO for the alfresco webapp, and |
||||
the other for the share webapp. |
||||
|
||||
Edit first ``alfresco-global.properties`` and add the following: |
||||
|
||||
.. code:: java |
||||
|
||||
### SSO ### |
||||
authentication.chain=external1:external |
||||
external.authentication.enabled=true |
||||
external.authentication.defaultAdministratorUserNames= |
||||
external.authentication.proxyUserName= |
||||
external.authentication.proxyHeader=Auth-User |
||||
external.authentication.userIdPattern= |
||||
|
||||
Edit then ``share-config-custom.xml`` and uncomment the last part. In |
||||
the ``<endpoint>``, change ``<connector-id>`` value to |
||||
``alfrescoHeader`` and change the ``<userHeader>`` value to |
||||
``Auth-User``: |
||||
|
||||
.. code:: xml |
||||
|
||||
<config evaluator="string-compare" condition="Remote"> |
||||
<remote> |
||||
<keystore> |
||||
<path>alfresco/web-extension/alfresco-system.p12</path> |
||||
<type>pkcs12</type> |
||||
<password>alfresco-system</password> |
||||
</keystore> |
||||
|
||||
<connector> |
||||
<id>alfrescoCookie</id> |
||||
<name>Alfresco Connector</name> |
||||
<description>Connects to an Alfresco instance using cookie-based authentication</description> |
||||
<class>org.alfresco.web.site.servlet.SlingshotAlfrescoConnector</class> |
||||
</connector> |
||||
|
||||
<connector> |
||||
<id>alfrescoHeader</id> |
||||
<name>Alfresco Connector</name> |
||||
<description>Connects to an Alfresco instance using header and cookie-based authentication</description> |
||||
<class>org.alfresco.web.site.servlet.SlingshotAlfrescoConnector</class> |
||||
<userHeader>Auth-User</userHeader> |
||||
</connector> |
||||
|
||||
<endpoint> |
||||
<id>alfresco</id> |
||||
<name>Alfresco - user access</name> |
||||
<description>Access to Alfresco Repository WebScripts that require user authentication</description> |
||||
<connector-id>alfrescoHeader</connector-id> |
||||
<endpoint-url>http://localhost:8080/alfresco/s</endpoint-url> |
||||
<identity>user</identity> |
||||
<external-auth>true</external-auth> |
||||
</endpoint> |
||||
</remote> |
||||
</config> |
||||
|
||||
You need to restart Tomcat to apply changes. |
||||
|
||||
|
||||
.. warning:: |
||||
|
||||
Now you can log in with a simple HTTP header. You need to |
||||
restrict access to Alfresco to LL::NG. |
||||
|
||||
LL::NG |
||||
~~~~~~ |
||||
|
||||
Headers |
||||
^^^^^^^ |
||||
|
||||
Just set the ``Auth-User`` header with the attribute that carries the |
||||
user login, for example ``$uid``. |
||||
|
||||
Rules |
||||
^^^^^ |
||||
|
||||
Set the default rule to what you need. |
||||
|
||||
Other rules: |
||||
|
||||
- Unprotect access to some resources: ``^/share/res => unprotect`` |
||||
- Catch logout: ``^/share/page/dologout => logout_app_sso`` |
||||
|
||||
SAML2 |
||||
----- |
||||
|
||||
.. _alfresco-2: |
||||
|
||||
Alfresco |
||||
~~~~~~~~ |
||||
|
||||
Install SAML Alfresco module package: |
||||
|
||||
:: |
||||
|
||||
cp alfresco-saml-repo-1.0.1.amp <ALFRESCO_HOME>/amps |
||||
cp alfresco-saml-share-1.0.1.amp <ALFRESCO_HOME>/amps_share |
||||
./bin/apply_amp.sh |
||||
|
||||
Generate SAML certificate: |
||||
|
||||
:: |
||||
|
||||
keytool -genkeypair -alias my-saml-key -keypass change-me -storepass change-me -keystore my-saml.keystore -storetype JCEKS |
||||
|
||||
Export the keystore: |
||||
|
||||
:: |
||||
|
||||
mv my-saml.keystore alf_data/keystore |
||||
cat <<EOT > alf_data/keystore/my-saml.keystore-metadata.properties |
||||
aliases=my-saml-key |
||||
keystore.password=change-me |
||||
my-saml-key.password=change-me |
||||
EOT |
||||
cat <<EOT >> tomcat/shared/classes/alfresco-global.properties |
||||
|
||||
saml.keystore.location=\${dir.keystore}/my-saml.keystore |
||||
saml.keystore.keyMetaData.location=\${dir.keystore}/my-saml.keystore-metadata.properties |
||||
EOT |
||||
|
||||
Edit then ``share-config-custom.xml``: |
||||
|
||||
.. code:: xml |
||||
|
||||
... |
||||
<config evaluator="string-compare" condition="CSRFPolicy" replace="true"> |
||||
|
||||
|
||||
|
||||
<!-- |
||||
If using https make a CSRFPolicy with replace="true" and override the properties section. |
||||
Note, localhost is there to allow local checks to succeed. |
||||
|
||||
|
||||
|
||||
I.e. |
||||
<properties> |
||||
<token>Alfresco-CSRFToken</token> |
||||
<referer>https://your-domain.com/.*|http://localhost:8080/.*</referer> |
||||
<origin>https://your-domain.com|http://localhost:8080</origin> |
||||
</properties> |
||||
--> |
||||
|
||||
|
||||
|
||||
<filter> |
||||
|
||||
|
||||
|
||||
<!-- SAML SPECIFIC CONFIG - START --> |
||||
|
||||
|
||||
|
||||
<!-- |
||||
Since we have added the CSRF filter with filter-mapping of "/*" we will catch all public GET to avoid them |
||||
having to pass through the remaining rules. |
||||
--> |
||||
<rule> |
||||
<request> |
||||
<method>GET</method> |
||||
<path>/res/.*</path> |
||||
</request> |
||||
</rule> |
||||
|
||||
|
||||
|
||||
<!-- Incoming posts from IDPs do not require a token --> |
||||
<rule> |
||||
<request> |
||||
<method>POST</method> |
||||
<path>/page/saml-authnresponse|/page/saml-logoutresponse|/page/saml-logoutrequest</path> |
||||
</request> |
||||
</rule> |
||||
|
||||
|
||||
|
||||
<!-- SAML SPECIFIC CONFIG - STOP --> |
||||
|
||||
|
||||
|
||||
<!-- EVERYTHING BELOW FROM HERE IS COPIED FROM share-security-config.xml --> |
||||
|
||||
|
||||
|
||||
<!-- |
||||
Certain webscripts shall not be allowed to be accessed directly form the browser. |
||||
Make sure to throw an error if they are used. |
||||
--> |
||||
<rule> |
||||
<request> |
||||
<path>/proxy/alfresco/remoteadm/.*</path> |
||||
</request> |
||||
<action name="throwError"> |
||||
<param name="message">It is not allowed to access this url from your browser</param> |
||||
</action> |
||||
</rule> |
||||
|
||||
|
||||
|
||||
<!-- |
||||
Certain Repo webscripts should be allowed to pass without a token since they have no Share knowledge. |
||||
TODO: Refactor the publishing code so that form that is posted to this URL is a Share webscript with the right tokens. |
||||
--> |
||||
<rule> |
||||
<request> |
||||
<method>POST</method> |
||||
<path>/proxy/alfresco/api/publishing/channels/.+</path> |
||||
</request> |
||||
<action name="assertReferer"> |
||||
<param name="referer">{referer}</param> |
||||
</action> |
||||
<action name="assertOrigin"> |
||||
<param name="origin">{origin}</param> |
||||
</action> |
||||
</rule> |
||||
|
||||
|
||||
|
||||
<!-- |
||||
Certain Surf POST requests from the WebScript console must be allowed to pass without a token since |
||||
the Surf WebScript console code can't be dependent on a Share specific filter. |
||||
--> |
||||
<rule> |
||||
<request> |
||||
<method>POST</method> |
||||
<path>/page/caches/dependency/clear|/page/index|/page/surfBugStatus|/page/modules/deploy|/page/modules/module|/page/api/javascript/debugger|/page/console</path> |
||||
</request> |
||||
<action name="assertReferer"> |
||||
<param name="referer">{referer}</param> |
||||
</action> |
||||
<action name="assertOrigin"> |
||||
<param name="origin">{origin}</param> |
||||
</action> |
||||
</rule> |
||||
|
||||
|
||||
|
||||
<!-- Certain Share POST requests does NOT require a token --> |
||||
<rule> |
||||
<request> |
||||
<method>POST</method> |
||||
<path>/page/dologin(\?.+)?|/page/site/[^/]+/start-workflow|/page/start-workflow|/page/context/[^/]+/start-workflow</path> |
||||
</request> |
||||
<action name="assertReferer"> |
||||
<param name="referer">{referer}</param> |
||||
</action> |
||||
<action name="assertOrigin"> |
||||
<param name="origin">{origin}</param> |
||||
</action> |
||||
</rule> |
||||
|
||||
|
||||
|
||||
<!-- Assert logout is done from a valid domain, if so clear the token when logging out --> |
||||
<rule> |
||||
<request> |
||||
<method>POST</method> |
||||
<path>/page/dologout(\?.+)?</path> |
||||
</request> |
||||
<action name="assertReferer"> |
||||
<param name="referer">{referer}</param> |
||||
</action> |
||||
<action name="assertOrigin"> |
||||
<param name="origin">{origin}</param> |
||||
</action> |
||||
<action name="clearToken"> |
||||
<param name="session">{token}</param> |
||||
<param name="cookie">{token}</param> |
||||
</action> |
||||
</rule> |
||||
|
||||
|
||||
|
||||
<!-- Make sure the first token is generated --> |
||||
<rule> |
||||
<request> |
||||
<session> |
||||
<attribute name="_alf_USER_ID">.+</attribute> |
||||
<attribute name="{token}"/> |
||||
<!-- empty attribute element indicates null, meaning the token has not yet been set --> |
||||
</session> |
||||
</request> |
||||
<action name="generateToken"> |
||||
<param name="session">{token}</param> |
||||
<param name="cookie">{token}</param> |
||||
</action> |
||||
</rule> |
||||
|
||||
|
||||
|
||||
<!-- Refresh token on new "page" visit when a user is logged in --> |
||||
<rule> |
||||
<request> |
||||
<method>GET</method> |
||||
<path>/page/.*</path> |
||||
<session> |
||||
<attribute name="_alf_USER_ID">.+</attribute> |
||||
<attribute name="{token}">.+</attribute> |
||||
</session> |
||||
</request> |
||||
<action name="generateToken"> |
||||
<param name="session">{token}</param> |
||||
<param name="cookie">{token}</param> |
||||
</action> |
||||
</rule> |
||||
|
||||
|
||||
|
||||
<!-- |
||||
Verify multipart requests from logged in users contain the token as a parameter |
||||
and also correct referer & origin header if available |
||||
--> |
||||
<rule> |
||||
<request> |
||||
<method>POST</method> |
||||
<header name="Content-Type">multipart/.+</header> |
||||
<session> |
||||
<attribute name="_alf_USER_ID">.+</attribute> |
||||
</session> |
||||
</request> |
||||
<action name="assertToken"> |
||||
<param name="session">{token}</param> |
||||
<param name="parameter">{token}</param> |
||||
</action> |
||||
<action name="assertReferer"> |
||||
<param name="referer">{referer}</param> |
||||
</action> |
||||
<action name="assertOrigin"> |
||||
<param name="origin">{origin}</param> |
||||
</action> |
||||
</rule> |
||||
|
||||
|
||||
|
||||
<!-- |
||||
Verify that all remaining state changing requests from logged in users' requests contains a token in the |
||||
header and correct referer & origin headers if available. We "catch" all content types since just setting it to |
||||
"application/json.*" since a webscript that doesn't require a json request body otherwise would be |
||||
successfully executed using i.e."text/plain". |
||||
--> |
||||
<rule> |
||||
<request> |
||||
<method>POST|PUT|DELETE</method> |
||||
<session> |
||||
<attribute name="_alf_USER_ID">.+</attribute> |
||||
</session> |
||||
</request> |
||||
<action name="assertToken"> |
||||
<param name="session">{token}</param> |
||||
<param name="header">{token}</param> |
||||
</action> |
||||
<action name="assertReferer"> |
||||
<param name="referer">{referer}</param> |
||||
</action> |
||||
<action name="assertOrigin"> |
||||
<param name="origin">{origin}</param> |
||||
</action> |
||||
</rule> |
||||
</filter> |
||||
</config> |
||||
... |
||||
|
||||
Configure SAML service provider using the Alfresco admin console |
||||
(/alfresco/s/enterprise/admin/admin-saml). |
||||
|
||||
Set the following parameters: |
||||
|
||||
- Enable SAML Authentication (SSO): on |
||||
- Authentication service URL: |
||||
https://auth.example.com/saml/singleSignOn |
||||
- Single Logout URL: https://auth.example.com/saml/singleLogout |
||||
- Single logout return URL: |
||||
https://auth.example.com/saml/singleLogoutReturn |
||||
- Entity identification: http://alfresco.myecm.org:8080/share |
||||
- User ID mapping: Subject/NameID |
||||
|
||||
To finish with Alfresco configuration, tick the “Enable SAML |
||||
authentication (SSO)” box. |
||||
|
||||
.. _llng-1: |
||||
|
||||
LL::NG |
||||
~~~~~~ |
||||
|
||||
Configure SAML service and set a certificate as signature public key in |
||||
metadata. |
||||
|
||||
Export Alfresco SAML Metadata from admin console and import them in |
||||
LL::NG. |
||||
|
||||
In the authentication response option, set: |
||||
|
||||
- Default NameID Format: Unspecified |
||||
- Force NameID session key: uid |
||||
|
||||
And you can define these exported attributes: |
||||
|
||||
- GivenName |
||||
- Surname |
||||
- Email |
||||
|
||||
Other resources |
||||
--------------- |
||||
|
||||
- `DevCon 2012: Unlocking the Secrets of Alfresco Authentication, Mehdi |
||||
Belmekki <https://www.youtube.com/watch?v=5tS0XrC_-rw>`__ |
||||
- `Setting up Alfresco SAML authentication with |
||||
LemonLDAP::NG <https://community.alfresco.com/blogs/alfresco-premier-services/2017/08/03/setting-up-alfresco-saml-authentication-lemonldapng>`__ |
||||
|
||||
.. |image0| image:: /applications/alfresco_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 7.6 KiB |
@ -0,0 +1,73 @@ |
||||
HTTP Basic Authentication |
||||
========================= |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
For now, this feature is only supported by Apache |
||||
handler. |
||||
|
||||
Extract from the `Wikipedia |
||||
article <http://en.wikipedia.org/wiki/Basic_access_authentication>`__: |
||||
|
||||
In the context of an HTTP transaction, the basic access authentication |
||||
is a method designed to allow a web browser, or other client program, to |
||||
provide credentials – in the form of a user name and password – when |
||||
making a request. |
||||
|
||||
Before transmission, the username and password are encoded as a sequence |
||||
of base-64 characters. For example, the user name Aladdin and password |
||||
open sesame would be combined as Aladdin:open sesame – which is |
||||
equivalent to QWxhZGRpbjpvcGVuIHNlc2FtZQ== when encoded in Base64. |
||||
Little effort is required to translate the encoded string back into the |
||||
user name and password, and many popular security tools will decode the |
||||
strings "on the fly". |
||||
|
||||
So HTTP Basic Authentication is managed trough an HTTP header |
||||
(``Authorization``), that can be forged by LL::NG, with this |
||||
precautions: |
||||
|
||||
- Data should not contains accents or special characters, as HTTP |
||||
protocol only allow ASCII values in header (but depending on the HTTP |
||||
server, you can use ISO encoded values) |
||||
- You need to forward the password, which can be the user main password |
||||
(if :doc:`password is stored in session<../passwordstore>`, or any |
||||
user attribute (if you keep secondary passwords in users database). |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
The Basic Authentication relies on a specific HTTP header, as described |
||||
above. So you have just to declare this header for the virtual host in |
||||
Manager. |
||||
|
||||
For example, to forward login (``$uid``) and password (``$_password`` if |
||||
:doc:`password is stored in session<../passwordstore>`): |
||||
|
||||
:: |
||||
|
||||
Authorization => "Basic ".encode_base64("$uid:$_password", "") |
||||
|
||||
LL::NG provides a special function named |
||||
:doc:`basic<../extendedfunctions>` to build this header. |
||||
|
||||
So the above example can also be written like this: |
||||
|
||||
:: |
||||
|
||||
Authorization => basic($uid,$_password) |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
The ``basic`` function will also force conversion from UTF-8 |
||||
to ISO-8859-1, which should be accepted by most of HTTP servers. |
||||
|
||||
.. |image0| image:: /applications/http_logo.png |
||||
:class: align-center |
||||
|
@ -0,0 +1,102 @@ |
||||
Amazon Web Services |
||||
=================== |
||||
|
||||
`Amazon Web Services <https://aws.amazon.com>`__ allows one to delegate |
||||
authentication through SAML2. |
||||
|
||||
SAML |
||||
---- |
||||
|
||||
- Make sure you have followed the steps |
||||
`here <https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-saml.html>`__. |
||||
- Go to https://your.portal.com/saml/metadata and save the resulting |
||||
file locally. |
||||
- In each AWS account, go to IAM -> Identity providers -> Create |
||||
Provider. |
||||
- Select ``SAML`` as the provider type |
||||
- Choose a name (best if kept consistent between accounts), and then |
||||
choose the metadata file you saved above. |
||||
- Looking again at the links on the left side of the page, go to Roles |
||||
-> Create role |
||||
- Choose ``SAML / Saml 2.0 federation`` |
||||
- Select the provider you just configured, click |
||||
``Allow programmatic and AWSManagement Console access`` which will |
||||
fill in the rest of the form for you, then click next. |
||||
- Set whatever permissions you need to and then click ``Review``. |
||||
- Choose a name for the role. These will shown to people when they log |
||||
in, so make them descriptive. We have different accounts for |
||||
different regions of the world, so I put the region into the role |
||||
name so people know which account is which. |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
If you have only one role, the configuration is simple. If you |
||||
have multiple roles for different people, it is a little trickier. As |
||||
you will see, the SAML attributes are not dynamic, so you have to set |
||||
them in the session when a user logs in or use a custom function. In |
||||
this example, I wanted to avoid managing custom functions on all the |
||||
servers, so the SAML attributes are set in the session. We also use LDAP |
||||
for user information, so I will describe that. In our LDAP tree, each |
||||
user has attributes which are used quite heavily for dynamic groups and |
||||
authorisation. You will want something similar, using whatever attribute |
||||
makes sense to you. For example: |
||||
|
||||
.. code:: |
||||
|
||||
dn: uid=user,ou=people,dc=your,dc=com |
||||
... |
||||
ou: sysadmin |
||||
ou: database |
||||
ou: root |
||||
|
||||
|
||||
|
||||
- Assuming you use the web interface to manage lemonldap, go to General |
||||
Parameters -> Authentication parameters -> LDAP parameters -> |
||||
Exported variables. Here set the key to the LDAP attribute and the |
||||
value to something sensible. I keep them the same to make it easy. |
||||
- Now go to \*Variables -> Macros*. Here set up variables which will be |
||||
computed based on the attributes you exported above. You will need to |
||||
emit strings in this format |
||||
``arn:aws:iam::account-number:role/role-name1,arn:aws:iam::account-number:saml-provider/provider-name``. |
||||
The parts you need to change are ``account-number``, ``role-name1`` |
||||
and ``provier-name``. The last two will be the provider name and role |
||||
names you just set up in AWS. |
||||
- Perl works in here, so something like this is valid: ``aws_eu_role`` |
||||
-> ``$ou =~ sysadmin ? "arn:aws..." : "arn:..."`` |
||||
- If it easier, split multiple roles into different macros. Then tie |
||||
all the variables you define together into one string concatenating |
||||
them with whatever is in General Parameters -> Advanced Parameters -> |
||||
Separator. Actually click into this field and move around with the |
||||
arrow keys to see if there is a space, since spaces can be part of |
||||
the separator. |
||||
- Remember macros are defined alphanumerically, so you want one right |
||||
at the end, like ``z_aws_roles`` -> |
||||
``join("; ", $role_name1, $role_name2, ...)`` |
||||
- On the left again, click ``SAML service providers``, then |
||||
``Add SAML SP``. |
||||
- Enter a name, click ok, then select it on the left. Select |
||||
``Metadata``, then enter |
||||
\`\ https://signin.aws.amazon.com/static/saml-metadata.xml\ \` in the |
||||
``URL`` field, then click load. |
||||
- Click ``Exported attributes`` on the left, then ``Add attribute`` |
||||
twice to add two attributes. The first field is the name of a |
||||
variable set in the user's session: |
||||
|
||||
- ``_whatToTrace`` -> |
||||
``https://aws.amazon.com/SAML/Attributes/RoleSessionName`` (leave |
||||
the rest) |
||||
- ``z_aws_roles`` (the macro name you defined above) -> |
||||
``https://aws.amazon.com/SAML/Attributes/Role`` (leave the rest) |
||||
|
||||
- On the left, select Options -> Security -> Enable use of IDP |
||||
initiated URL -> On |
||||
- Select General Parameters -> Portal -> Menu -> Categories and |
||||
applications |
||||
- Select a category or create a new one if you need to. Then click |
||||
``New application``. |
||||
- Enter a name etc. For the URL, use |
||||
``https://your.portal.com/saml/singleSignOn?IDPInitiated=1&sp=urn:amazon:webservices`` |
||||
- Display application should be set to ``Enabled`` |
||||
- Go to your portal, click on the link, and check that it works! |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 122 KiB |
After Width: | Height: | Size: 13 KiB |
@ -0,0 +1,209 @@ |
||||
AWX (Ansible Tower) |
||||
=================== |
||||
|
||||
|logo-awx.png| |logo-ansibletower.png| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`AWX <https://github.com/ansible/awx>`__ is the upstream version for |
||||
Ansible Tower. |
||||
|
||||
This documentation explains how to interconnect LemonLDAP::NG and AWX |
||||
using SAML 2.0 protocol. |
||||
|
||||
You can find the Official AWX documentation about this topic here : |
||||
https://docs.ansible.com/ansible-tower/latest/html/administration/ent_auth.html#saml-authentication-settings |
||||
Please read it before the LLNG doc. |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
This page assumes you already have configured the SAML Service in |
||||
LemonLDAP::NG, if not please follow : |
||||
:doc:`SAML service configuration<../samlservice>` |
||||
|
||||
AWX SAML Key & Certificate |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
You'll need a private key and the corresponding certificate to setup |
||||
saml in AWX, you can do it with your pki or with openssl on your machine |
||||
: |
||||
|
||||
:: |
||||
|
||||
openssl req -x509 -newkey rsa:4096 -keyout saml-awx.key -out saml-awx.crt -days 3650 -nodes |
||||
|
||||
LLNG SAML Certificate |
||||
~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
AWX need a certificate for the IDP signature, a public key won't work. |
||||
You can either just generate a certificate from the private key and put |
||||
it in AWX conf, or you can do it globally. |
||||
|
||||
Generate Certificate from Key |
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
||||
|
||||
You can find your private key in : SAML2 Service -> Security Parameters |
||||
-> Signature -> Private Key |
||||
|
||||
Copy it somewhere secure as lemonldap.key, and then generate the |
||||
certificate with this command : |
||||
|
||||
:: |
||||
|
||||
openssl req -new -x509 -days 3650 -key lemonldap.key > lemonldap.crt |
||||
|
||||
After that, if you want, you can replace your SAML public key with this |
||||
certificate in LLNG configuration, this is not mandatory. |
||||
|
||||
AWX |
||||
~~~ |
||||
|
||||
You'll need an administrator account, then go to Settings -> |
||||
Authentication -> SAML |
||||
|
||||
|image2| |
||||
|
||||
There is a few settings : |
||||
|
||||
SAML Service Provider Entity ID |
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
||||
|
||||
This is the entityID for awx, lets put the fqdn : ``awx.example.com`` |
||||
|
||||
SAML Service Provider Public Certificate |
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
||||
|
||||
Put the content of ``saml-awx.crt`` : ``-----BEGIN CERTIFICATE----- |
||||
cert |
||||
-----END CERTIFICATE-----`` |
||||
|
||||
SAML Service Provider Private Key |
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
||||
|
||||
Put the content of ``saml-awx.key`` : ``-----BEGIN RSA PRIVATE KEY----- |
||||
key |
||||
-----END RSA PRIVATE KEY-----`` |
||||
|
||||
It will be replaced with ``$encrypted$`` after you save the settings. |
||||
|
||||
SAML Service Provider Organization Info |
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
||||
|
||||
Organization Info for The SP, this is purely "for looks" |
||||
|
||||
:: |
||||
|
||||
{ |
||||
"en-US": { |
||||
"displayname": "AWX ACME", |
||||
"url": "https://awx.example.com", |
||||
"name": "awxacme" |
||||
} |
||||
} |
||||
|
||||
SAML Service Provider Technical Contact |
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
||||
|
||||
Technical Contact for the SP |
||||
|
||||
:: |
||||
|
||||
{ |
||||
"emailAddress": "support@example.com", |
||||
"givenName": "Support ACME" |
||||
} |
||||
|
||||
SAML Service Provider Support Contact |
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
||||
|
||||
Support Contact for the SP |
||||
|
||||
:: |
||||
|
||||
{ |
||||
"emailAddress": "support@example.com", |
||||
"givenName": "Support ACME" |
||||
} |
||||
|
||||
SAML Enabled Identity Providers |
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
||||
|
||||
This is the configuration of the IdP : |
||||
|
||||
:: |
||||
|
||||
{ |
||||
"lemonldap": { |
||||
"attr_last_name": "sn", |
||||
"x509cert": "SOXGp.....", |
||||
"attr_username": "uid", |
||||
"entity_id": "https://auth.example.com/saml/metadata", |
||||
"attr_first_name": "givenName", |
||||
"attr_email": "mail", |
||||
"attr_user_permanent_id": "uid", |
||||
"url": "https://auth.example.com/saml/singleSignOn" |
||||
} |
||||
} |
||||
|
||||
- "attr_last_name": "sn" SAML Attribute for the user last name |
||||
- "x509cert": "SOXGp....." the content of ``lemonldap.crt`` generated |
||||
in the "LLNG SAML Certificate" section |
||||
- "attr_username": "uid" SAML Attribute for the user username |
||||
- "entity_id": "https://auth.example.com/saml/metadata" entityID of the |
||||
IdP |
||||
- "attr_first_name": "givenName" SAML Attribute for the user first name |
||||
- "attr_email": "mail" SAML Attribute user for the user email |
||||
- "attr_user_permanent_id": "uid" SAML Attribute for the user unique id |
||||
inside AWX |
||||
- "url": "https://auth.example.com/saml/singleSignOn" SAML SSO Url |
||||
|
||||
Save your configuration. |
||||
|
||||
LemonLDAP:NG |
||||
~~~~~~~~~~~~ |
||||
|
||||
We now have to define a service provider in LL:NG. |
||||
|
||||
Go to "SAML service providers", click on "Add SAML SP" and name it as |
||||
you want (example : 'AWX') |
||||
|
||||
In the new subtree 'AWX', open 'Metadata' and paste the content of the |
||||
AWX Metadatas, wich can be found at the |
||||
``SAML Service Provider Metadata URL`` in AWX : |
||||
https://awx.example.com/sso/metadata/saml/ |
||||
|
||||
|image3| |
||||
|
||||
Now go in "Exported attributes" and add, the 'uid', 'sn', 'givenName', |
||||
'mail'. |
||||
|
||||
All four attributes are mandatory for AWX. Make sure they match the |
||||
names of the attributes available in your LemonLDAP sessions. |
||||
|
||||
|image4| |
||||
|
||||
Don't forget to save your configuration. |
||||
|
||||
You are now good to go, and you can add the application in |
||||
:doc:`your menu<../portalmenu>` and |
||||
:doc:`your virtual hosts<../configvhost>`. |
||||
|
||||
You should now have a SAML button on the login page : |
||||
|
||||
|image5| |
||||
|
||||
.. |logo-awx.png| image:: /applications/logo-awx.png |
||||
:class: align-center |
||||
.. |logo-ansibletower.png| image:: /applications/logo-ansibletower.png |
||||
:class: align-center |
||||
.. |image2| image:: /applications/saml-awx.png |
||||
:class: align-center |
||||
.. |image3| image:: /applications/awx-metadata.png |
||||
:class: align-center |
||||
.. |image4| image:: /applications/awx-attr.png |
||||
:class: align-center |
||||
.. |image5| image:: /applications/awx-saml-login.png |
||||
:class: align-center |
||||
|
@ -0,0 +1,109 @@ |
||||
Bugzilla |
||||
======== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Bugzilla <http://www.bugzilla.org>`__ is server software designed to |
||||
help you manage software development. |
||||
|
||||
Bugzilla can authenticate a user with HTTP headers, and auto-create its |
||||
account with a few information: |
||||
|
||||
- User ID |
||||
- Email |
||||
- Real name |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
Bugzilla administration |
||||
~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
In Bugzilla administration interface, go in ``Parameters`` » |
||||
``User authentication`` |
||||
|
||||
Then set: |
||||
|
||||
- **auth_env_id**: HTTP_AUTH_USER |
||||
- **auth_env_email**: HTTP_AUTH_MAIL |
||||
- **auth_env_realname**: HTTP_AUTH_CN |
||||
- **user_info_class**: Env or Env,CGI |
||||
|
||||
Bugzilla virtual host |
||||
~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Configure Bugzilla virtual host like other |
||||
:doc:`protected virtual host<../configvhost>`. |
||||
|
||||
- For Apache: |
||||
|
||||
.. code:: apache |
||||
|
||||
<VirtualHost *:80> |
||||
ServerName bugzilla.example.com |
||||
|
||||
PerlHeaderParserHandler Lemonldap::NG::Handler |
||||
|
||||
... |
||||
|
||||
</VirtualHost> |
||||
|
||||
- For Nginx: |
||||
|
||||
.. code:: nginx |
||||
|
||||
server { |
||||
listen 80; |
||||
server_name bugzilla.example.com; |
||||
root /path/to/application; |
||||
# Internal authentication request |
||||
location = /lmauth { |
||||
internal; |
||||
include /etc/nginx/fastcgi_params; |
||||
fastcgi_pass unix:/var/run/llng-fastcgi-server/llng-fastcgi.sock; |
||||
# Drop post datas |
||||
fastcgi_pass_request_body off; |
||||
fastcgi_param CONTENT_LENGTH ""; |
||||
# Keep original hostname |
||||
fastcgi_param HOST $http_host; |
||||
# Keep original request (LLNG server will received /llauth) |
||||
fastcgi_param X_ORIGINAL_URI $request_uri; |
||||
} |
||||
|
||||
# Client requests |
||||
location / { |
||||
auth_request /lmauth; |
||||
auth_request_set $lmremote_user $upstream_http_lm_remote_user; |
||||
auth_request_set $lmlocation $upstream_http_location; |
||||
error_page 401 $lmlocation; |
||||
try_files $uri $uri/ =404; |
||||
|
||||
... |
||||
|
||||
include /etc/lemonldap-ng/nginx-lua-headers.conf; |
||||
} |
||||
location / { |
||||
try_files $uri $uri/ =404; |
||||
} |
||||
} |
||||
|
||||
Bugzilla virtual host in Manager |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Go to the Manager and :doc:`create a new virtual host<../configvhost>` |
||||
for Bugzilla. |
||||
|
||||
Configure the :doc:`access rules<../writingrulesand_headers>`. |
||||
|
||||
Configure the following :doc:`headers<../writingrulesand_headers>`. |
||||
|
||||
- **Auth-User**: $uid |
||||
- **Auth-Mail**: $mail |
||||
- **Auth-Cn**: $cn |
||||
|
||||
.. |image0| image:: /applications/bugzilla_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 5.8 KiB |
@ -0,0 +1,90 @@ |
||||
Cornerstone On Demand |
||||
===================== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`CornerStone On Demand (CSOD) <http://www.cornerstoneondemand.com/>`__ |
||||
allows one to use SAML to authenticate users. It works by default with |
||||
IDP intiated mechanism, but can works with the standard SP initiated |
||||
cinematic. |
||||
|
||||
To work with LL::NG it requires: |
||||
|
||||
- An enterprise account |
||||
- LL::NG configured as :doc:`SAML Identity Provider<../idpsaml>` |
||||
- Registered users on CSOD with the same email than those used by |
||||
LL::NG (email will be the NameID exchanged between CSOD and LL::NG) |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
New Service Provider |
||||
~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
You should have configured LL::NG as an |
||||
:doc:`SAML Identity Provider<../idpsaml>`, |
||||
|
||||
Now we will add CSOD as a new SAML Service Provider: |
||||
|
||||
#. In Manager, click on SAML service providers and the button |
||||
``New service provider``. |
||||
#. Set csod as Service Provider name. |
||||
#. Set ``Email`` in ``Options`` » ``Authentication Response`` » |
||||
``Default NameID format`` |
||||
#. Select ``Metadata``, and unprotect the field to paste the following |
||||
value: |
||||
|
||||
.. code:: xml |
||||
|
||||
<md:EntityDescriptor entityID="mycompanyid.csod.com" xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"> |
||||
<SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> |
||||
<KeyDescriptor use="signing"> |
||||
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> |
||||
<ds:X509Data> |
||||
<ds:X509Certificate> |
||||
Base64 encoded CSOD certificate |
||||
</ds:X509Certificate> |
||||
</ds:X509Data> |
||||
</ds:KeyInfo> |
||||
</KeyDescriptor> |
||||
<AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://mycompanyid.csod.com/samldefault.aspx" index="1" /> |
||||
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat> |
||||
</SPSSODescriptor> |
||||
</md:EntityDescriptor> |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
Change **mycompanyid** (in ``AssertionConsumerService`` |
||||
markup, parameter ``Location``) into your CSOD company ID and put the |
||||
certificate value inside the ds:X509Certificate markup |
||||
|
||||
CSOD control panel |
||||
~~~~~~~~~~~~~~~~~~ |
||||
|
||||
CSOD needs two things to configure LL::NG as an IDP: |
||||
|
||||
- Certificate |
||||
- SAML assertion |
||||
|
||||
Certificate |
||||
^^^^^^^^^^^ |
||||
|
||||
See :doc:`SAML security parameters<../samlservice>` to know how generate |
||||
a certificate from you SAML private key. |
||||
|
||||
SAML assertion |
||||
^^^^^^^^^^^^^^ |
||||
|
||||
You need to use the IDP initiated feature of LL::NG. Just call this URL: |
||||
|
||||
:: |
||||
|
||||
https://auth.example.com/saml/singleSignOn?IDPInitiated=1&sp=mycompanyid.csod.com |
||||
|
||||
.. |image0| image:: /applications/csod_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 3.6 KiB |
@ -0,0 +1,65 @@ |
||||
Discourse |
||||
========= |
||||
|
||||
|discourse.jpg| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Discourse <https://www.discourse.org/>`__ is a conversation-oriented |
||||
forum engine |
||||
|
||||
Discourse supports `its own Single-Sign-On |
||||
scheme <https://meta.discourse.org/t/official-single-sign-on-for-discourse-sso/13045>`__ |
||||
but is also compatible with standard protocols such as SAML and OpenID |
||||
Connect, through plugins. |
||||
|
||||
This documentation illustrates the OpenID Connect plugin. |
||||
|
||||
First, make sure you have set up LemonLDAP::NG 's |
||||
:doc:`OpenID Connect service<..//openidconnectservice>` and added |
||||
:doc:`a Relaying Party for your Discourse instance<..//idpopenidconnect>` |
||||
|
||||
Discourse can use the following OpenID Connect attributes to fill the |
||||
user's profile: |
||||
|
||||
:: |
||||
|
||||
* name |
||||
* email |
||||
* given_name |
||||
* family_name |
||||
* preferred_username |
||||
* picture |
||||
|
||||
Make sure you create a username and password for the Relying Party, and |
||||
that the discourse callback URL is allowed : |
||||
https://discourse.example.com/auth/oidc/callback |
||||
|
||||
Discourse configuration |
||||
----------------------- |
||||
|
||||
Plugin installation |
||||
~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Install the `Discourse OpenID Connect |
||||
Plugin <https://meta.discourse.org/t/openid-connect-authentication-plugin/103632>`__ |
||||
according to these instructions |
||||
|
||||
Plugin configuration |
||||
~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Browse to your Discourse admin interface, and to the plugin settings |
||||
|
||||
- openid_connect_enabled: *Yes* |
||||
- openid_connect_discovery_document: |
||||
https://auth.example.com/.well-known/openid-configuration |
||||
- openid_connect_client_id: *Client ID you chose when configuring the |
||||
Relying Party* |
||||
- openid_connect_client_secret: *Client Secret you chose when |
||||
configuring the Relying Party* |
||||
- openid_connect_authorize_scope: *openid email profile* |
||||
|
||||
.. |discourse.jpg| image:: /applications/discourse.jpg |
||||
:class: align-center |
||||
|
@ -0,0 +1,16 @@ |
||||
Django |
||||
====== |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Django <https://www.djangoproject.com/>`__ is a high-level Python Web |
||||
framework that encourages rapid development and clean, pragmatic design. |
||||
|
||||
Connector |
||||
--------- |
||||
|
||||
The Django connector is available on GitHub: |
||||
https://github.com/rclsilver/django-lemonldap |
||||
|
||||
See the README to know how install and configure it. |
After Width: | Height: | Size: 1.9 KiB |
@ -0,0 +1,127 @@ |
||||
Dokuwiki |
||||
======== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`DokuWiki <http://www.dokuwiki.org/>`__ is a standards compliant, simple |
||||
to use Wiki, mainly aimed at creating documentation of any kind. It is |
||||
targeted at developer teams, workgroups and small companies. It has a |
||||
simple but powerful syntax which makes sure the data files remain |
||||
readable outside the Wiki and eases the creation of structured texts. |
||||
All data is stored in plain text files – no database is required. |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
LemonLDAP::NG wiki uses Dokuwiki! |
||||
|
||||
HTTP headers |
||||
------------ |
||||
|
||||
You need to install a Dokuwiki plugin, available on `Dokuwiki plugins |
||||
registry <https://www.dokuwiki.org/plugins>`__: |
||||
https://www.dokuwiki.org/plugin:authlemonldap |
||||
|
||||
Plugin installation |
||||
~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Install the plugin using the `Plugin |
||||
Manager <https://www.dokuwiki.org/plugin:plugin>`__. |
||||
|
||||
Dokuwiki configuration |
||||
~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
As administrator, go in Dokuwiki parameters and set: |
||||
|
||||
- Authentication backend: authlemonldap |
||||
- Manager: set which users and/or groups will be admin |
||||
|
||||
|image1| |
||||
|
||||
Dokuwiki virtual host |
||||
~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Configure Dokuwiki virtual host like other |
||||
:doc:`protected virtual host<../configvhost>`. |
||||
|
||||
- For Apache: |
||||
|
||||
.. code:: apache |
||||
|
||||
<VirtualHost *:80> |
||||
ServerName dokuwiki.example.com |
||||
|
||||
PerlHeaderParserHandler Lemonldap::NG::Handler |
||||
|
||||
... |
||||
|
||||
</VirtualHost> |
||||
|
||||
- For Nginx: |
||||
|
||||
.. code:: nginx |
||||
|
||||
server { |
||||
listen 80; |
||||
server_name dokuwiki.example.com; |
||||
root /path/to/application; |
||||
# Internal authentication request |
||||
location = /lmauth { |
||||
internal; |
||||
include /etc/nginx/fastcgi_params; |
||||
fastcgi_pass unix:/var/run/llng-fastcgi-server/llng-fastcgi.sock; |
||||
# Drop post datas |
||||
fastcgi_pass_request_body off; |
||||
fastcgi_param CONTENT_LENGTH ""; |
||||
# Keep original hostname |
||||
fastcgi_param HOST $http_host; |
||||
# Keep original request (LLNG server will received /llauth) |
||||
fastcgi_param X_ORIGINAL_URI $request_uri; |
||||
} |
||||
|
||||
# Client requests |
||||
location / { |
||||
auth_request /lmauth; |
||||
auth_request_set $lmremote_user $upstream_http_lm_remote_user; |
||||
auth_request_set $lmlocation $upstream_http_location; |
||||
error_page 401 $lmlocation; |
||||
try_files $uri $uri/ =404; |
||||
|
||||
... |
||||
|
||||
include /etc/lemonldap-ng/nginx-lua-headers.conf; |
||||
} |
||||
location / { |
||||
try_files $uri $uri/ =404; |
||||
} |
||||
} |
||||
|
||||
Dokuwiki virtual host in Manager |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Go to the Manager and :doc:`create a new virtual host<../configvhost>` |
||||
for Dokuwiki. |
||||
|
||||
Configure the :doc:`access rules<../writingrulesand_headers>`. |
||||
|
||||
Configure the :doc:`headers<../writingrulesand_headers>`: |
||||
|
||||
- Auth-User $uid |
||||
- Auth-Cn: $cn |
||||
- Auth-Mail: $mail |
||||
- Auth-Groups: encode_base64($groups,"") |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
To allow execution of encode_base64() method, you must |
||||
deactivate the :doc:`Safe jail<../safejail>`. |
||||
|
||||
.. |image0| image:: /applications/dokuwiki_logo.png |
||||
:class: align-center |
||||
.. |image1| image:: /applications/screenshot_dokuwiki_configuration.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 14 KiB |
@ -0,0 +1,158 @@ |
||||
Drupal |
||||
====== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Drupal <http://drupal.org>`__ is a CMS written in PHP. It can works |
||||
with external modules to extends its functionalities. One of this module |
||||
can be used to delegate authentication server to the web server: |
||||
`Webserver Auth <http://drupal.org/project/Webserver_auth>`__. |
||||
|
||||
Installation |
||||
------------ |
||||
|
||||
Install `Webserver Auth <http://drupal.org/project/Webserver_auth>`__ |
||||
module, by downloading it, and unarchive it in the drupal modules/ |
||||
directory. |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
Drupal module activation |
||||
~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Go on Drupal administration interface and enable the Webserver Auth |
||||
module. |
||||
|
||||
Drupal virtual host |
||||
~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Configure Drupal virtual host like other |
||||
:doc:`protected virtual host<../configvhost>`. |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
If you are protecting Drupal with LL::NG as reverse |
||||
proxy, |
||||
:doc:`convert header into REMOTE_USER environment variable<../header_remote_user_conversion>`. |
||||
|
||||
- For Apache: |
||||
|
||||
.. code:: apache |
||||
|
||||
<VirtualHost *:80> |
||||
ServerName drupal.example.com |
||||
|
||||
PerlHeaderParserHandler Lemonldap::NG::Handler |
||||
|
||||
... |
||||
|
||||
</VirtualHost> |
||||
|
||||
- For Nginx: |
||||
|
||||
.. code:: nginx |
||||
|
||||
server { |
||||
listen 80; |
||||
server_name drupal.example.com; |
||||
root /path/to/application; |
||||
# Internal authentication request |
||||
location = /lmauth { |
||||
internal; |
||||
include /etc/nginx/fastcgi_params; |
||||
fastcgi_pass unix:/var/run/llng-fastcgi-server/llng-fastcgi.sock; |
||||
# Drop post datas |
||||
fastcgi_pass_request_body off; |
||||
fastcgi_param CONTENT_LENGTH ""; |
||||
# Keep original hostname |
||||
fastcgi_param HOST $http_host; |
||||
# Keep original request (LLNG server will received /llauth) |
||||
fastcgi_param X_ORIGINAL_URI $request_uri; |
||||
} |
||||
|
||||
# Client requests |
||||
location / { |
||||
auth_request /lmauth; |
||||
auth_request_set $lmremote_user $upstream_http_lm_remote_user; |
||||
auth_request_set $lmlocation $upstream_http_location; |
||||
error_page 401 $lmlocation; |
||||
try_files $uri $uri/ =404; |
||||
|
||||
... |
||||
|
||||
include /etc/lemonldap-ng/nginx-lua-headers.conf; |
||||
} |
||||
location / { |
||||
try_files $uri $uri/ =404; |
||||
} |
||||
} |
||||
|
||||
Drupal virtual host in Manager |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Go to the Manager and :doc:`create a new virtual host<../configvhost>` |
||||
for Drupal. |
||||
|
||||
Just configure the :doc:`access rules<../writingrulesand_headers>`. |
||||
|
||||
If using LL::NG as reverse proxy, configure the ``Auth-User`` |
||||
:doc:`header<../writingrulesand_headers>`, else no headers are needed. |
||||
|
||||
Protect only the administration pages |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
With the above solution, all the Drupal site will be protected, so no |
||||
anonymous access will be allowed. |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
You cannot use the ``unprotect`` rule because Drupal |
||||
navigation is based on query strings (?q=admin, ?q=user, etc.), and |
||||
unprotect rule only works on URL patterns. |
||||
|
||||
You can create a special virtual host and use `Apache rewrite |
||||
module <http://httpd.apache.org/docs/current/mod/mod_rewrite.html>`__ to |
||||
switch between open and protected hosts: |
||||
|
||||
.. code:: apache |
||||
|
||||
<VirtualHost *:80> |
||||
ServerName drupal.example.com |
||||
|
||||
# DocumentRoot |
||||
DocumentRoot /var/www/html/drupal/ |
||||
DirectoryIndex index.php |
||||
|
||||
# Redirect admin pages |
||||
RewriteEngine On |
||||
RewriteCond %{QUERY_STRING} q=(admin|user) |
||||
RewriteRule ^/(.*)$ http://admindrupal.example.com/$1 [R] |
||||
|
||||
LogLevel warn |
||||
ErrorLog /var/log/httpd/drupal-error.log |
||||
CustomLog /var/log/httpd/drupal-access.log combined |
||||
</VirtualHost> |
||||
<VirtualHost *:80> |
||||
ServerName admindrupal.example.com |
||||
|
||||
# SSO protection |
||||
PerlHeaderParserHandler Lemonldap::NG::Handler |
||||
|
||||
# DocumentRoot |
||||
DocumentRoot /var/www/html/drupal/ |
||||
DirectoryIndex index.php |
||||
|
||||
LogLevel warn |
||||
ErrorLog /var/log/httpd/admindrupal-error.log |
||||
CustomLog /var/log/httpd/admindrupal-access.log combined |
||||
</VirtualHost> |
||||
|
||||
.. |image0| image:: /applications/drupal_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,36 @@ |
||||
FusionDirectory |
||||
=============== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`FusionDirectory <https://www.fusiondirectory.org/>`__ provides a |
||||
solution to daily management of data stored in an LDAP directory. |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
.. _fusiondirectory-1: |
||||
|
||||
FusionDirectory |
||||
~~~~~~~~~~~~~~~ |
||||
|
||||
Go in Configuration and in Login and Session panel. Set: |
||||
|
||||
- **HTTP Header authentication**: Activate |
||||
- **Header name**: Auth-User |
||||
|
||||
See also |
||||
https://documentation.fusiondirectory.org/en/documentation/admin_installation/core_configuration#login-and-session |
||||
|
||||
LL::NG |
||||
~~~~~~ |
||||
|
||||
Just set the ``Auth-User`` header with the attribute that carries the |
||||
user login, for example ``$uid``. |
||||
|
||||
.. |image0| image:: /applications/fusiondirectory-logo.jpg |
||||
:class: align-center |
||||
|
@ -0,0 +1,190 @@ |
||||
Gitlab |
||||
====== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
See `Gitlab <https://about.gitlab.com/>`__ page for product |
||||
presentation. |
||||
|
||||
Gitlab allows one to use SAML to authenticate users, see `official |
||||
documentation <https://docs.gitlab.com/ee/integration/saml.html>`__ |
||||
|
||||
SAML |
||||
---- |
||||
|
||||
For this example, we use these sample values: |
||||
|
||||
- Gitlab URL : https://gitlab.example.com |
||||
- LL::NG portal URL : https://auth.example.com |
||||
|
||||
Gitlab configuration |
||||
~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Find the gitlab.rb file and add these settings: |
||||
|
||||
:: |
||||
|
||||
vi /etc/gitlab/gitlab.rb |
||||
|
||||
.. code:: ruby |
||||
|
||||
gitlab_rails['omniauth_enabled'] = true |
||||
gitlab_rails['omniauth_allow_single_sign_on'] = ['saml'] |
||||
gitlab_rails['omniauth_auto_link_saml_user'] = true |
||||
gitlab_rails['omniauth_block_auto_created_users'] = false |
||||
|
||||
gitlab_rails['omniauth_providers'] = [ |
||||
{ |
||||
name: 'saml', |
||||
args: { |
||||
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback', |
||||
idp_cert_fingerprint: '99:BE:7B:68:3F:XX:7D:EF:6B:C3:XX:C0:0E:XX:D4:EA:02:XX:83:2A', |
||||
idp_sso_target_url: 'https://auth.example.com/saml/singleSignOn', |
||||
issuer: 'https://gitlab.example.com', |
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress' |
||||
}, |
||||
label: 'Login with LL::NG' # optional label for SAML login button |
||||
} |
||||
] |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
To get the fingerprint of IDP certificate, copy SAML |
||||
certificate from LL::NG configuration in a file and use openssl: |
||||
|
||||
:: |
||||
|
||||
openssl x509 -in CERT.pem -noout -fingerprint |
||||
|
||||
|
||||
|
||||
You can force SAML by default with this option: |
||||
|
||||
.. code:: ruby |
||||
|
||||
gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'saml' |
||||
|
||||
In this case, users won't be able to log directly on gitlab. Set it once |
||||
you are sure the SAML configuration is valid. |
||||
|
||||
To apply changes: |
||||
|
||||
:: |
||||
|
||||
gitlab-ctl reconfigure |
||||
|
||||
LL::NG configuration |
||||
~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
We suppose LL::NG is configured as SAML IDP, and that you converted the |
||||
public key into a certificate for SAML signature. You must enable the |
||||
option to send certificates in response. If you don't want to, you need |
||||
to copy the certificate value into Gitlab configuration, in \`idp_cert\` |
||||
parameter. |
||||
|
||||
You can get Gitlab SAML metadata on |
||||
https://gitlab.example.com/users/auth/saml/metadata |
||||
|
||||
Register them in LL::NG and send these SAML attributes: |
||||
|
||||
- mail => email |
||||
- uid => uid |
||||
- cn => name |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
The value from LL::NG mail session attribute must be the |
||||
email of the user in Gitlab database, in order to associate |
||||
accounts. |
||||
|
||||
Manage groups |
||||
~~~~~~~~~~~~~ |
||||
|
||||
You can pass groups to Gitlab. For this, declare groups attribute in |
||||
gitlab.rb: |
||||
|
||||
.. code:: ruby |
||||
|
||||
... |
||||
gitlab_rails['omniauth_providers'] = [ |
||||
{ |
||||
name: 'saml', |
||||
groups_attribute: 'groups', |
||||
... |
||||
|
||||
And in LL::NG, export the groups attribute: |
||||
|
||||
- groups => groups |
||||
|
||||
OpenID Connect |
||||
-------------- |
||||
|
||||
**Alternatively** to SAML, you can choose to configure Gitlab to use |
||||
OpenID Connect. |
||||
|
||||
.. _gitlab-configuration-1: |
||||
|
||||
Gitlab configuration |
||||
~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
In ``/etc/gitlab/gitlab.rb`` |
||||
|
||||
.. code:: ruby |
||||
|
||||
... |
||||
gitlab_rails['omniauth_allow_single_sign_on'] = ['openid_connect'] |
||||
gitlab_rails['omniauth_block_auto_created_users'] = false |
||||
|
||||
gitlab_rails['omniauth_providers'] = [ |
||||
{ 'name' => 'openid_connect', |
||||
'label' => 'LemonLDAP::NG', |
||||
'args' => { |
||||
'name' => 'openid_connect', |
||||
'issuer' => 'https://auth.example.com', |
||||
'scope' => ['openid', 'profile', 'email'], |
||||
'response_type' => 'code', |
||||
'client_auth_method' => 'client_secret_post', |
||||
'discovery' => true, |
||||
'uid_field' => 'sub', |
||||
'client_options' => { |
||||
'redirect_uri' => 'http://gitlab.example.com/users/auth/openid_connect/callback', |
||||
'identifier' => 'LEMONLDAP_CLIENT_ID', |
||||
'secret' => 'LEMONLDAP_CLIENT_SECRET', |
||||
} |
||||
} |
||||
} |
||||
]; |
||||
|
||||
... |
||||
|
||||
.. _llng-configuration-1: |
||||
|
||||
LL::NG configuration |
||||
~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Add an OpenID Connect RP to LemonLDAP::NG |
||||
|
||||
- Chose a client ID and a client secret, and write the same values in |
||||
the ``gitlab.rb`` file above |
||||
- You need to chose an asymetrical signature algorithm for the ID Token |
||||
(RS256 or above) |
||||
- You also need to set a key identifier on your LemonLDAP::NG server in |
||||
``OpenID Connect service`` » ``Security`` » ``Signing key ID`` (use |
||||
something like ``default`` as the value). |
||||
- Make sure the attribute containing the user email in the |
||||
LemonLDAP::NG session is mapped to the ``email`` claim. |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
You need to set a key identifier, or you will get a |
||||
*JSON::JWK::Set::KidNotFound* error on Gitlab |
||||
|
||||
.. |image0| image:: /applications/gitlab_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 7.0 KiB |
@ -0,0 +1,38 @@ |
||||
GLPI |
||||
==== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`GLPI <http://www.glpi-project.org>`__ is the Information |
||||
Resource-Manager with an additional Administration- Interface. You can |
||||
use it to build up a database with an inventory for your company |
||||
(computer, software, printers...). It has enhanced functions to make the |
||||
daily life for the administrators easier, like a job-tracking-system |
||||
with mail-notification and methods to build a database with basic |
||||
information about your network-topology. |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
For GLPI >= 0.71, it is a simple configuration in GLPI: Setup → |
||||
Authentication. In “External authentications” click “Others” and in |
||||
“Field holding the login in the \_SERVER array” select “REMOTE_USER” |
||||
|
||||
For older version, check |
||||
http://wiki.glpi-project.org/doku.php?id=en:authautoad |
||||
|
||||
If you use Nginx, you need to add this in configuration: |
||||
|
||||
.. code:: nginx |
||||
|
||||
proxy_set_header Host $http_host; |
||||
proxy_set_header X-Forwarded-Host $http_host; |
||||
proxy_set_header X-Real-IP $remote_addr; |
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
||||
|
||||
.. |image0| image:: /applications/glpi_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,171 @@ |
||||
Google Apps |
||||
=========== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Google Apps <http://www.google.com/apps/>`__ can use SAML to |
||||
authenticate users, behaving as an SAML service provider, as explained |
||||
`here <http://code.google.com/googleapps/domain/sso/saml_reference_implementation.html>`__. |
||||
|
||||
To work with LL::NG it requires: |
||||
|
||||
- An `enterprise Google Apps |
||||
account <http://www.google.com/apps/intl/en/business/index.html>`__ |
||||
- LL::NG configured as :doc:`SAML Identity Provider<../idpsaml>` |
||||
- Registered users on Google Apps with the same email than those used |
||||
by LL::NG (email will be the NameID exchanged between Google Apps and |
||||
LL::NG) |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
Google Apps control panel |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
This part is based on `SimpleSAMLPHP |
||||
documentation <http://simplesamlphp.org/docs/1.6/simplesamlphp-googleapps>`__. |
||||
|
||||
As administrator, go in Google Apps control panel and click on Advanced |
||||
tools: |
||||
|
||||
|image1| |
||||
|
||||
Then select ``Set up single sign-on (SSO)``: |
||||
|
||||
|image2| |
||||
|
||||
Now configure all SAML parameters: |
||||
|
||||
|image3| |
||||
|
||||
- **Enable Single Sign-On**: check the box. Uncheck it to disable SAML |
||||
authentication (for example, if your Identity Provider is down). |
||||
- **Sign-in page URL**: SSO access point (HTTP-Redirect binding). |
||||
Example: http://auth.example.com/saml/singleSignOn |
||||
- **Sign-out page URL**: this in not the SLO access point (Google Apps |
||||
does not support SLO), but the main logout page. Example: |
||||
http://auth.example.com/?logout=1 |
||||
- **Change password URL**: where users can change their password. |
||||
Example: http://auth.example.com |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
You must check the option |
||||
``Use a specific domain transmitter`` to force Google Apps to send the |
||||
full entityId. |
||||
|
||||
Certificate |
||||
~~~~~~~~~~~ |
||||
|
||||
For the certificate, you can build it from the signing private key |
||||
registered in Manager. Select the key, and export it (button |
||||
``Download``). This will download the public and the private key. |
||||
|
||||
Keep the private key in a file, for example lemonldap-ng-priv.key, then |
||||
use openssl to generate an auto-signed certificate: |
||||
|
||||
:: |
||||
|
||||
openssl req -new -key lemonldap-ng-priv.key -out cert.csr |
||||
openssl x509 -req -days 3650 -in cert.csr -signkey lemonldap-ng-priv.key -out cert.pem |
||||
|
||||
You can now the upload the certificate (``cert.pem``) on Google Apps. |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
You can also use the certificate instead of public key in SAML |
||||
metadata, see :doc:`SAML service configuration<../samlservice>`\ |
||||
|
||||
New Service Provider |
||||
~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
You should have configured LL::NG as an |
||||
:doc:`SAML Identity Provider<../idpsaml>`, |
||||
|
||||
Now we will add Google Apps as a new SAML Service Provider: |
||||
|
||||
#. In Manager, click on SAML service providers and the button |
||||
``New service provider``. |
||||
#. Set GoogleApps as Service Provider name. |
||||
#. Set ``Email`` in ``Options`` » ``Authentication Response`` » |
||||
``Default NameID format`` |
||||
#. Disable all signature flags in ``Options`` » ``Signature``, except |
||||
``Sign SSO message`` which should be to ``On`` |
||||
#. Select ``Metadata``, and unprotect the field to paste the following |
||||
value: |
||||
|
||||
.. code:: xml |
||||
|
||||
<md:EntityDescriptor entityID="google.com" xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"> |
||||
<SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> |
||||
<AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://www.google.com/a/mydomain.org/acs" index="1" /> |
||||
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat> |
||||
</SPSSODescriptor> |
||||
</md:EntityDescriptor> |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
Change **mydomain.org** (in ``AssertionConsumerService`` |
||||
markup, parameter ``Location``) into your Google Apps domain. Also adapt |
||||
your entityID to match the Assertion issuer: google.com/a/mydomain.org |
||||
|
||||
|
||||
Application menu |
||||
~~~~~~~~~~~~~~~~ |
||||
|
||||
You can add a link in :doc:`application menu<../portalmenu>` to display |
||||
Google Apps to users. |
||||
|
||||
You need to adapt some parameters: |
||||
|
||||
- **Address**: set one of Google Apps URL (all Google Apps product a |
||||
distinct URL), for example |
||||
http://www.google.com/calendar/hosted/mydomain.org/render |
||||
- **Display**: As Google Apps is not a protected application, set to |
||||
``On`` to always display it |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
Change **mydomain.org** into your Google Apps |
||||
domain |
||||
|
||||
Logout |
||||
~~~~~~ |
||||
|
||||
Google Apps does not support Single Logout (SLO). |
||||
|
||||
Google Apps has a configuration parameter to redirect user on a specific |
||||
URL after Google Apps logout (see :doc:`Google Apps control panel<>`). |
||||
|
||||
To manage the other way (LL::NG → Google Apps), you can add a dedicated |
||||
:doc:`logout forward rule<../logoutforward>`: |
||||
|
||||
:: |
||||
|
||||
GoogleApps => http://www.google.com/calendar/hosted/mydomain.org/logout |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
Change **mydomain.org** into your Google Apps |
||||
domain |
||||
|
||||
.. |image0| image:: /applications/googleapps_logo.png |
||||
:class: align-center |
||||
.. |image1| image:: /documentation/googleapps-menu.png |
||||
:class: align-center |
||||
.. |image2| image:: /documentation/googleapps-sso.png |
||||
:class: align-center |
||||
.. |image3| image:: /documentation/googleapps-ssoconfig.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,77 @@ |
||||
Grafana |
||||
======= |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Grafana <https://grafana.com/>`__ is an Open Source dashboard for |
||||
monitoring databases such as Prometheus, Graphite or Elasticsearch |
||||
|
||||
Grafana offers social login through a generic OAuth 2 connector. |
||||
Thankfully, it is close enough to OpenID Connect to work well with |
||||
LemonLDAP::NG |
||||
|
||||
Pre-requisites |
||||
-------------- |
||||
|
||||
Grafana configuration |
||||
~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
You should start by following the generic OAuth2 documentation provided |
||||
by Grafana: https://grafana.com/docs/grafana/latest/auth/generic-oauth/ |
||||
|
||||
Your configuration file will have to look something like this: |
||||
|
||||
:: |
||||
|
||||
[auth.generic_oauth] |
||||
enabled = true |
||||
client_id = CHOOSE_A_CLIENT_ID |
||||
client_secret = CHOOSE_A_CLIENT_SECRET |
||||
scopes = openid email profile |
||||
auth_url = https://auth.example.com/oauth2/authorize |
||||
token_url = https://auth.example.com/oauth2/token |
||||
api_url = https://auth.example.com/oauth2/userinfo |
||||
allow_sign_up = true |
||||
name = LemonLDAP::NG |
||||
send_client_credentials_via_post = false |
||||
email_attribute_name = email |
||||
|
||||
LL:NG |
||||
~~~~~ |
||||
|
||||
Make sure you have already |
||||
:doc:`enabled OpenID Connect<../idpopenidconnect>` on your LemonLDAP::NG |
||||
server |
||||
|
||||
Then, add a Relaying Party with the following configuration |
||||
|
||||
- Options » Authentification » Client ID : same as ``client_id`` above |
||||
- Options » Allowed redirection address : same as ''client_secret '' |
||||
above |
||||
|
||||
If you want to transmit user attributes to Grafana, you also need to |
||||
configure |
||||
|
||||
- Extra Claims » |
||||
|
||||
- add a key named ``profile`` |
||||
- set a value of ``name username display_name upn`` |
||||
|
||||
- Exported Attributes (not all of them are mandatory) |
||||
|
||||
- replace the existing keys with the following 5 new keys: |
||||
|
||||
- ``name`` |
||||
- ``username`` |
||||
- ``display_name`` |
||||
- ``upn`` |
||||
- ``email`` |
||||
|
||||
- map them to your corresponding LemonLDAP::NG session attribute |
||||
|
||||
.. |image0| image:: /applications/grafana_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 5.9 KiB |
@ -0,0 +1,50 @@ |
||||
GRR |
||||
=== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`GRR <http://grr.devome.com/fr/>`__ is a room booking software. |
||||
|
||||
HTTP header |
||||
----------- |
||||
|
||||
Configuration |
||||
~~~~~~~~~~~~~ |
||||
|
||||
GRR has a SSO configuration page in its administration panel. |
||||
|
||||
Do not use Lemonldap mode, which is for a very old Lemonldap version, |
||||
but HTTP authentication. |
||||
|
||||
Set the default profile of connected users and which headers contains |
||||
surname, firstname and mail. |
||||
|
||||
|image1| |
||||
|
||||
GRR will check the username in REMOTE_USER, so use |
||||
:doc:`remote header conversion<../header_remote_user_conversion>` if you |
||||
are in proxy mode. |
||||
|
||||
GRR virtual host in LL::NG |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Access rules: |
||||
|
||||
- ^/index.php => accept |
||||
- default => unprotect |
||||
|
||||
Headers: |
||||
|
||||
- Auth-User $uid |
||||
- Auth-Sn: $sn |
||||
- Auth-GivenName: $givenName |
||||
- Auth-Mail: $mail |
||||
|
||||
.. |image0| image:: /applications/grr_logo.png |
||||
:class: align-center |
||||
.. |image1| image:: /applications/screenshot_grr_configuration.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 6.5 KiB |
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,247 @@ |
||||
HumHub |
||||
====== |
||||
|
||||
|image0| |
||||
|
||||
Présentation |
||||
------------ |
||||
|
||||
`HumHub <https://humhub.org/>`__ is a free and open-source social |
||||
network written on top of the `Yii2 PHP |
||||
framework <https://www.yiiframework.com/>`__ that provides an easy to |
||||
use toolkit for creating and launching your own social network. |
||||
|
||||
Unauthenticated users may connect using a login form against HumHub |
||||
local database or a LDAP directory, or choose which authentication |
||||
service they want to use. |
||||
|
||||
Administrator can configure one or several OAuth, OAuth2 or OIDC |
||||
authentication services to be displayed as buttons on the login page. |
||||
|
||||
With :doc:`OpenID Connect<>` authentication service, users successfully |
||||
authenticated by LemonLDAP::NG will be registered in HumHub upon their |
||||
first login. |
||||
|
||||
|
||||
.. warning:: |
||||
|
||||
HumHub retrieves a user from his username and the |
||||
authentication service he came through. As a result, a former local or |
||||
LDAP user will be rejected when trying to authenticate using another |
||||
authentication service. See |
||||
:doc:`Migrate former local or ldap Humhub account to connect through SSO<>` |
||||
|
||||
|
||||
OpenID Connect |
||||
-------------- |
||||
|
||||
|
||||
.. note:: |
||||
|
||||
This set-up works with option enablePrettyUrl activated in |
||||
Humhub. If not activated, rewrite URL in Humhub HTTP server and allowed |
||||
redirect URL in LemonLDAP needs to be adapted to work with the non |
||||
pretty URL format. |
||||
|
||||
Configuring HumHub |
||||
~~~~~~~~~~~~~~~~~~ |
||||
|
||||
First disable LDAP (Administration > Users section) and delete (or |
||||
:doc:`migrate<>`) any local users whose username or email are |
||||
conflicting with the username or email of your OIDC users. |
||||
|
||||
Then install and configure the `OIDC connector for |
||||
humhub <https://github.com/Worteks/humhub-auth-oidc>`__ extension using |
||||
composer : |
||||
|
||||
- Install composer. |
||||
|
||||
- Consider using prestissimo, to speed up composer update command (4x |
||||
faster): |
||||
|
||||
:: |
||||
|
||||
composer global require hirak/prestissimo |
||||
|
||||
:: |
||||
|
||||
* Go to {humhub_home} folder |
||||
|
||||
- Check if composer.json file is present. If not, download it for your |
||||
current version: |
||||
|
||||
:: |
||||
|
||||
wget https://raw.githubusercontent.com/humhub/humhub/v1.3.15/composer.json |
||||
|
||||
- Install the connector as a dependency: |
||||
|
||||
:: |
||||
|
||||
composer require --no-update --update-no-dev worteks/humhub-auth-oidc |
||||
composer update worteks/humhub-auth-oidc --no-dev --prefer-dist -vvv |
||||
|
||||
|
||||
.. note:: |
||||
|
||||
If you just need to update the connector, change its version |
||||
in composer.json and run the above composer update command. |
||||
|
||||
:: |
||||
|
||||
* Edit {humhub_home}/protected/config/common.php with the client configuration : |
||||
|
||||
:: |
||||
|
||||
'components' => [ |
||||
'authClientCollection' => [ |
||||
'clients' => [ |
||||
// ... |
||||
'lemonldapng' => [ |
||||
'class' => 'worteks\humhub\authclient\OIDC', |
||||
'domain' => 'https://auth.example.com', |
||||
'clientId' => 'myClientId', // Client ID for this RP in LemonLDAP |
||||
'clientSecret' => 'myClientSecret', // Client secret for this RP in LemonLDAP |
||||
'defaultTitle' => 'auth.example.com', // Text displayed in login button |
||||
'cssIcon' => 'fa fa-lemon-o', // Icon displayed in login button |
||||
], |
||||
], |
||||
// ... |
||||
] |
||||
|
||||
:: |
||||
|
||||
* Edit {humhub_home}/protected/config/web.php to disconnect users from LemonLDAP::NG after they logged out of Humhub: |
||||
|
||||
:: |
||||
|
||||
return [ |
||||
// ... |
||||
'modules' => [ |
||||
'user' => [ |
||||
'logoutUrl' => 'https://auth.domain.com/?logout=1', |
||||
], |
||||
] |
||||
]; |
||||
|
||||
User can now log in through SSO using a button on humhub logging page. |
||||
If you want to remove this intermediate login page, so user are |
||||
automatically logged in through SSO when they first access Humhub, you |
||||
can set up a redirection in the http server in front of the application |
||||
: |
||||
|
||||
- Example in apache |
||||
|
||||
:: |
||||
|
||||
RewriteEngine On |
||||
RewriteCond %{QUERY_STRING} !nosso [NC] |
||||
RewriteRule "^/user/auth/login$" "/user/auth/external?authclient=lemonldapng" [L,R=301] |
||||
|
||||
- Example in nginx |
||||
|
||||
:: |
||||
|
||||
if ($query_string !~ "nosso"){ |
||||
rewrite ^/user/auth/login$ /user/auth/external?authclient=lemonldapng permanent; |
||||
} |
||||
|
||||
If the authentication was successful but the user could not be |
||||
registered in Humhub (which often happen if there is a conflict between |
||||
source, username or email), Humhub will redirect to the login page to |
||||
display the error, which trigger a redirection to the portal, ultimately |
||||
triggering a loop error while registration error is not displayed. |
||||
|
||||
To change this behavior and display the registration error, |
||||
AuthController.onAuthSuccess method needs to be adapted so redirect to |
||||
SSO will be bypassed when a registration error occured. This works for |
||||
version 1.3.15 : |
||||
|
||||
:: |
||||
|
||||
* Go to {humhub_home} folder |
||||
* Execute |
||||
|
||||
:: |
||||
|
||||
sed -i "s|return \$this->redirect(\['/user/auth/login'\]);|return \$this->redirect(['/user/auth/login','nosso'=>'showerror']);|" protected/humhub/modules/user/controllers/AuthController.php |
||||
|
||||
Configuring LemonLDAP |
||||
~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
If not done yet, configure LemonLDAP::NG as an |
||||
:doc:`OpenID Connect service<..//openidconnectservice>`. |
||||
|
||||
Then, configure LemonLDAP::NG to recognize your HumHub instance as a |
||||
valid :doc:`new OpenID Connect Relying Party<..//idpopenidconnect>` |
||||
using the following parameters: |
||||
|
||||
:: |
||||
|
||||
* **Client ID**: the same you set in HumHub configuration |
||||
* **Client Secret**: the same you set in HumHub configuration |
||||
* Add the following **exported attributes** |
||||
* **given_name**: user's givenName attribute |
||||
* **family_name**: user's sn attribute |
||||
* **email**: user's mail attribute |
||||
* **Redirect URIs** containing your Yii2 auth client ID. |
||||
|
||||
Configuration sample using CLI: |
||||
|
||||
:: |
||||
|
||||
$ /usr/libexec/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \ |
||||
addKey \ |
||||
oidcRPMetaDataExportedVars/humhub given_name givenName \ |
||||
oidcRPMetaDataExportedVars/humhub family_name sn \ |
||||
oidcRPMetaDataExportedVars/humhub email mail \ |
||||
oidcRPMetaDataOptions/humhub oidcRPMetaDataOptionsClientID myClientId \ |
||||
oidcRPMetaDataOptions/humhub oidcRPMetaDataOptionsClientSecret myClientSecret \ |
||||
oidcRPMetaDataOptions/humhub oidcRPMetaDataOptionsRedirectUris 'https://humhub.example.com/user/auth/external?authclient=lemonldapng' \ |
||||
oidcRPMetaDataOptions/humhub oidcRPMetaDataOptionsPostLogoutRedirectUris 'https://humhub.example.com' \ |
||||
oidcRPMetaDataOptions/humhub oidcRPMetaDataOptionsIDTokenSignAlg RS512 \ |
||||
oidcRPMetaDataOptions/humhub oidcRPMetaDataOptionsIDTokenExpiration 3600 \ |
||||
oidcRPMetaDataOptions/humhub oidcRPMetaDataOptionsAccessTokenExpiration 3600 \ |
||||
oidcRPMetaDataOptions/humhub oidcRPMetaDataOptionsBypassConsent 1 && \ |
||||
|
||||
Migrate former local or ldap Humhub account to connect through SSO |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
You need to manually update Humhub database to swith authentication mode |
||||
to LemonLDAP::NG. |
||||
|
||||
Table "user": |
||||
|
||||
:: |
||||
|
||||
* Columns "username" and "email" should match exactly OIDC sub and email attributes ; |
||||
* If former ldap user, change column "auth_mode" to "local". |
||||
|
||||
Table "user_auth": |
||||
|
||||
:: |
||||
|
||||
* Add an entry with user_id, username and "lemonldapng" as source (or the name you chose in your connector configuration) : |
||||
|
||||
:: |
||||
|
||||
+---------+-------------+-------------+ |
||||
| user_id | source | source_id | |
||||
+---------+-------------+-------------+ |
||||
| 4 | lemonldapng | jdoe | |
||||
|
||||
Troubleshooting |
||||
~~~~~~~~~~~~~~~ |
||||
|
||||
If LemonLDAP login page freezes because of a browser security blockage, |
||||
adapt security's CSP Form Action to allow HumHub host : |
||||
|
||||
:: |
||||
|
||||
$ /usr/libexec/lemonldap-ng/bin/lemonldap-ng-cli -yes 1 \ |
||||
set \ |
||||
cspFormAction "'self' https://*.example.com" |
||||
|
||||
.. |image0| image:: /applications/humhub_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1,118 @@ |
||||
Jitsi Meet |
||||
========== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Jitsi Meet <https://github.com/jitsi/jitsi-meet>`__ is a WEBRTC-based |
||||
video conferencing application, powering the |
||||
`meet.jit.si <http://meet.jit.si>`__ online service. |
||||
|
||||
Users may install their own instance of Jitsi Meet for private use, in |
||||
which case, they may use authentication to control the creation of |
||||
conference rooms. |
||||
|
||||
The official documentation provides instructions on `how to configure |
||||
Jitsi Meet to use |
||||
Shibboleth <https://github.com/jitsi/jicofo/blob/master/doc/shibboleth.md>`__, |
||||
but with a little adaptation, it can work just as fine with |
||||
LemonLDAP::NG. |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
Pre-requisites |
||||
~~~~~~~~~~~~~~ |
||||
|
||||
In this guide, it is assumed that you have followed the `Jitsi Meet |
||||
quick |
||||
start <https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md>`__ |
||||
and that **you have installed Nginx on your Jitsi Meet server first** |
||||
|
||||
If you have not done that, the Jitsi Meet installer will not generate a |
||||
Nginx configuration file for you. This is not a problem is you are |
||||
already using your own reverse proxy. |
||||
|
||||
Jitsi Meet configuration |
||||
~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
As with the Shibboleth guide, you need to configure |
||||
``/etc/jitsi/jicofo/sip-communicator.properties`` |
||||
|
||||
:: |
||||
|
||||
org.jitsi.jicofo.auth.URL=shibboleth:default |
||||
org.jitsi.jicofo.auth.LOGOUT_URL=/logout/ |
||||
|
||||
This defines the login servlet as ``/login/`` and the logout URL as |
||||
``/logout/`` |
||||
|
||||
Jitsi Meet Nginx configuration |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
In the Nginx configuration that the Jitsi Meet quickstart generated, you |
||||
must add the following blocks, just like you would in a typical handler |
||||
configuration file: |
||||
|
||||
:: |
||||
|
||||
|
||||
location = /lmauth { |
||||
internal; |
||||
include /etc/nginx/fastcgi_params; |
||||
fastcgi_pass unix:/var/run/llng-fastcgi-server/llng-fastcgi.sock; |
||||
fastcgi_pass_request_body off; |
||||
fastcgi_param CONTENT_LENGTH ""; |
||||
fastcgi_param HOST $http_host; |
||||
fastcgi_param X_ORIGINAL_URI $request_uri; |
||||
} |
||||
|
||||
# Protect only the /login/ URL |
||||
# You may want to change this is your goal is to make the whole Jitsi Meet instance private |
||||
|
||||
location /login/ { |
||||
|
||||
auth_request /lmauth; |
||||
auth_request_set $lmremote_user $upstream_http_lm_remote_user; |
||||
auth_request_set $lmlocation $upstream_http_location; |
||||
error_page 401 $lmlocation; |
||||
|
||||
auth_request_set $mail $upstream_http_mail; |
||||
proxy_set_header mail $mail; |
||||
auth_request_set $displayname $upstream_http_displayName; |
||||
proxy_set_header displayName $displayname; |
||||
auth_request_set $lmcookie $upstream_http_cookie; |
||||
proxy_set_header Cookie: $lmcookie; |
||||
|
||||
proxy_pass http://127.0.0.1:8888/login; |
||||
} |
||||
|
||||
Jitsi Meet Virtual host in Manager |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Go to the Manager and :doc:`create a new virtual host<../configvhost>` |
||||
for Jitsi Meet. |
||||
|
||||
Configure the :doc:`access rules<../writingrulesand_headers>`. |
||||
|
||||
:: |
||||
|
||||
* Don't forget to configure the /logout/ URL |
||||
|
||||
Configure the following :doc:`headers<../writingrulesand_headers>`. |
||||
|
||||
- **mail**: $mail |
||||
- **displayName**: $cn |
||||
|
||||
|
||||
.. warning:: |
||||
|
||||
Jitsi meet expects to find a ``mail`` HTTP header, it |
||||
will ignore REMOTE_USER and only use the mail value to identify the |
||||
user. |
||||
|
||||
.. |image0| image:: /applications/logo-jitsimeet.png |
||||
:class: align-center |
||||
|
@ -0,0 +1,190 @@ |
||||
Liferay |
||||
======= |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Liferay <http://www.liferay.com/>`__ is an enterprise portal. |
||||
|
||||
Liferay can use LL::NG as an SSO provider but you have to manage how |
||||
users are created: |
||||
|
||||
- By hand in Liferay administration screens |
||||
- Imported from an LDAP directory |
||||
|
||||
Of course, integration will be full if you use the LDAP directory as |
||||
users backend for LL::NG and Liferay. |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
If the user is not created, or can not be created via |
||||
LDAP import, the connection to Liferay will be refused. With LDAP, |
||||
login, mail, first name and last name are required attributes. If one is |
||||
missing, the user is not created. |
||||
|
||||
This documentation just explains how to set up the SSO part. Please |
||||
refer to Liferay documentation to enable LDAP provisionning. |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
Liferay administration |
||||
~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Access to Liferay (first time): |
||||
|
||||
|image1| |
||||
|
||||
Login as administrator: |
||||
|
||||
|image2| |
||||
|
||||
Go to ``My Account``: |
||||
|
||||
|image3| |
||||
|
||||
Go to ``Portal`` » ``Settings``: |
||||
|
||||
|image4| |
||||
|
||||
Go to ``Configuration`` » ``Authentication``: |
||||
|
||||
|image5| |
||||
|
||||
In ``General``, fill at least the following information: |
||||
|
||||
- **How do users authenticate?**: by login |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
We advice to deactivate other options, cause users will use |
||||
LL::NG portal to modify or reset their password. |
||||
|
||||
|image6| |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
You need to activate LDAP authentication, else SSO |
||||
authentication will not work. Do this in the control panel or in the |
||||
configuration file: |
||||
|
||||
:: |
||||
|
||||
ldap.auth.enabled=true |
||||
|
||||
|
||||
|
||||
Then use the ``SiteMinder`` tab to configure SSO: |
||||
|
||||
- **Enabled**: Yes |
||||
- **Import from LDAP**: Yes (see :doc:`presentation<>`) |
||||
- **User Header**: Auth-User (case sensitive) |
||||
|
||||
|image7| |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
Do not forget to save your changes! |
||||
|
||||
Liferay virtual host |
||||
~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Configure Liferay virtual host like other |
||||
:doc:`protected virtual host<../configvhost>`. |
||||
|
||||
- For Apache: |
||||
|
||||
.. code:: apache |
||||
|
||||
<VirtualHost *:80> |
||||
ServerName liferay.example.com |
||||
|
||||
PerlHeaderParserHandler Lemonldap::NG::Handler |
||||
|
||||
... |
||||
|
||||
</VirtualHost> |
||||
|
||||
- For Nginx: |
||||
|
||||
.. code:: nginx |
||||
|
||||
server { |
||||
listen 80; |
||||
server_name liferay.example.com; |
||||
root /path/to/application; |
||||
# Internal authentication request |
||||
location = /lmauth { |
||||
internal; |
||||
include /etc/nginx/fastcgi_params; |
||||
fastcgi_pass unix:/var/run/llng-fastcgi-server/llng-fastcgi.sock; |
||||
# Drop post datas |
||||
fastcgi_pass_request_body off; |
||||
fastcgi_param CONTENT_LENGTH ""; |
||||
# Keep original hostname |
||||
fastcgi_param HOST $http_host; |
||||
# Keep original request (LLNG server will received /llauth) |
||||
fastcgi_param X_ORIGINAL_URI $request_uri; |
||||
} |
||||
|
||||
# Client requests |
||||
location / { |
||||
auth_request /lmauth; |
||||
auth_request_set $lmremote_user $upstream_http_lm_remote_user; |
||||
auth_request_set $lmlocation $upstream_http_location; |
||||
error_page 401 $lmlocation; |
||||
try_files $uri $uri/ =404; |
||||
|
||||
... |
||||
|
||||
include /etc/lemonldap-ng/nginx-lua-headers.conf; |
||||
} |
||||
location / { |
||||
try_files $uri $uri/ =404; |
||||
} |
||||
} |
||||
|
||||
Liferay virtual host in Manager |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Go to the Manager and :doc:`create a new virtual host<../configvhost>` |
||||
for Liferay. |
||||
|
||||
Just configure the :doc:`access rules<../writingrulesand_headers>`. You |
||||
can add a rule for logout: |
||||
|
||||
:: |
||||
|
||||
^/c/portal/logout => logout_sso |
||||
|
||||
Configure the ``Auth-User`` :doc:`header<../writingrulesand_headers>`. |
||||
|
||||
.. |image0| image:: /applications/liferay_logo.png |
||||
:class: align-center |
||||
.. |image1| image:: /documentation/liferay_1.png |
||||
:class: align-center |
||||
:width: 600px |
||||
.. |image2| image:: /documentation/liferay_2.png |
||||
:class: align-center |
||||
:width: 600px |
||||
.. |image3| image:: /documentation/liferay_3.png |
||||
:class: align-center |
||||
:width: 600px |
||||
.. |image4| image:: /documentation/liferay_4.png |
||||
:class: align-center |
||||
:width: 600px |
||||
.. |image5| image:: /documentation/liferay_5.png |
||||
:class: align-center |
||||
:width: 600px |
||||
.. |image6| image:: /documentation/liferay_6.png |
||||
:class: align-center |
||||
:width: 600px |
||||
.. |image7| image:: /documentation/liferay_7.png |
||||
:class: align-center |
||||
:width: 600px |
After Width: | Height: | Size: 6.9 KiB |
@ -0,0 +1,124 @@ |
||||
LimeSurvey |
||||
========== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`LimeSurvey <http://www.limesurvey.org>`__ is a web survey software |
||||
written in PHP. |
||||
|
||||
HTTP Headers |
||||
------------ |
||||
|
||||
LimeSurvey has a webserver authentication mode that allows one to |
||||
integrate it directly into LemonLDAP::NG. |
||||
|
||||
To have a stronger integration, we will configure LimeSurvey to |
||||
autocreate unknown users and use HTTP headers to fill name and mail. |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
We suppose that LimeSurvey is installed in |
||||
/var/www/html/limesurvey |
||||
|
||||
LimeSurvey configuration |
||||
~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
In Administration panel, go in Configuration > Parameters > Extensions |
||||
manager. Select the WebServer module and configure it. |
||||
|
||||
|image1| |
||||
|
||||
This is enough for the authentication part. |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
If you are blocked, you can deactivate the plugin with this |
||||
request in database: |
||||
|
||||
:: |
||||
|
||||
update lime_plugins SET active=0 where name="Authwebserver"; |
||||
|
||||
|
||||
|
||||
To configure account autocreation, you need to edit |
||||
application/config/config.php: The configuration is done in config.php: |
||||
|
||||
:: |
||||
|
||||
vi /var/www/html/limesurvey/application/config/config.php |
||||
|
||||
.. code:: php |
||||
|
||||
'config'=>array( |
||||
// debug: Set this to 1 if you are looking for errors. If you still get no errors after enabling this |
||||
// then please check your error-logs - either in your hosting provider admin panel or in some /logs directory |
||||
// on your webspace. |
||||
// LimeSurvey developers: Set this to 2 to additionally display STRICT PHP error messages and get full access to standard templates |
||||
'debug'=>0, |
||||
'debugsql'=>0, // Set this to 1 to enanble sql logging, only active when debug = 2 |
||||
// Update default LimeSurvey config here |
||||
'auth_webserver_autocreate_user' => true, |
||||
'auth_webserver_autocreate_profile' => Array('full_name' => $_SERVER['HTTP_AUTH_CN'],'email' => $_SERVER['HTTP_AUTH_MAIL'],'lang'=>'en'), |
||||
'auth_webserver_autocreate_permissions' => Array('surveys' => array('create'=>true,'read'=>false,'update'=>false,'delete'=>false)), |
||||
) |
||||
|
||||
See also |
||||
https://manual.limesurvey.org/Optional_settings#Authentication_delegation_with_automatic_user_import |
||||
|
||||
LimeSurvey virtual host |
||||
~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Configure LimeSurvey virtual host like other |
||||
:doc:`protected virtual host<../configvhost>`. |
||||
|
||||
LimeSurvey virtual host in Manager |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Go to the Manager and :doc:`create a new virtual host<../configvhost>` |
||||
for LimeSurvey. |
||||
|
||||
Headers |
||||
^^^^^^^ |
||||
|
||||
=========== ============== |
||||
Header name Description |
||||
=========== ============== |
||||
Auth-User user login |
||||
Auth-Cn user full name |
||||
Auth-Mail user email |
||||
=========== ============== |
||||
|
||||
Rules |
||||
^^^^^ |
||||
|
||||
========= =========== ======================================== |
||||
Rule name Expression Description |
||||
========= =========== ======================================== |
||||
Logout /sa/logout$ Logout rule (for example logout_app_sso) |
||||
Admin Allow only admin and superadmin users |
||||
Default default Allow only users with a LimeSurvey role |
||||
========= =========== ======================================== |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
You can set the default access to: |
||||
|
||||
:: |
||||
|
||||
* **accept**: all authenticated users will access surveys |
||||
* **unprotect**: no authentication will be asked to access surveys |
||||
|
||||
|
||||
|
||||
.. |image0| image:: /applications/limesurvey_logo.png |
||||
:class: align-center |
||||
.. |image1| image:: /applications/screenshot_limesurvey_configuration.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 8.8 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 17 KiB |
@ -0,0 +1,135 @@ |
||||
Mattermost Team Edition |
||||
======================= |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
Mattermost is a team-based instant messaging application. |
||||
|
||||
See `the official Mattermost website <https://mattermost.com/>`__ for a |
||||
complete presentation. |
||||
|
||||
Mattermost follows an Open Core development model. The freely available |
||||
`Team edition <https://docs.mattermost.com/developer/manifesto.html>`__ |
||||
contains all the basic chat features, but lack the integration |
||||
capabilities found in the `Enterprise |
||||
edition <https://mattermost.com/pricing/>`__. |
||||
|
||||
The Enterprise edition provides `SAML |
||||
integration <https://docs.mattermost.com/deployment/sso-saml.html>`__ |
||||
out of the box, and you can configure it just like |
||||
:doc:`any other SAML service in LemonLDAP::NG<..//idpsaml>` |
||||
|
||||
The Team edition, however, only provides SSO integration with Gitlab. |
||||
|
||||
However, it is possible to configure LemonLDAP::NG to behave exactly |
||||
like a Gitlab Oauth2 server, allowing Mattermost Team Edition to be |
||||
integrated with LemonLDAP::NG without having to use a |
||||
:doc:`Gitlab<gitlab>` server. |
||||
|
||||
|
||||
.. warning:: |
||||
|
||||
The following configuration requires your user database |
||||
to expose a unique numeric identifier for every user. |
||||
|
||||
Configuring Mattermost Team Edition |
||||
----------------------------------- |
||||
|
||||
Configuring Mattermost through the *System Console* will not allow you |
||||
to set the correct URLs. You need to edit the Mattermost configuration |
||||
file, and avoid changing Gitlab integration settings in the *System |
||||
Console* |
||||
|
||||
Set the following settings in ``/opt/mattermost/config/config.json`` |
||||
|
||||
:: |
||||
|
||||
"GitLabSettings": { |
||||
"Enable": true, |
||||
"Secret": "CHOOSE_A_CLIENT_SECRET", |
||||
"Id": "CHOOSE_A_CLIENT_ID", |
||||
"Scope": "", |
||||
"AuthEndpoint": "https://auth.example.com/oauth2/gitlab_authorize", |
||||
"TokenEndpoint": "https://auth.example.com/oauth2/token", |
||||
"UserApiEndpoint": "https://auth.example.com/oauth2/userinfo" |
||||
}, |
||||
|
||||
Configuring your web server |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Mattermost does not use OpenID Connect to communicate with Gitlab, but |
||||
uses plain OAuth2 instead. Because of that, LemonLDAP::NG will not |
||||
receive the ``scope=`` parameter and will display an error on the portal |
||||
when trying to authenticate. |
||||
|
||||
In order to fix this, we can add a fake OAuth2 authorize URL on the |
||||
LemonLDAP::NG server that will automatically add this ``scope=`` |
||||
parametrer, before sending the request to the correct OIDC URL |
||||
|
||||
Here is an example configuration for Nginx, add it in your Portal |
||||
virtualhost before any other rewrite rule: |
||||
|
||||
:: |
||||
|
||||
rewrite ^/oauth2/gitlab_(authorize.*)$ https://auth.example.com/oauth2/$1?scope=openid%20gitlab ; |
||||
|
||||
And if you are using Apache |
||||
|
||||
:: |
||||
|
||||
RewriteRule "^/oauth2/gitlab_authorize(.*)$" "https://auth.example.com/oauth2/authorize?$1scope=openid gitlab" [QSA,NE] |
||||
|
||||
Configuring LemonLDAP |
||||
~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
We now have to configure LemonLDAP::NG to recognize Mattermost as a |
||||
valid OAuth2 relaying party and send it the information it needs to |
||||
recognize a user. |
||||
|
||||
Add a :doc:`new OpenID Connect relaying party<..//idpopenidconnect>` |
||||
with the following parameters: |
||||
|
||||
:: |
||||
|
||||
* **Client ID**: the same you set in Mattermost configuration |
||||
* **Client Secret**: the same you set in Mattermost configuration |
||||
* Add a new scope in "Extra claims" |
||||
* **Key**: ''gitlab'' |
||||
* **Value**: ''id username name email'' |
||||
* Add the following exported attributes |
||||
* ''username'': set it to the session attribute containing the user login |
||||
* ''name'': session attribute containing the user's full name |
||||
* ''email'': session attribute containing the user's email |
||||
* ''id'': session attribute containing the user's numeric ID |
||||
|
||||
|
||||
.. warning:: |
||||
|
||||
Mattermost absolutely needs to receive a numerical value |
||||
in the ``id`` claim. If you are using a LDAP server, you could use the |
||||
``uidNumber`` LDAP attribute. If you use something else, you will have |
||||
to find a trick to assign a unique numeric ID to each Mattermost user. |
||||
|
||||
The ``id`` attribute has to be different for each user, since this is |
||||
the field Mattermost will use internally to map Gitlab identities to |
||||
Mattermost accouts. |
||||
|
||||
Troubleshooting |
||||
~~~~~~~~~~~~~~~ |
||||
|
||||
If you see a HTTP code 500 when going back to mattermost, with a panic() |
||||
in ``(*GitLabUser).IsValid(...)`` , it probably means that you are not |
||||
exporting the correct attributes, but it can also mean that ``id`` is |
||||
exported as a JSON string. |
||||
|
||||
If this case, it can help to create a macro, for example |
||||
``uidNumber_n``, with a value of ``$uidNumber + 0`` to force conversion |
||||
to a numeric value. You must then export it as the ``id`` field in the |
||||
Relaying Party configuration. |
||||
|
||||
.. |image0| image:: /applications/mattermost_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1,208 @@ |
||||
MediaWiki |
||||
========= |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`MediaWiki <http://www.mediawiki.org>`__ is a wiki software, used by the |
||||
well known `Wikipedia <http://www.wikipedia.org>`__. |
||||
|
||||
Several extensions allows one to configure SSO on MediaWiki: |
||||
|
||||
- `Automatic |
||||
REMOTE_USER <http://www.mediawiki.org/wiki/Extension:AutomaticREMOTE_USER>`__ |
||||
- `Siteminder |
||||
Authentication <http://www.mediawiki.org/wiki/Extension:Siteminder_Authentication>`__ |
||||
|
||||
We will explain how to use `Automatic |
||||
REMOTE_USER <http://www.mediawiki.org/wiki/Extension:AutomaticREMOTE_USER>`__ |
||||
extension. |
||||
|
||||
Installation |
||||
------------ |
||||
|
||||
The extension is presented here: |
||||
http://www.mediawiki.org/wiki/Extension:AutomaticREMOTE_USER |
||||
|
||||
You can download the code here: |
||||
https://www.mediawiki.org/wiki/Special:ExtensionDistributor/Auth_remoteuser |
||||
|
||||
You have to install '' Auth_remoteuser'' in the ``extensions/`` |
||||
directory of your MediaWiki installation: |
||||
|
||||
:: |
||||
|
||||
cp -a Auth_remoteuser/ extensions/ |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
MediWiki local configuration |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Then edit MediaWiki local settings |
||||
|
||||
:: |
||||
|
||||
vi LocalSettings.php |
||||
|
||||
.. code:: php |
||||
|
||||
require_once "$IP/extensions/Auth_remoteuser/Auth_remoteuser.php"; |
||||
$wgAuth = new Auth_remoteuser(); |
||||
|
||||
Add then extension configuration, for example: |
||||
|
||||
.. code:: php |
||||
|
||||
$wgAuthRemoteuserAuthz = true; /* Your own authorization test */ |
||||
$wgAuthRemoteuserName = $_SERVER["HTTP_AUTH_CN"]; /* User's name */ |
||||
$wgAuthRemoteuserMail = $_SERVER["HTTP_AUTH_MAIL"]; /* User's Mail */ |
||||
$wgAuthRemoteuserNotify = false; /* Do not send mail notifications */ |
||||
//$wgAuthRemoteuserDomain = "NETBIOSDOMAIN"; /* Remove NETBIOSDOMAIN\ from the beginning or @NETBIOSDOMAIN at the end of a IWA username */ |
||||
/* User's mail domain to append to the user name to make their email address */ |
||||
//$wgAuthRemoteuserMailDomain = "example.com"; |
||||
|
||||
// see http://www.mediawiki.org/wiki/Manual:Hooks/SpecialPage_initList |
||||
// and http://www.mediawiki.org/w/Manual:Special_pages |
||||
// and http://lists.wikimedia.org/pipermail/mediawiki-l/2009-June/031231.html |
||||
// disable login and logout functions for all users |
||||
function LessSpecialPages(&$list) { |
||||
unset( $list['Userlogout'] ); |
||||
unset( $list['Userlogin'] ); |
||||
return true; |
||||
} |
||||
$wgHooks['SpecialPage_initList'][]='LessSpecialPages'; |
||||
|
||||
// http://www.mediawiki.org/wiki/Extension:Windows_NTLM_LDAP_Auto_Auth |
||||
// remove login and logout buttons for all users |
||||
function StripLogin(&$personal_urls, &$wgTitle) { |
||||
unset( $personal_urls["login"] ); |
||||
unset( $personal_urls["logout"] ); |
||||
unset( $personal_urls['anonlogin'] ); |
||||
return true; |
||||
} |
||||
$wgHooks['PersonalUrls'][] = 'StripLogin'; |
||||
|
||||
|
||||
.. warning:: |
||||
|
||||
In last version of Auth_remoteuser and Mediawiki, empty |
||||
passwords are not authorized, so you may need to patch the extension |
||||
code if you get the error: "Unexpected REMOTE_USER authentication |
||||
failure. Login Error was:EmptyPass". If necessary, use the code |
||||
below to patch the extension: |
||||
|
||||
:: |
||||
|
||||
sed -i "s/'wpPassword' => ''/'wpPassword' => 'none'/" extensions/Auth_remoteuser/Auth_remoteuser.body.php |
||||
|
||||
|
||||
.. warning:: |
||||
|
||||
In last version of Auth_remoteuser and Mediawiki, |
||||
auto-provisioning requires REMOTE_USER to match the normalized mediawiki |
||||
username (for example: john_doe -> john doe), so you may need to patch |
||||
the extension code if you get the error: "Unexpected REMOTE_USER |
||||
authentication failure. Login Error was:WrongPluginPass" You can |
||||
use the code below for normalizing logins containing "_" in the |
||||
extension: |
||||
|
||||
:: |
||||
|
||||
sed -i '/$usertest = $this->getRemoteUsername();/a\ $usertest = str_replace( "_"," ", $usertest );' extensions/Auth_remoteuser/Auth_remoteuser.body.php |
||||
|
||||
MediaWiki virtual host |
||||
~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Configure MediaWiki virtual host like other |
||||
:doc:`protected virtual host<../configvhost>`. |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
If you are protecting MediaWiki with LL::NG as reverse |
||||
proxy, |
||||
:doc:`convert header into REMOTE_USER environment variable<../header_remote_user_conversion>`. |
||||
|
||||
- For Apache: |
||||
|
||||
.. code:: apache |
||||
|
||||
<VirtualHost *:80> |
||||
ServerName mediawiki.example.com |
||||
|
||||
PerlHeaderParserHandler Lemonldap::NG::Handler |
||||
|
||||
... |
||||
|
||||
</VirtualHost> |
||||
|
||||
- For Nginx: |
||||
|
||||
.. code:: nginx |
||||
|
||||
server { |
||||
listen 80; |
||||
server_name mediawiki.example.com; |
||||
root /path/to/application; |
||||
# Internal authentication request |
||||
location = /lmauth { |
||||
internal; |
||||
include /etc/nginx/fastcgi_params; |
||||
fastcgi_pass unix:/var/run/llng-fastcgi-server/llng-fastcgi.sock; |
||||
# Drop post datas |
||||
fastcgi_pass_request_body off; |
||||
fastcgi_param CONTENT_LENGTH ""; |
||||
# Keep original hostname |
||||
fastcgi_param HOST $http_host; |
||||
# Keep original request (LLNG server will received /llauth) |
||||
fastcgi_param X_ORIGINAL_URI $request_uri; |
||||
} |
||||
|
||||
# Client requests |
||||
location / { |
||||
auth_request /lmauth; |
||||
auth_request_set $lmremote_user $upstream_http_lm_remote_user; |
||||
auth_request_set $lmlocation $upstream_http_location; |
||||
error_page 401 $lmlocation; |
||||
try_files $uri $uri/ =404; |
||||
|
||||
... |
||||
|
||||
include /etc/lemonldap-ng/nginx-lua-headers.conf; |
||||
} |
||||
location / { |
||||
try_files $uri $uri/ =404; |
||||
} |
||||
} |
||||
|
||||
MediaWiki virtual host in Manager |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Go to the Manager and :doc:`create a new virtual host<../configvhost>` |
||||
for MediaWiki. |
||||
|
||||
Just configure the :doc:`access rules<../writingrulesand_headers>`. You |
||||
can also add a rule for logout: |
||||
|
||||
:: |
||||
|
||||
Userlogout => logout_sso |
||||
|
||||
You can create these two headers to fill user name and mail (see |
||||
extension configuration): |
||||
|
||||
:: |
||||
|
||||
Auth-Cn => $cn |
||||
Auth-Mail => $mail |
||||
|
||||
If using LL::NG as reverse proxy, configure also the ``Auth-User`` |
||||
:doc:`header<../writingrulesand_headers>`, |
||||
|
||||
.. |image0| image:: /applications/mediawiki_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 9.9 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 7.2 KiB |
@ -0,0 +1,137 @@ |
||||
NextCloud |
||||
========= |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`NextCloud <https://nextcloud.com/>`__ is a fork of Owncloud, suite of |
||||
client-server software for creating file hosting services and using |
||||
them. |
||||
|
||||
This documentation explains how to interconnect LemonLDAP::NG and |
||||
NextCloud using SAML 2.0 protocol. |
||||
|
||||
Pre-requisites |
||||
-------------- |
||||
|
||||
.. _nextcloud-1: |
||||
|
||||
NextCloud |
||||
~~~~~~~~~ |
||||
|
||||
You need to `install the |
||||
software <https://docs.nextcloud.com/server/10/admin_manual/installation/index.html>`__. |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
If your NextCloud is behind a proxy (thus having a private |
||||
IP), metadata generated by NextCloud won't work. |
||||
|
||||
Consider changing the configuration of NextCloud to force the domain, in |
||||
**$nextcloudrootwww/config/config.php**, add the following: |
||||
|
||||
.. code:: php |
||||
|
||||
'overwritehost' => 'nextcloud.example.com', |
||||
|
||||
|
||||
|
||||
You also need to enable the "SAML authentication" plugin in your |
||||
NextCloud. <code> + Apps -> Not enabled -> SAML authentication</code> |
||||
|
||||
LL:NG |
||||
~~~~~ |
||||
|
||||
You need to enable SAML 2.0 issuer module in LL:NG: |
||||
|
||||
:: |
||||
|
||||
"General Parameters -> Issuer modules -> SAML -> Activation" |
||||
|
||||
|image1| |
||||
|
||||
NextCloud, SAML 2.0 configuration |
||||
--------------------------------- |
||||
|
||||
Configuration of SAML 2.0 in NextCloud is pretty straightforward. |
||||
|
||||
:: |
||||
|
||||
Administration -> SAML authentication |
||||
|
||||
You will find the following fields: |
||||
|
||||
- **Attribute to map the UID to**: Identity attribute provided by your |
||||
LL:NG that will be used as UID in NextCloud. |
||||
- **Identity Provider Data**: |
||||
|
||||
- **Identifier of the IdP entity**: SAML Metadata URL of your LL:NG |
||||
- **URL Target of the IdP where the SP will send the Authentication |
||||
Request Message**: SingleSignOn URL of your LL:NG |
||||
- **URL Location of the IdP where the SP will send the SLO |
||||
Request**: SingleLogOut URL of your LL:NG |
||||
- **Public X.509 certificate of the IdP**: Certificate of your LL:NG |
||||
(see below for instructions) |
||||
|
||||
We need a few steps to generate our LL:NG certificate (unless you |
||||
already have one). You first need to create a pair of SSH Keys in LL:NG: |
||||
|
||||
:: |
||||
|
||||
SAML 2 Service -> Security Parameters -> Signature |
||||
|
||||
and click "New keys" |image2| |
||||
|
||||
Take the private key in a private.key file, and run the following: |
||||
|
||||
:: |
||||
|
||||
openssl req -new -key private.key -out cert.csr |
||||
openssl x509 -req -days 3650 -in cert.csr -signkey private.key -out cert.pem |
||||
|
||||
Copy/Paste the content of your new cert.pem in the "Public X.509 |
||||
certificate of the IdP" field of your NextCloud. |
||||
|
||||
Your fields should look like this: |image3| |
||||
|
||||
You can now download your metadata xml file. |
||||
|
||||
LL:NG, SAML 2.0 Service Provider configuration |
||||
---------------------------------------------- |
||||
|
||||
We now have to define a service provider (e.g our nextcloud) in LL:NG. |
||||
|
||||
Go to "SAML service providers", click on "Add SAML SP" and name it as |
||||
you want (example : 'NextCloud') |
||||
|
||||
In the new subtree 'NextCloud', open 'Metadata' and paste the content of |
||||
your previously downloaded file (or upload the file) |
||||
|
||||
|image4| |
||||
|
||||
Now go in "Exported attributes" and add, at least, the 'uid' |
||||
|
||||
|image5| |
||||
|
||||
Don't forget to save your configuration. |
||||
|
||||
You are now good to go, and you can add the application in |
||||
:doc:`your menu<../portalmenu>` and |
||||
:doc:`your virtual hosts<../configvhost>`. |
||||
|
||||
.. |image0| image:: /applications/nextcloud-logo.png |
||||
:class: align-center |
||||
.. |image1| image:: /applications/nextcloud_saml_activation.png |
||||
:class: align-center |
||||
.. |image2| image:: /applications/nextcloud_certificate_keys.png |
||||
:class: align-center |
||||
.. |image3| image:: /applications/nextcloud_saml_configuration.png |
||||
:class: align-center |
||||
.. |image4| image:: /applications/nextcloud_service_metadata.png |
||||
:class: align-center |
||||
.. |image5| image:: /applications/nextcloud_service_exportedattributes.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 187 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 102 KiB |
@ -0,0 +1,18 @@ |
||||
Nginx |
||||
===== |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
Nginx is fully supported by LemonLDAP::NG since version |
||||
1.9. |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
Nginx is a very fast web server. It can be used to host the portal or |
||||
the manager through its FastCGI support and can be used to protect |
||||
applications using the auth_request module (dialing with a FastCGI |
||||
authorization server). See |
||||
:doc:`installation pages<../start>` to know how install |
||||
and use it. |
@ -0,0 +1,260 @@ |
||||
OBM |
||||
=== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`OBM <http://obm.org>`__ is enterprise-class messaging and collaboration |
||||
platform for workgroup or enterprises with many thousands users. OBM |
||||
includes Groupware, messaging server, CRM, LDAP, Windows Domain, |
||||
smartphone and PDA synchronization… |
||||
|
||||
OBM is shipped with a LL::NG plugin with these features: |
||||
|
||||
- SSO on OBM web interface |
||||
- Logout |
||||
- User provisioning (account auto creation at first connection) |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
.. _obm-1: |
||||
|
||||
OBM |
||||
~~~ |
||||
|
||||
To enable LL::NG authentication plugin, go in ``/etc/obm/obm_conf.inc``: |
||||
|
||||
.. code:: php |
||||
|
||||
$auth_kind = 'LemonLDAP'; |
||||
|
||||
$lemonldap_config = Array( |
||||
"auto_update" => true, |
||||
"auto_update_force_user" => true, |
||||
"auto_update_force_group" => false, |
||||
"url_logout" => "https://OBMURL/logout", |
||||
"server_ip_address" => "localhost", |
||||
"server_ip_check" => false, |
||||
"debug_level" => "NONE", |
||||
// "debug_header_name" => "HTTP_OBM_UID", |
||||
// "group_header_name" => "HTTP_OBM_GROUPS", |
||||
"headers_map" => Array( |
||||
//"userobm_gid" => "HTTP_OBM_GID", |
||||
//"userobm_domain_id" => , |
||||
"userobm_login" => "HTTP_OBM_UID", |
||||
"userobm_password" => "HTTP_OBM_USERPASSWORD", |
||||
//"userobm_password_type" => , |
||||
"userobm_perms" => "HTTP_OBM_PERMS", |
||||
//"userobm_kind" => , |
||||
"userobm_lastname" => "HTTP_OBM_SN", |
||||
"userobm_firstname" => "HTTP_OBM_GIVENNAME", |
||||
// "userobm_title" => "HTTP_OBM_TITLE", |
||||
"userobm_email" => "HTTP_OBM_MAIL", |
||||
"userobm_datebegin" => "HTTP_OBM_DATEBEGIN", |
||||
//"userobm_account_dateexp" => , |
||||
//"userobm_delegation_target" => , |
||||
//"userobm_delegation" => , |
||||
"userobm_description" => "HTTP_OBM_DESCRIPTION", |
||||
//"userobm_archive" => , |
||||
//"userobm_hidden" => , |
||||
//"userobm_status" => , |
||||
//"userobm_local" => , |
||||
//"userobm_photo_id" => , |
||||
"userobm_phone" => "HTTP_OBM_TELEPHONENUMBER", |
||||
//"userobom_phone2" => , |
||||
//"userobm_mobile" => , |
||||
"userobm_fax" => "HTTP_OBM_FACSIMILETELEPHONENUMBER", |
||||
//"userobm_fax2" => , |
||||
"userobm_company" => "HTTP_OBM_O", |
||||
//"userobm_direction" => , |
||||
"userobm_service" => "HTTP_OBM_OU", |
||||
"userobm_address1" => "HTTP_OBM_POSTALADDRESS", |
||||
//"userobm_address2" => , |
||||
//"userobm_address3" => , |
||||
"userobm_zipcode" => "HTTP_OBM_POSTALCODE", |
||||
"userobm_town" => "HTTP_OBM_L", |
||||
"userobm_zipcode" => "HTTP_OBM_POSTALCODE", |
||||
"userobm_town" => "HTTP_OBM_L", |
||||
//"userobm_expresspostal" => , |
||||
//"userobm_host_id" => , |
||||
//"userobm_web_perms" => , |
||||
//"userobm_web_list" => , |
||||
//"userobm_web_all" => , |
||||
//"userobm_mail_perms" => , |
||||
//"userobm_mail_ext_perms" => , |
||||
//"userobm_mail_server_id" => , |
||||
//"userobm_mail_server_hostname" => , |
||||
"userobm_mail_quota" => "HTTP_OBM_MAILQUOTA", |
||||
//"userobm_nomade_perms" => , |
||||
//"userobm_nomade_enable" => , |
||||
//"userobm_nomade_local_copy" => , |
||||
//"userobm_email_nomade" => , |
||||
//"userobm_vacation_enable" => , |
||||
//"userobm_vacation_datebegin" => , |
||||
//"userobm_vacation_dateend" => , |
||||
//"userobm_vacation_message" => , |
||||
//"userobm_samba_perms" => , |
||||
//"userobm_samba_home" => , |
||||
//"userobm_samba_home_drive" => , |
||||
//"userobm_samba_logon_script" => , |
||||
// ---- Unused values ? ---- |
||||
"userobm_ext_id" => "HTTP_OBM_SERIALNUMBER", |
||||
//"userobm_system" => , |
||||
//"userobm_nomade_datebegin" => , |
||||
//"userobm_nomade_dateend" => , |
||||
//"userobm_location" => , |
||||
//"userobm_education" => , |
||||
), |
||||
); |
||||
|
||||
Parameters: |
||||
|
||||
- **url_logout**: URL used by OBM to logout, will be caught by LL::NG |
||||
- **headers_map**: map OBM internal field to LL::NG header |
||||
|
||||
Edit also OBM configuration to enable LL::NG Handler: |
||||
|
||||
- For Apache: |
||||
|
||||
.. code:: apache |
||||
|
||||
<VirtualHost *:80> |
||||
ServerName obm.example.com |
||||
|
||||
# SSO protection |
||||
PerlHeaderParserHandler Lemonldap::NG::Handler |
||||
|
||||
DocumentRoot /usr/share/obm/php |
||||
|
||||
... |
||||
|
||||
</VirtualHost> |
||||
|
||||
- For Nginx: |
||||
|
||||
.. code:: nginx |
||||
|
||||
server { |
||||
listen 80; |
||||
server_name obm.example.com; |
||||
root /usr/share/obm/php; |
||||
# Internal authentication request |
||||
location = /lmauth { |
||||
internal; |
||||
include /etc/nginx/fastcgi_params; |
||||
fastcgi_pass unix:/var/run/llng-fastcgi-server/llng-fastcgi.sock; |
||||
# Drop post datas |
||||
fastcgi_pass_request_body off; |
||||
fastcgi_param CONTENT_LENGTH ""; |
||||
# Keep original hostname |
||||
fastcgi_param HOST $http_host; |
||||
# Keep original request (LLNG server will received /llauth) |
||||
fastcgi_param X_ORIGINAL_URI $request_uri; |
||||
} |
||||
|
||||
# Client requests |
||||
location ~ \.php$ { |
||||
auth_request /lmauth; |
||||
auth_request_set $lmremote_user $upstream_http_lm_remote_user; |
||||
auth_request_set $lmlocation $upstream_http_location; |
||||
error_page 401 $lmlocation; |
||||
try_files $uri $uri/ =404; |
||||
|
||||
... |
||||
|
||||
include /etc/lemonldap-ng/nginx-lua-headers.conf; |
||||
} |
||||
location / { |
||||
try_files $uri $uri/ =404; |
||||
} |
||||
} |
||||
|
||||
LL::NG |
||||
~~~~~~ |
||||
|
||||
Attributes and macros |
||||
^^^^^^^^^^^^^^^^^^^^^ |
||||
|
||||
You will need to collect all attributes needed to create a user in OBM, |
||||
this includes: |
||||
|
||||
- First name |
||||
- Last name |
||||
- Login |
||||
- Mail |
||||
- ... |
||||
|
||||
To add these attributes, go in Manager, ``Variables`` » |
||||
``Exported Variables``. |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
If you plan to forward user's password to OBM, then you |
||||
have to :doc:`keep the password in session<../passwordstore>`. |
||||
|
||||
You may also create these macros to manage OBM administrator account |
||||
(``Variables`` » ``Macros``): |
||||
|
||||
===== ====================================================== =============================== == ============================== |
||||
field value |
||||
===== ====================================================== =============================== == ============================== |
||||
uidR ($uid =~ /^admin0/i)[0] ? "admin0\@global.virt" : $uid |
||||
mailR %%($uid =~ / admin0/i)[0] ? "" : ($mail =~ / ([ @]+)/)[0] . "\@example.com" %% |
||||
===== ====================================================== =============================== == ============================== |
||||
|
||||
Virtual host |
||||
^^^^^^^^^^^^ |
||||
|
||||
Create OBM virtual host (for example obm.example.com) in LL::NG |
||||
configuration: ``Virtual Hosts`` » ``New virtual host``. |
||||
|
||||
Then edit rules and headers. |
||||
|
||||
Rules |
||||
''''' |
||||
|
||||
Define at least: |
||||
|
||||
- **Default rule**: who can access to the application |
||||
- **Logout rule**: catch OBM logout |
||||
- **Exceptions**: allow anonymous access for specific URLs (connectors, |
||||
etc.) |
||||
|
||||
============================= ============================= |
||||
field value |
||||
============================= ============================= |
||||
^/logout logout_sso |
||||
^/obm-sync unprotect |
||||
^/minig unprotect |
||||
^/Microsoft-Server-ActiveSync unprotect |
||||
^/caldav unprotect |
||||
default accept (or whatever you want) |
||||
============================= ============================= |
||||
|
||||
Headers |
||||
''''''' |
||||
|
||||
Define headers used in OBM mapping, for example: |
||||
|
||||
================ ========== |
||||
field valeur |
||||
================ ========== |
||||
OBM_GIVENNAME $givenName |
||||
OBM_GROUPS $groups |
||||
OBM_UID $uidR |
||||
OBM_MAIL $mailR |
||||
OBM_USERPASSWORD $_password |
||||
================ ========== |
||||
|
||||
Other |
||||
^^^^^ |
||||
|
||||
Do not forget to add OBM in :doc:`applications menu<../portalmenu>`. |
||||
|
||||
.. |image0| image:: /applications/obm_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 13 KiB |
@ -0,0 +1,75 @@ |
||||
Office 365 |
||||
========== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Office 365 <https://en.wikipedia.org/wiki/Office_365>`__ provides |
||||
online access to Microsoft products like Office, Outlook or Yammer. |
||||
Authentication is done on https://login.microsoftonline.com/ and can be |
||||
forwarded to an SAML Identity Provider. |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
.. _office-365-1: |
||||
|
||||
Office 365 |
||||
~~~~~~~~~~ |
||||
|
||||
You first need to install AzureAD PowerShell to be able to run |
||||
administrative commands. |
||||
|
||||
Then run this script: |
||||
|
||||
.. code:: bash |
||||
|
||||
$dom = "mycompany.com" |
||||
$brand = "My Company" |
||||
$url = "https://auth.example.com/saml/singleSignOn" |
||||
$uri = "https://auth.example.com/saml/metadata" |
||||
$logouturl = "https://auth.example.com/?logout=1" |
||||
$cert = "xxxxxxxxxxxxxxxxxxx" |
||||
|
||||
Set-MsolDomainAuthentication –DomainName $dom -FederationBrandName $brand -Authentication Federated -PassiveLogOnUri $url -SigningCertificate $cert -IssuerUri $uri -LogOffUri $logouturl -PreferredAuthenticationProtocol SAMLP |
||||
|
||||
Where parameters are: |
||||
|
||||
- dom: Your Office 365 domain |
||||
- brand: Simple label |
||||
- url: The SAML SSO endpoint |
||||
- uri: The SAML metadata endpoint |
||||
- logouturl: Logout URL |
||||
- cert: The SAML certificate containing the signature public key |
||||
|
||||
If you have several Office365 domains, you can't use the same URLs for |
||||
each domains. To be able to have a single SAML IDP for several domains, |
||||
you must add the 'domain' GET parameters at the end of SSO endpoint and |
||||
metadata URLs, for example: |
||||
|
||||
- domain 'mycompany.com': |
||||
|
||||
- url: https://auth.example.com/saml/singleSignOn?domain=mycompany |
||||
- uri: https://auth.example.com/saml/metadata?domain=mycompany |
||||
|
||||
- domain 'myfirm.com': |
||||
|
||||
- url: https://auth.example.com/saml/singleSignOn?domain=myfirm |
||||
- uri: https://auth.example.com/saml/metadata?domain=myfirm |
||||
|
||||
LemonLDAP::NG |
||||
~~~~~~~~~~~~~ |
||||
|
||||
Create a new SAML Service Provider and import Microsoft metadata from |
||||
https://nexus.microsoftonline-p.com/federationmetadata/saml20/federationmetadata.xml |
||||
|
||||
Set the NameID value to persistent, or any immutable value for the user. |
||||
|
||||
Create a SAML attribute named IDPEmail which contains the user principal |
||||
name (UPN). |
||||
|
||||
.. |image0| image:: /applications/logo_office_365.png |
||||
:class: align-center |
||||
|
@ -0,0 +1,109 @@ |
||||
phpLDAPadmin |
||||
============ |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`phpLDAPadmin <http://phpldapadmin.sourceforge.net>`__ is an LDAP |
||||
administration tool written in PHP. |
||||
|
||||
phpLDAPadmin will connect to the directory with a static DN and |
||||
password, and so will not request authentication anymore. The access to |
||||
phpLDAPadmin will be protected by LemonLDAP::NG with specific access |
||||
rules. |
||||
|
||||
|
||||
.. warning:: |
||||
|
||||
phpLDAPadmin will have no idea of the user connected to |
||||
the WebSSO. So a simple user can have admin rights on the LDAP directory |
||||
if your access rules are too lazy. |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
phpLDAPadmin local configuration |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Just set the authentication type to ``config`` and indicate DN and |
||||
password inside the file ``config.php``: |
||||
|
||||
.. code:: php |
||||
|
||||
$ldapservers->SetValue($i,'server','auth_type','config'); |
||||
$ldapservers->SetValue($i,'login','dn','cn=Manager,dc=example,dc=com'); |
||||
$ldapservers->SetValue($i,'login','pass','secret'); |
||||
|
||||
phpLDAPadmin virtual host |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Configure phpLDAPadmin virtual host like other |
||||
:doc:`protected virtual host<../configvhost>`. |
||||
|
||||
- For Apache: |
||||
|
||||
.. code:: apache |
||||
|
||||
<VirtualHost *:80> |
||||
ServerName phpldapadmin.example.com |
||||
|
||||
PerlHeaderParserHandler Lemonldap::NG::Handler |
||||
|
||||
... |
||||
|
||||
</VirtualHost> |
||||
|
||||
- For Nginx: |
||||
|
||||
.. code:: nginx |
||||
|
||||
server { |
||||
listen 80; |
||||
server_name phpldapadmin.example.com; |
||||
root /path/to/application; |
||||
# Internal authentication request |
||||
location = /lmauth { |
||||
internal; |
||||
include /etc/nginx/fastcgi_params; |
||||
fastcgi_pass unix:/var/run/llng-fastcgi-server/llng-fastcgi.sock; |
||||
# Drop post datas |
||||
fastcgi_pass_request_body off; |
||||
fastcgi_param CONTENT_LENGTH ""; |
||||
# Keep original hostname |
||||
fastcgi_param HOST $http_host; |
||||
# Keep original request (LLNG server will received /llauth) |
||||
fastcgi_param X_ORIGINAL_URI $request_uri; |
||||
} |
||||
|
||||
# Client requests |
||||
location / { |
||||
auth_request /lmauth; |
||||
auth_request_set $lmremote_user $upstream_http_lm_remote_user; |
||||
auth_request_set $lmlocation $upstream_http_location; |
||||
error_page 401 $lmlocation; |
||||
try_files $uri $uri/ =404; |
||||
|
||||
... |
||||
|
||||
include /etc/lemonldap-ng/nginx-lua-headers.conf; |
||||
} |
||||
location / { |
||||
try_files $uri $uri/ =404; |
||||
} |
||||
} |
||||
|
||||
phpLDAPadmin virtual host in Manager |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Go to the Manager and :doc:`create a new virtual host<../configvhost>` |
||||
for phpLDAPadmin. |
||||
|
||||
Just configure the :doc:`access rules<../writingrulesand_headers>`. |
||||
|
||||
No :doc:`headers<../writingrulesand_headers>` are required. |
||||
|
||||
.. |image0| image:: /applications/phpldapadmin_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,48 @@ |
||||
RoundCube |
||||
========= |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`RoundCube <http://www.roundcube.net>`__ webmail is a browser-based |
||||
multilingual IMAP client with an application-like user interface. It |
||||
provides full functionality you expect from an email client, including |
||||
MIME support, address book, folder manipulation, message searching and |
||||
spell checking. |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
LemonLDAP::NG |
||||
~~~~~~~~~~~~~ |
||||
|
||||
- Add a new virtual host webmail.domain.tld |
||||
- Add a new rule: |
||||
|
||||
:: |
||||
|
||||
"^/\?_task\=logout" -> "logout_app https://auth.domain.tld" |
||||
|
||||
- in HTTP headers, you need Auth-User ($mail) and Auth-Pw ($_password). |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
To be able to forward password to RoundCube, see |
||||
:doc:`how to store password in session<../passwordstore>`\ |
||||
|
||||
- Configure :doc:`Apache or Nginx virtual host<../configvhost>` |
||||
|
||||
.. _roundcube-1: |
||||
|
||||
RoundCube |
||||
~~~~~~~~~ |
||||
|
||||
- install http_authentication plugin |
||||
- Patch it to replace ``PHP_AUTH_*`` by ``HTTP_AUTH_*`` |
||||
- enable http_authentication plugin in main.inc.php : |
||||
|
||||
.. code:: php |
||||
|
||||
$rcmail_config['plugins'] = array('http_authentication'); |
||||
|
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,130 @@ |
||||
SalesForce |
||||
========== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
Salesforce Inc. is a cloud computing company. It is best known for their |
||||
CRM products and social networking applications. |
||||
|
||||
It allows one to use SAML to authenticate users. It can deal with both |
||||
SP and IdP initiated modes. |
||||
|
||||
This page presents the SP initiated mode. |
||||
|
||||
To work with LL::NG it requires: |
||||
|
||||
- LL::NG configured as :doc:`SAML Identity Provider<../idpsaml>` |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
You should have configured LL::NG as a |
||||
:doc:`SAML Identity Provider<../idpsaml>`. |
||||
|
||||
Create Salesforce domain |
||||
~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
|image1| |
||||
|
||||
For using SP-initiated mode, you must create your salesforce domain. |
||||
Creation can take up to 1 hour. (if it is superior to 1h, then there is |
||||
a problem. Problems are generally resolved in up to 72 hours) |
||||
|
||||
Then you must **deploy** this domain in order to go on with the |
||||
configuration. |
||||
|
||||
Finally, just ensure that at least: |
||||
|
||||
- Login policy |
||||
- Redirect policy |
||||
- domain name |
||||
- authentication service |
||||
|
||||
match with the correct values. (adapt the domain if necessary) |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
For now, the authentication service parameter has no |
||||
domain available. You must come back later to fill this parameter. Once |
||||
SAML cinematics are working, you can then put your domain, and delete |
||||
the login form, and you'll have an automatic redirection to your |
||||
Identity Provider (no need for the user to click). Note that you can |
||||
always access Salesforce by the general login page: |
||||
https://login.salesforce.com\ |
||||
|
||||
SAML settings |
||||
~~~~~~~~~~~~~ |
||||
|
||||
Salesforce is not able to read metadata, you must fill the information |
||||
into a form. |
||||
|
||||
|image2| |
||||
|
||||
Go to the SAML Single Sign On settings, and fill these information: |
||||
|
||||
- Name: should be filled automatically with your organization or domain |
||||
- SAML Version: check that version 2.0 is used |
||||
- Issuer: this is the LemonLDAP::NG (our IdP) Entity Id, which is by |
||||
default #PORTAL#/saml/metadata |
||||
- Identity Provider Certificate: whereas it is mentioned that this is |
||||
the authentication certificate, you must give your LemonLDAP::NG |
||||
(IdP) signing certificate. If you don't have one, create it with the |
||||
signing key pair already generated (you could do this with openssl). |
||||
SSL authentication (https) does not seem to be checked anyway. |
||||
- Signing Certificate: choose a certificate for SP signature. (create |
||||
one if none is present) |
||||
- Assertion decryption Certificate: choose a certificate only if you |
||||
want to cipher your assertion. (default is not to cipher) |
||||
- SAML Identity Type: choose Federation ID. This means that the user |
||||
Name ID will be mapped to the Federation ID field. (see next section) |
||||
- SAML Identity Location: choose if the user Name ID is held in the |
||||
subject or in some attribute |
||||
- Identity Provider Login URL: the user/password SAML portal location |
||||
on the IdP |
||||
- Identity Provider Logout URL: the logout location on the IdP |
||||
- Custom Error URL: you can redirect the user to a special page when an |
||||
error is happening |
||||
- SP Initiated Binding: chose any of the supported binding (every one |
||||
listed there is currently supported on LemonLDAP::NG) HTTP POST is a |
||||
good choice |
||||
- Salesforce Login URL: generated automatically. This is the entry |
||||
point of our login cinematic. |
||||
- OAuth 2.0 Token Endpoint: not used here |
||||
- API Name: filled automatically |
||||
- User Provisioning Enabled: should create automatically the user in |
||||
Salesforce (not functionnal right now) |
||||
- EntityId: Salesforce (the SP) Entity ID. Fill this field accordingly. |
||||
It should be the same value as the organization domain url, displayed |
||||
on the previous section |
||||
|
||||
Configure Federation ID |
||||
~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Finally, configure for each user his Federation ID value. It will be the |
||||
link between the SAML assertion coming from LemonLDAP::NG (the IdP) and |
||||
a given user in Salesforce. Here, the mail has been chosen as the user |
||||
Name ID. |
||||
|
||||
|image3| |
||||
|
||||
Once this is completed, click to export the Salesforce metadata and |
||||
import them into LemonLDAP::NG, into the declaration of the Salesforce |
||||
Service Provider. |
||||
|
||||
See |
||||
:doc:`Register partner Service Provider on LemonLDAP::NG<../idpsaml>` |
||||
configuration chapter. |
||||
|
||||
.. |image0| image:: /applications/salesforce-logo.jpg |
||||
:class: align-center |
||||
.. |image1| image:: /applications/my_domain_salesforce-resize-web.png |
||||
:class: align-center |
||||
.. |image2| image:: /applications/saml_sso_settings-resize-web.png |
||||
:class: align-center |
||||
.. |image3| image:: /applications/user_federation_id-resize-web.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 152 KiB |
After Width: | Height: | Size: 106 KiB |
@ -0,0 +1,20 @@ |
||||
SAP |
||||
=== |
||||
|
||||
|SAP| |
||||
|
||||
HTTP header |
||||
----------- |
||||
|
||||
Read the following documentation: |
||||
http://help.sap.com/saphelp_nw70/helpdata/en/d0/a3d940c2653126e10000000a1550b0/frameset.htm |
||||
|
||||
SAML |
||||
---- |
||||
|
||||
Read the following documentation: |
||||
https://help.sap.com/saphelp_nw70/helpdata/en/94/695b3ebd564644e10000000a114084/content.htm |
||||
|
||||
.. |SAP| image:: /applications/SAPLogo.gif |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 538 B |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 28 KiB |
@ -0,0 +1,253 @@ |
||||
simpleSAMLphp |
||||
============= |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`simpleSAMLphp <https://simplesamlphp.org/>`__ is an identity/service |
||||
provider written in PHP. It supports a lot of protocols like CAS, OpenID |
||||
and SAML. |
||||
|
||||
This documentation explains how to interconnect LemonLDAP::NG and |
||||
simpleSAMLphp using SAML 2.0 protocol. |
||||
|
||||
Pre-requisites |
||||
-------------- |
||||
|
||||
.. _simplesamlphp-1: |
||||
|
||||
simpleSAMLphp |
||||
~~~~~~~~~~~~~ |
||||
|
||||
You need to `install the |
||||
software <https://simplesamlphp.org/docs/stable/simplesamlphp-install>`__. |
||||
If using Debian, just do: |
||||
|
||||
:: |
||||
|
||||
apt-get install simplesamlphp |
||||
|
||||
We suppose that configuration is done in ``/etc/simplesamlphp`` and that |
||||
simpleSAMLphp is accessible at http://localhost/simplesamlphp. |
||||
|
||||
To be able to sign SAML messages, you need to create a certificate. |
||||
First set where certificates are stored: |
||||
|
||||
:: |
||||
|
||||
vi /etc/simplesamlphp/config.php |
||||
|
||||
.. code:: php |
||||
|
||||
'certdir' => '/etc/simplesamlphp/certs/', |
||||
|
||||
Create directory and generate the certificate |
||||
|
||||
:: |
||||
|
||||
mkdir /etc/simplesamlphp/certs/ |
||||
cd /etc/simplesamlphp/certs/ |
||||
openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out saml.crt -keyout saml.pem |
||||
|
||||
Then associate this certificate to the default SP: |
||||
|
||||
:: |
||||
|
||||
vi /etc/simplesamlphp/authsources.php |
||||
|
||||
.. code:: php |
||||
|
||||
'default-sp' => array( |
||||
'saml:SP', |
||||
'privatekey' => 'saml.pem', |
||||
'certificate' => 'saml.crt', |
||||
|
||||
LemonLDAP::NG |
||||
~~~~~~~~~~~~~ |
||||
|
||||
You need to configure :doc:`SAML Service<../samlservice>`. Be sure to |
||||
convert public key in a certificate, as described in the |
||||
:doc:`security chapter<../samlservice>` as simpleSAMLphp can't use the |
||||
public key. |
||||
|
||||
simpleSAMLphp as Service Provider |
||||
--------------------------------- |
||||
|
||||
We suppose you configured LemonLDAP::NG as |
||||
:doc:`SAML Identity Provider<../idpsaml>` and want to use simpleSAMLphp |
||||
as Service Provider. |
||||
|
||||
In LL::NG Manager, create an new SP and load simpleSAMLphp metadata |
||||
trough URL (by default: |
||||
http://localhost/simplesamlphp/module.php/saml/sp/metadata.php/default-sp): |
||||
|
||||
|image1| |
||||
|
||||
Then set some attributes that will be sent to simpleSAMLphp: |
||||
|
||||
|image2| |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
Set ``Mandatory`` to ``On`` to force attributes in |
||||
authentication response. |
||||
|
||||
You can also force all signatures: |
||||
|
||||
|image3| |
||||
|
||||
On simpleSAMLphp side, use the metadata converter (by default: |
||||
http://localhost/simplesamlphp/admin/metadata-converter.php) to convert |
||||
LL::NG metadata (by default: http://auth.example.com/saml/metadata) into |
||||
internal PHP representation. Copy the ``saml20-idp-remote`` content: |
||||
|
||||
:: |
||||
|
||||
vi /etc/simplesamlphp/metadata/saml20-idp-remote.php |
||||
|
||||
.. code:: php |
||||
|
||||
<?php |
||||
$metadata['http://auth.example.com/saml/metadata'] = array ( |
||||
'entityid' => 'http://auth.example.com/saml/metadata', |
||||
... |
||||
// Add this option to force SLO requests signature |
||||
'sign.logout' => true, |
||||
); |
||||
?> |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
Don't forget PHP start and end tag to have a valid PHP |
||||
file. |
||||
|
||||
All is ready, you can now test the authentication (by default: |
||||
http://localhost/simplesamlphp/module.php/core/authenticate.php). You |
||||
should see something like that: |
||||
|
||||
|image4| |
||||
|
||||
simpleSAMLphp as Identity Provider |
||||
---------------------------------- |
||||
|
||||
We suppose you configured LemonLDAP::NG as |
||||
:doc:`SAML Service Provider<../authsaml>` and want to use simpleSAMLphp |
||||
as Identity Provider. |
||||
|
||||
First, you need to activate IDP feature in simpleSAMLphp: |
||||
|
||||
:: |
||||
|
||||
vi /etc/simplesamlphp/config.php |
||||
|
||||
.. code:: php |
||||
|
||||
'enable.saml20-idp' => true, |
||||
|
||||
And create a default IDP configuration: |
||||
|
||||
:: |
||||
|
||||
vi /etc/simplesamlphp/metadata/saml20-idp-hosted.php |
||||
|
||||
.. code:: php |
||||
|
||||
<?php |
||||
$metadata['__DYNAMIC:1__'] = array( |
||||
/* |
||||
* The hostname for this IdP. This makes it possible to run multiple |
||||
* IdPs from the same configuration. '__DEFAULT__' means that this one |
||||
* should be used by default. |
||||
*/ |
||||
'host' => '__DEFAULT__', |
||||
|
||||
/* |
||||
* The private key and certificate to use when signing responses. |
||||
* These are stored in the cert-directory. |
||||
*/ |
||||
'privatekey' => 'saml.pem', |
||||
'certificate' => 'saml.crt', |
||||
|
||||
/* |
||||
* The authentication source which should be used to authenticate the |
||||
* user. This must match one of the entries in config/authsources.php. |
||||
*/ |
||||
'auth' => 'admin', |
||||
// Sign SLO messages |
||||
'sign.logout' => true, |
||||
); |
||||
?> |
||||
|
||||
|
||||
.. important:: |
||||
|
||||
You need to configure your own certificates and |
||||
authentication scheme |
||||
|
||||
Now in LL::NG Manager, create a new IDP and import metadata with URL (by |
||||
default: http://localhost/simplesamlphp/saml2/idp/metadata.php): |
||||
|
||||
|image5| |
||||
|
||||
List attributes you want to collect: |
||||
|
||||
|image6| |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
You can keep ``Mandatory`` to ``Off`` to not fail if attribute |
||||
is not sent by IDP |
||||
|
||||
And activate all signatures: |
||||
|
||||
|image7| |
||||
|
||||
To finish, you need to declare LL::NG SP in simpleSAMLphp. Use the |
||||
metadata converter (by default: |
||||
http://localhost/simplesamlphp/admin/metadata-converter.php) to convert |
||||
LL::NG metadata (by default: http://auth.example.com/saml/metadata) into |
||||
internal PHP representation. Copy the ``saml20-sp-remote`` content: |
||||
|
||||
:: |
||||
|
||||
vi /etc/simplesamlphp/metadata/saml20-sp-remote.php |
||||
|
||||
.. code:: php |
||||
|
||||
<?php |
||||
$metadata['http://auth.example.com/saml/metadata'] = array ( |
||||
'entityid' => 'http://auth.example.com/saml/metadata', |
||||
... |
||||
); |
||||
?> |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
Don't forget PHP start and end tag to have a valid PHP |
||||
file. |
||||
|
||||
All is ready, you can now test the authentication from LL::NG portal. |
||||
|
||||
.. |image0| image:: /applications/simplesamlphp_logo.png |
||||
:class: align-center |
||||
.. |image1| image:: /applications/simplesamlphp_sp_metadata.png |
||||
:class: align-center |
||||
.. |image2| image:: /applications/simplesamlphp_sp_attributes.png |
||||
:class: align-center |
||||
.. |image3| image:: /applications/simplesamlphp_sp_signature.png |
||||
:class: align-center |
||||
.. |image4| image:: /applications/simplesamlphp_sp_authentication.png |
||||
:class: align-center |
||||
.. |image5| image:: /applications/simplesamlphp_idp_metadata.png |
||||
:class: align-center |
||||
.. |image6| image:: /applications/simplesamlphp_idp_attributes.png |
||||
:class: align-center |
||||
.. |image7| image:: /applications/simplesamlphp_idp_signature.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 22 KiB |
@ -0,0 +1,48 @@ |
||||
Spring Security (ACEGI) |
||||
======================= |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Spring |
||||
Security <http://static.springsource.org/spring-security/site/>`__ is |
||||
the new ACEGI name. This is a well known security framework for J2EE |
||||
applications. |
||||
|
||||
Spring Security provides a default ``pre-authentication`` mechanism that |
||||
can be used to connect your J2EE application to LL::NG. |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
You can find all suitable information here: |
||||
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/preauth.html |
||||
|
||||
To summarize, to get the user connected trough the ``Auth-User`` HTTP |
||||
Header, use this Sping Security configuration: |
||||
|
||||
.. code:: xml |
||||
|
||||
<bean id="LemonLDAPNGFilter" class= |
||||
"org.springframework.security.web.authentication.preauth.header.RequestHeaderPreAuthenticatedProcessingFilter"> |
||||
<security:custom-filter position="PRE_AUTH_FILTER" /> |
||||
<property name="principalRequestHeader" value="Auth-User"/> |
||||
<property name="authenticationManager" ref="authenticationManager" /> |
||||
</bean> |
||||
|
||||
<bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider"> |
||||
<security:custom-authentication-provider /> |
||||
<property name="preAuthenticatedUserDetailsService"> |
||||
<bean id="userDetailsServiceWrapper" class="org.springframework.security.userdetails.UserDetailsByNameServiceWrapper"> |
||||
<property name="userDetailsService" ref="userDetailsService"/> |
||||
</bean> |
||||
</property> |
||||
</bean> |
||||
|
||||
<security:authentication-manager alias="authenticationManager" /> |
||||
|
||||
.. |image0| image:: /applications/spring_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1,190 @@ |
||||
PHP (Symfony) |
||||
============= |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Symfony <https://symfony.com/>`__ is the well-known PHP framework. It |
||||
is intended to ease the development of PHP applications. |
||||
|
||||
Symfony provides many methods conventions to authenticate users (basic, |
||||
ldap,...) and to load external user sources (ldap, database). The method |
||||
presented here relies on the "remote_user" method. (in security |
||||
firewall) |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
Follow these step to protect your application using the "REMOTE_USER" |
||||
HTTP header. |
||||
|
||||
1. Adapt the app/config/security.yml configuration file as below: |
||||
|
||||
.. code:: json |
||||
|
||||
security: |
||||
|
||||
encoders: |
||||
AppBundle\Security\User\HeaderUser: plaintext |
||||
|
||||
providers: |
||||
header: |
||||
id: AppBundle\Security\User\HeaderUserProvider |
||||
|
||||
firewalls: |
||||
dev: |
||||
pattern: ^/(_(profiler|wdt)|css|images|js)/ |
||||
security: false |
||||
|
||||
main: |
||||
pattern: ^/ |
||||
remote_user: |
||||
user: HTTP_REMOTE_USER |
||||
provider: header |
||||
|
||||
- encoders : define a password hashing scheme (useless in our case, but |
||||
the parameter is mandatory) |
||||
- providers : define the user providers (even virtual) |
||||
- remote_user : define the authentication method to "assume the user is |
||||
already authenticated and get an http variable to know his username" |
||||
- user : define the HTTP header containing the username |
||||
- provider : references the previously defined provider owning the user |
||||
data (in our scenario, a virtual) |
||||
|
||||
2. Define a "header user" class |
||||
|
||||
Create the file src/AppBundle/Security/User/HeaderUser.php : |
||||
|
||||
.. code:: php |
||||
|
||||
<?php |
||||
|
||||
// src/Security/User/HeaderUser.php |
||||
namespace AppBundle\Security\User; |
||||
|
||||
use Symfony\Component\Security\Core\User\UserInterface; |
||||
use Symfony\Component\Security\Core\User\EquatableInterface; |
||||
|
||||
class HeaderUser implements UserInterface, EquatableInterface |
||||
{ |
||||
private $username; |
||||
private $password; |
||||
private $salt; |
||||
private $roles; |
||||
|
||||
public function __construct($username, $password, $salt, array $roles) |
||||
{ |
||||
$this->username = $username; |
||||
$this->password = $password; |
||||
$this->salt = $salt; |
||||
$this->roles = $roles; |
||||
} |
||||
|
||||
public function getRoles() |
||||
{ |
||||
return $this->roles; |
||||
} |
||||
|
||||
public function getPassword() |
||||
{ |
||||
return $this->password; |
||||
} |
||||
|
||||
public function getSalt() |
||||
{ |
||||
return $this->salt; |
||||
} |
||||
public function getUsername() |
||||
{ |
||||
return $this->username; |
||||
} |
||||
|
||||
public function eraseCredentials() |
||||
{ |
||||
} |
||||
|
||||
public function isEqualTo(UserInterface $user) |
||||
{ |
||||
if (!$user instanceof HeaderUser) { |
||||
return false; |
||||
} |
||||
|
||||
if ($this->username !== $user->getUsername()) { |
||||
return false; |
||||
} |
||||
|
||||
//if ($this->password !== $user->getPassword()) { |
||||
// return false; |
||||
//} |
||||
|
||||
return true; |
||||
} |
||||
} |
||||
?> |
||||
|
||||
3. Define a "header user provider" class relying on the previous class |
||||
|
||||
Create the file src/AppBundle/Security/User/HeaderUserProvider.php : |
||||
|
||||
.. code:: php |
||||
|
||||
<?php |
||||
|
||||
// src/Security/User/HeaderUserProvider.php |
||||
namespace AppBundle\Security\User; |
||||
|
||||
use AppBundle\Security\User\HeaderUser; |
||||
use Symfony\Component\Security\Core\User\UserProviderInterface; |
||||
use Symfony\Component\Security\Core\User\UserInterface; |
||||
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; |
||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException; |
||||
|
||||
class HeaderUserProvider implements UserProviderInterface |
||||
{ |
||||
public function loadUserByUsername($username) |
||||
{ |
||||
|
||||
if ($username) { |
||||
|
||||
$password = "dummy"; |
||||
$salt = ""; |
||||
$roles = array('ROLE_USER'); |
||||
|
||||
return new HeaderUser($username, $password, $salt, $roles); |
||||
} |
||||
|
||||
throw new UsernameNotFoundException( |
||||
sprintf('Username "%s" does not exist.', $username) |
||||
); |
||||
} |
||||
|
||||
public function refreshUser(UserInterface $user) |
||||
{ |
||||
if (!$user instanceof HeaderUser) { |
||||
throw new UnsupportedUserException( |
||||
sprintf('Instances of "%s" are not supported.', get_class($user)) |
||||
); |
||||
} |
||||
|
||||
return $this->loadUserByUsername($user->getUsername()); |
||||
} |
||||
|
||||
public function supportsClass($class) |
||||
{ |
||||
return HeaderUser::class === $class; |
||||
} |
||||
} |
||||
|
||||
?> |
||||
|
||||
References |
||||
---------- |
||||
|
||||
- http://symfony.com/doc/current/security/pre_authenticated.html#remote-user-based-authentication |
||||
- https://symfony.com/doc/current/security/custom_provider.html |
||||
|
||||
.. |image0| image:: /applications/symfony_logo.png |
||||
:class: align-center |
||||
|
After Width: | Height: | Size: 3.6 KiB |
@ -0,0 +1,139 @@ |
||||
Sympa |
||||
===== |
||||
|
||||
|image0| |
||||
|
||||
Presentation |
||||
------------ |
||||
|
||||
`Sympa <http://www.sympa.org>`__ is a mailing list manager. |
||||
|
||||
To configure SSO with Sympa, use **Magic authentication**: a special SSO |
||||
URL is protected by LL::NG, Sympa will display a button for users who |
||||
wants to use this feature. |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
Since version 1.9 of LLNG, old Auto-Login feature has been |
||||
removed since it works only with Sympa-5 which has been deprecated |
||||
|
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
Sympa configuration |
||||
~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Edit the file "auth.conf", for example: |
||||
|
||||
:: |
||||
|
||||
vi /etc/sympa/auth.conf |
||||
|
||||
And fill it: |
||||
|
||||
:: |
||||
|
||||
generic_sso |
||||
service_name Centralized auth service |
||||
service_id lemonldapng |
||||
email_http_header HTTP_MAIL |
||||
netid_http_header HTTP_AUTH_USER |
||||
internal_email_by_netid 1 |
||||
logout_url http://sympa.example.com/wws/logout |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
You can also disable internal Sympa authentication to keep |
||||
only LemonLDAP::NG by removing user_table paragraph |
||||
|
||||
Note that if you use FastCGI, you must restart Apache to enable changes. |
||||
|
||||
|
||||
You can also use <portal>?logout=1 as logout_url to remove LemonLDAP::NG |
||||
session when "disconnect" is chosen. |
||||
|
||||
Sympa virtual host |
||||
~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Configure Sympa virtual host like other |
||||
:doc:`protected virtual host<../configvhost>` but protect only magic |
||||
authentication URL. |
||||
|
||||
|
||||
.. tip:: |
||||
|
||||
The location URL end is based on the ``service_id`` defined in |
||||
Sympa apache configuration. |
||||
|
||||
- For Apache: |
||||
|
||||
.. code:: apache |
||||
|
||||
<VirtualHost *:80> |
||||
ServerName sympa.example.com |
||||
|
||||
<Location /wws/sso_login/lemonldapng> |
||||
PerlHeaderParserHandler Lemonldap::NG::Handler |
||||
</Location> |
||||
|
||||
... |
||||
|
||||
</VirtualHost> |
||||
|
||||
- For Nginx: |
||||
|
||||
.. code:: nginx |
||||
|
||||
server { |
||||
listen 80; |
||||
server_name sympa.example.com; |
||||
root /path/to/application; |
||||
# Internal authentication request |
||||
location = /lmauth { |
||||
internal; |
||||
include /etc/nginx/fastcgi_params; |
||||
fastcgi_pass unix:/var/run/llng-fastcgi-server/llng-fastcgi.sock; |
||||
# Drop post datas |
||||
fastcgi_pass_request_body off; |
||||
fastcgi_param CONTENT_LENGTH ""; |
||||
# Keep original hostname |
||||
fastcgi_param HOST $http_host; |
||||
# Keep original request (LLNG server will received /llauth) |
||||
fastcgi_param X_ORIGINAL_URI $request_uri; |
||||
} |
||||
|
||||
# Client requests |
||||
location /wws/sso_login/lemonldapng { |
||||
auth_request /lmauth; |
||||
auth_request_set $lmremote_user $upstream_http_lm_remote_user; |
||||
auth_request_set $lmlocation $upstream_http_location; |
||||
error_page 401 $lmlocation; |
||||
try_files $uri $uri/ =404; |
||||
|
||||
... |
||||
|
||||
include /etc/lemonldap-ng/nginx-lua-headers.conf; |
||||
} |
||||
location / { |
||||
try_files $uri $uri/ =404; |
||||
} |
||||
} |
||||
|
||||
Sympa virtual host in Manager |
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
Go to the Manager and :doc:`create a new virtual host<../configvhost>` |
||||
for Sympa. |
||||
|
||||
Configure the :doc:`access rules<../writingrulesand_headers>` and define |
||||
the following :doc:`headers<../writingrulesand_headers>`: |
||||
|
||||
- Auth-User |
||||
- Mail |
||||
|
||||
.. |image0| image:: /applications/sympa_logo.png |
||||
:class: align-center |
||||
|