In our project, we have successfully implemented SAML (Security Assertion Markup Language) 2.0 with our Alfresco Content Service v5.2.0. We use AD(Active Directory) to sync users and groups into Alfresco System.

Installation

Installation was straight forward. Just following the guides from Alfresco https://docs.alfresco.com/saml/concepts/saml-overview.html.

Before Implementing, make sure you have gone through the supported-platforms by Alfresco Content Service and download the correct versions of amps. https://docs.alfresco.com/5.2/concepts/supported-platforms-ACS.html.

We have installed the following amps:

  • alfresco-saml-repo-1.0.3.amp
  • alfresco-saml-share-1.0.3.amp

Configuration

There are several ways to configure SAML:

  • Admin Console (Enterprise Admin Tool)
  • JMX settings
  • alfresco-global.properties
  • New subsystem

We chose to do the configuration by adding a subsystem (SAML) under ../tomcat/shared/classes/alfresco/extension/subsystems/SAML.

There are some reasons, we decided to use properties-files over JMX console.

  • First of all, its easier to transfer configurations between environments(development-test-production) by using properties-files.
  • The reason to choose Subsystem instead of alfresco-global.properties is that we have different settings between Share, REST-API and AOS. In REST-API we want saml.sp.isEnforced=false, but in the others saml.sp.isEnforced=true.

Configuration files and settings

Generate the certificate or ask your organization to provide the signed jks certificate to validate. Add the below attributes in alfresco-global.properties file:

saml.keystore.location=f:/alfresco/${alfresco.version}/alf_data/keystore/saml/test-saml.keystore.jks
saml.keystore.keyMetaData.location=f:/alfresco/alf_data/keystore/saml/test-saml.keystore-passwords.properties

Update the test-saml.keystore-passwords.properties file to look like

aliases=te-c1c66075-f6e3-6fe3-b3e1-rtr
keystore.password=password123
te-c1c66075-f6e3-6fe3-b3e1-rtr.password=password123

Note: Use keytool to convert pfx certificate to jks certificate if your organization does not provide jks, in our case we did this.

Create a subsystem/SAML directory if it does not exists in extension directory.

subsystem/SAML directory will have the configurations for repository and share application. Inline-style:

alt text

The share folder will store the configuration file for share, saml-custom-share-sp.properties. The repository folder will have two sub-folders, aos and rest-api. The aos folder will store the configuration file for aos, saml-custom-aos-sp.properties. And the rest-api folder will store the configuration file for rest-api, saml-custom-rest-api-sp.properties.

Update and provide the SAML configuration for share, repository and aos properties as below.

saml-custom-share-sp.properties:

# The SAML attribute (or 'Subject/NameID' for SAML subject NameID) to map to the Alfresco user's ID
saml.sp.user.mapping.id=Subject/NameID

# Whether or not SAML is enabled for the service provider
saml.sp.isEnabled=true

# Whether or not SAML login is enforced
saml.sp.isEnforced=true

# IdP description if you choose to enforce SAML login
saml.sp.idp.description=WAM-TEST

# IdP URL to which the Authentication Request from Alfresco is posted for the service provider
saml.sp.idp.sso.request.url=https://mycompany.com/FIM/sps/alfresco/saml20/login

# IdP URL to which a logout *request* from Alfresco is posted when logging out from the service provider
saml.sp.idp.slo.request.url=https://mycompany.com/FIM/sps/alfresco/saml20/slo

# IdP URL to which a logout *response* from Alfresco is posted when receiving a logout request from your IdP for the service provider
#saml.sp.idp.slo.response.url=

# Path to the certificate used to validate the requests and responses from the IdP
saml.sp.idp.certificatePath=f:/alfresco/5.2.0/alf_data/keystore/saml/alfresco-cert.cer


# Entity identification (issuer) for the service provider.  Some IdPs may use this to determine which SP connection to use.
saml.sp.idp.spIssuer=https://alfresco.mycompany.com

saml-custom-rest-api-sp.properties:

# The SAML attribute (or 'Subject/NameID' for SAML subject NameID) to map to the Alfresco user's ID
saml.sp.user.mapping.id=Subject/NameID

# Whether or not SAML is enabled for the service provider
saml.sp.isEnabled=true

# Whether or not SAML login is enforced
saml.sp.isEnforced=false

# IdP description if you choose to enforce SAML login
saml.sp.idp.description=WAM-TEST

# IdP URL to which the Authentication Request from Alfresco is posted for the service provider
saml.sp.idp.sso.request.url=https://mycompany.com/FIM/sps/alfresco/saml20/login

