1 Session Identification
When using the REST API, a session is identified by the session secret cookie and the session id, which must be sent as query parameter sid. This ensures that
- A session can never be fully identified by URLs (because the session secret is not part of the URL)
- One client may have multiple sessions. They share the same session secret, but use different session ids
2 Authentication with credentials
To login with credentials, the client must
POST /CNPortletapp/rest/auth/login { "login": ..., "password": ... }
The response will be of the form
{ "sid" : "1022", "user" : { "id" : 34, "description" : "", "login" : "editor", "email" : "", "firstName" : "Max", "lastName" : "No-Publish" }, "responseInfo" : { "responseCode" : "OK", "responseMessage" : "Successfully performed login" } }
Note that the “User-Agent” has to be set in the header of the request as it will be saved in the session, otherwise the login will fail.
Additionally, the session secret cookie will be set to the client.
3 SSO with CAS
3.1 Configuration
The CAS client configuration for the REST API is done by adding necessary filters in the file /Node/tomcat/conf/web.xml
<!-- =============== CAS SSO Filter Start =============== --> <!-- Filter parameter shared by some filters --> <context-param> <param-name>casServerLoginUrl</param-name> <param-value>{CAS Server Login URL}</param-value> </context-param> <context-param> <param-name>casServerUrlPrefix</param-name> <param-value>{CAS Server URL Prefix}</param-value> </context-param> <context-param> <param-name>serverName</param-name> <param-value>{Server Name}</param-value> </context-param> <!-- The authentication filter will check, whether CAS Authentication is necessary and will redirect to the CAS Server --> <filter> <filter-name>CAS Authentication Filter</filter-name> <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> <init-param> <param-name>gateway</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CAS Authentication Filter</filter-name> <url-pattern>/rest/auth/ssologin</url-pattern> </filter-mapping> <!-- The Ticket Validation Filter will validate the Ticket (found in the query as additional parameter) against the CAS Server and will do a redirect to the service without the ticket --> <filter> <filter-name>CAS Ticket Validation Filter</filter-name> <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS Ticket Validation Filter</filter-name> <url-pattern>/rest/auth/ssologin</url-pattern> </filter-mapping> <!-- The Assertion Thread Local Filter makes the assertion available as ThreadLocal (the CASIntegrationFilter depends on it) --> <filter> <filter-name>CAS Assertion Thread Local Filter</filter-name> <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS Assertion Thread Local Filter</filter-name> <url-pattern>/rest/auth/ssologin</url-pattern> </filter-mapping> <!-- The CASIntegrationFilter reads the assertion, matches it against the User-DB (or creates a new user). And performs the login. --> <filter> <filter-name>CAS GCN Integration Filter</filter-name> <filter-class>com.gentics.contentnode.auth.filter.CASIntegrationFilter</filter-class> <init-param> <param-name>initGroups</param-name> <param-value>[4, 6]</param-value> <!-- expression that returns the ids of the initial groups --> </init-param> </filter> <filter-mapping> <filter-name>CAS GCN Integration Filter</filter-name> <url-pattern>/rest/auth/ssologin</url-pattern> </filter-mapping> <!-- =============== CAS SSO Filter End =============== -->
{CAS Server Login URL} must be set to the login URL of the CAS server, {CAS Server URL Prefix} to the URL prefix and {Server Name} to the server name (base URL).
The init parameter initGroups is an expression that must return the ids of the initial groups, new users shall be put in. The expression can resolve systemuser attributes via user.* or attributes returned from the CAS service via attr.*.
For security reasons, it is not possible to add users to groups 1 or 2.
3.2 Client side implementation
The client implementation of SSO login using CAS is problematic, when done with AJAX. The authentication is done by redirecting the client to the CAS Server (which probably is hosted on another domain) which will create a service ticket and redirect back to the authenticated service. Redirects to other domains violate the same domain policy, which normally applies to AJAX requests (with default security settings), therefore the authentication will not be possible using AJAX requests.
However, this problem can be solved, using an iframe, as in the following demo implementation:
// SSO login works with an iframe var $iframe = $("<iframe></iframe>"); $iframe.hide(); $("body").append($iframe); // add an onload handler $iframe.load(function() { // get the reponse var response = $iframe.contents().text(); switch(response) { case 'NOTFOUND': case 'FAILURE': // TODO do some error handling break; default: // TODO the response contains the sid now. Store and use in subsequent calls } // finally remove iframe $iframe.remove(); }); // set the source $iframe.attr("src", '/CNPortletapp/rest/auth/ssologin?ts=' + (new Date()).getTime());
4 SSO with SiteMinder
4.1 Configuration
The SiteMinder client configuration for the REST API is done by adding necessary filters in the file /Node/tomcat/conf/web.xml
<!-- =============== SiteMinder SSO Filter Start =============== --> <filter> <filter-name>Http Auth Filter</filter-name> <filter-class>com.gentics.contentnode.auth.filter.HttpAuthFilter</filter-class> </filter> <filter-mapping> <filter-name>Http Auth Filter</filter-name> <url-pattern>/rest/auth/ssologin</url-pattern> </filter-mapping> <!-- =============== SiteMinder SSO Filter End =============== --> </pre> Additionally, the feature +http_auth_login+ must be set to _true_ and the names of the headers must be configured in the file <code>/Node/etc/node.conf</code> <pre> // ** Start ** Http Authentication (SiteMinder) $FEATURE["http_auth_login"] = true; $HTTP_AUTH_LOGIN["login"] = "HTTP_UID"; $HTTP_AUTH_LOGIN["firstname"] = "HTTP_GIVENNAME"; $HTTP_AUTH_LOGIN["lastname"] = "HTTP_SN"; $HTTP_AUTH_LOGIN["email"] = "HTTP_MAIL"; $HTTP_AUTH_LOGIN["group"] = "HTTP_CN_GRUPPE"; $HTTP_AUTH_LOGIN["splitter"] = ";"; // ** End ** Http Authentication (SiteMinder)
For security reasons, it is not possible to add users to groups 1 or 2.
4.2 Syncronizing the group-ids between CAS-Server and the Content.Node
In the configuration in web.xml, you can add in the Integration Filter followed parameters:
<filter> <filter-name>CAS GCN Integration Filter</filter-name> <filter-class>com.gentics.contentnode.auth.filter.CASIntegrationFilter</filter-class> <init-param> <param-name>initGroups</param-name> <param-value>eval(attr.cmsgroup)</param-value> </init-param> <init-param> <param-name>syncGroups</param-name> <param-value>true</param-value> </init-param> </filter>
In the parameter initGroups you have the attribution, which saved the group-ids. syncGroups is default false, set it to true that the group-syncing works.
4.3 Client side implementation
Since the SiteMinder Authentication works without a redirect, the login can be done by just doing an AJAX call to
GET /CNPortletapp/rest/auth/ssologin
The response will simply contain the sid as plain text.
5 Logout
A logout can be performed with the following request
POST /CNPortletapp/rest/auth/logout/{sid}
in the response, the session secret cookie is removed.