SAML 2.0
Overview
SAML (Security Assertion Markup Language) lets an institution authenticate its readers against its own identity provider and send them into your store already logged in. The institution acts as the identity provider (IdP); your Publica.la store acts as the service provider (SP). Readers never share their institutional credentials with you.
Each reader gets their own account.
Admin Role Limitation – click to expand
Authentication methods based on IP, URL referrer, LTI, or SAML are designed for end-user access only.
When the identifier corresponds to an administrator account, the platform intentionally starts the session with regular user permissions to prevent privilege escalation.
Administrators who need to access the Control Panel must:
- Set a password to their account.
- Log out of the current integration-based session.
- Log back in using email + password to regain full administrator privileges.
Identity providers known to work with this integration include Google Workspace, OpenAthens, Azure AD, and Shibboleth.
For the step-by-step walkthrough of the dashboard screens, with screenshots, see the Help Center article.
Pre-requisites
- An Enterprise plan subscription.
- The institution's identity provider metadata XML file.
How it works
Both directions of SAML single sign-on are supported.
- IdP-initiated: the reader clicks your store in their institutional portal. The identity provider posts a signed assertion to your store, which validates it and starts the session.
- SP-initiated: the reader opens the login URL of the integration. Your store redirects them to the identity provider, they authenticate there, and the provider posts the assertion back.
Each integration you create gets its own set of endpoints, named after the consumer key you choose:
| Endpoint | Role |
|---|---|
https://{store_final_domain}/saml2/{consumer_key}/login | SP-initiated login. Give this URL to the institution. |
https://{store_final_domain}/saml2/{consumer_key}/metadata | Your store's SAML metadata, as XML. |
https://{store_final_domain}/saml2/{consumer_key}/acs | Assertion consumer service. Where the IdP posts. |
https://{store_final_domain}/saml2/{consumer_key}/sls | Single logout service. |
Configuration
Ask the institution for the following values and load them in Settings > Integrations > SAML settings:
| Field | Description |
|---|---|
| Consumer key | A name you choose to identify the institution, for example universidad-san-blas. |
| Entity id | The identity provider's entity id. |
| Single sign-on service | URL the reader is redirected to in order to authenticate. |
| Single logout service | URL used to end the session on the identity provider. |
| x509 certificate | Certificate used to validate the signature of the assertion. |
Every value except the consumer key comes from the identity provider's metadata XML file.
You also choose whether readers get direct access to all content or a plan assigned on login, the same distinction described in Authentication by IP Ranges.
Once saved, the integration shows a login URL and a metadata URL. The institution registers your store as an application in their identity provider using the values published at that metadata URL:
| Value the IdP asks for | Where it comes from |
|---|---|
| Login URL | Shown in the integration details. |
| Entity id, or audience | md:EntityDescriptor.entityID in your metadata. |
| Assertion consumer service (ACS) URL | md:AssertionConsumerService.Location. |
| Single logout service URL | md:SingleLogoutService.Location. |
| x509 certificate | ds:X509Certificate. |
Identifying the reader
The assertion can identify a reader by email address, by an institutional identifier, or by both. Either one on its own is enough, so institutions that do not release email addresses can still be integrated.
Email address
Taken from the first of these that holds a valid email address: the NameID, the Azure emailaddress claim, the emailAddress attribute (the one we recommend, and the one OpenAthens sends), or the mail friendly name (urn:oid:0.9.2342.19200300.100.1.3).
External id
Taken from the first of these that holds a usable value:
- The standard attributes
urn:oid:1.3.6.1.4.1.5923.1.1.1.6,eduPersonPrincipalName,eduPersonTargetedID, and the Azurenameidentifierclaim. - The NameID, when it is not an email address.
These names are fixed. If your institution publishes its identifier under a name of its own, contact support.
The value can be up to 200 characters. A NameID in transient format is never used as an identifier, because the identity provider regenerates it on every session and each login would create a new account.
Any other attribute in the assertion is ignored, with one exception: reader_exit_url, which sets where the reader's exit button in the reader takes them.
How the account is resolved
- The reader is looked up by external id first, then by email address. If neither matches an existing account, one is created from the values the assertion carries, and an account created from an external id alone has no email address.
- If the account is found by email and has no external id yet, the external id is attached to it. This links readers that were created from the dashboard beforehand.
- The reader is sent to the login form only when the assertion carries no usable identifier at all.
The external id identifies one account across integrations, so a reader arriving through SAML and through an IP range entry point with the same identifier lands on the same account.
Troubleshooting
| Symptom | Likely cause | Recommended fix |
|---|---|---|
| Reader lands on the login form | The assertion carries neither an email address nor an external id | Ask the institution to release the identifier under one of the attributes listed above. |
| A new account is created on every login | The identity provider sends a transient NameID and no attributes | Ask the institution to release a stable attribute. |
| Readers share a single account | The identity provider sends the same identifier for every reader | Confirm the attribute is per reader, not per institution. |
| A reader sees an empty library after logging in | The identifier the identity provider sends already belongs to another account in your store | Contact support with the reader's email address and the identifier the assertion carries. |
| The store rejects the assertion | Certificate mismatch or an expired certificate | Request the current x509 certificate from the institution and update the entry point. |
To follow the SAML messages exchanged in the browser, the SAML-tracer extension shows each request and response as it happens.