# IdP URL to which a logout *request* from Alfresco is posted when logging out from the service provider
saml.sp.idp.slo.request.url=https://mycompany.com/FIM/sps/alfresco/saml20/slo

# IdP URL to which a logout *response* from Alfresco is posted when receiving a logout request from your IdP for the service provider
#saml.sp.idp.slo.response.url=

# Path to the certificate used to validate the requests and responses from the IdP
saml.sp.idp.certificatePath=f:/alfresco/5.2.0/alf_data/keystore/saml/alfresco-cert.cer


# Entity identification (issuer) for the service provider.  Some IdPs may use this to determine which SP connection to use.
saml.sp.idp.spIssuer=https://alfresco.mycompany.com/rest-api

saml-custom-aos-sp.properties:

# The SAML attribute (or 'Subject/NameID' for SAML subject NameID) to map to the Alfresco user's ID
saml.sp.user.mapping.id=Subject/NameID

# Whether or not SAML is enabled for the service provider
saml.sp.isEnabled=true

# Whether or not SAML login is enforced
saml.sp.isEnforced=true

# IdP description if you choose to enforce SAML login
saml.sp.idp.description=WAM-TEST

# IdP URL to which the Authentication Request from Alfresco is posted for the service provider
saml.sp.idp.sso.request.url=https://mycompany.com/FIM/sps/alfresco/saml20/login

# IdP URL to which a logout *request* from Alfresco is posted when logging out from the service provider
saml.sp.idp.slo.request.url=https://mycompany.com/FIM/sps/alfresco/saml20/slo

# IdP URL to which a logout *response* from Alfresco is posted when receiving a logout request from your IdP for the service provider
#saml.sp.idp.slo.response.url=

# Path to the certificate used to validate the requests and responses from the IdP
saml.sp.idp.certificatePath=f:/alfresco/5.2.0/alf_data/keystore/saml/alfresco-cert.cer

# Entity identification (issuer) for the service provider.  Some IdPs may use this to determine which SP connection to use.
saml.sp.idp.spIssuer=https://alfresco.mycompany.com/aos

Update the custom-share-config file to implement SAML on share:

<config evaluator="string-compare" condition="CSRFPolicy" replace="true">
  <filter>
    <!-- SAML SPECIFIC CONFIG -  START -->
    <!-- Since we have added the CSRF filter with filter-mapping of "/*" we will catch all public GET's 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 -->
  </filter>
</config>

SAML dance

To connect to backend API’s using SAML-based authentication, you do “the SAML-dance”.

To authenticate: http://alfresco.mycompany.com/alfresco/service/saml/-default-/rest-api/authenticate

Response:

*entry:
id:      "TICKET_4d5f271531755e13302d00774290ab2c0ecfd0c9"
userId:  "test_user"*

Call the repo-api using the ticket from response above: http://alfresco.mycompany.com/alfresco/s/api/sites?alf_ticket=TICKET_4d5f271531755e13302d00774290ab2c0ecfd0c9

Logout: http://alfresco.mycompany.com/alfresco/service/saml/-default-/rest-api/logout-request?alf_ticket=TICKET_4d5f271531755e13302d00774290ab2c0ecfd0c9

See https://docs.alfresco.com/saml/concepts/develop-saml.html for more details.

Problems & solutions

We have encountered some problems after the deploy of SAML-based authentication.

One problem is with View In Browser when using Internet Explorer. If you are in Document Library and try to do a View In Browser on a Microsoft Office file, the Office program will show you a login dialog. If you click cancel twice the document will open just fine. This is a known issue.

Share/proxy URLs

When integrating with Alfresco, you will notice that if you try to connect to a repo-api through share/proxy you will not get authenticated by SAML. We have lot of users that are creating links to documents from our Intranet, they are taking the download URL from Alfresco share. (URL includes share/proxy). These links will not work any more if the users isn’t already having a session in the browser. We have created a custom share-api that authenticate the user with SAML and redirect to the original URL.

Fredrik Kasström

Alfresco Consultant at Redpill Linpro

Fredrik started at Redpill Linpro in 2015. He is specialised in the ECM area.

Just-Make-toolbox

make is a utility for automating builds. You specify the source and the build file and make will determine which file(s) have to be re-built. Using this functionality in make as an all-round tool for command running as well, is considered common practice. Yes, you could write Shell scripts for this instead and they would be probably equally good. But using make has its own charm (and gets you karma points).

Even this ... [continue reading]

Containerized Development Environment

Published on February 28, 2024

Ansible-runner

Published on February 27, 2024