This document describes the SAML support in the SimplyE iOS mobile client.  It is using the SAML Test Bed.


The following shows the UX flow a user will have for SAML based SSO access on iOS.  The process for this flow is directed by the Authentication Document.  The Authentication Document defines the method of authentication that the Library Simplified clients must support for a particular library.  In this case is the SAML SSO.

The SAML Protocol and login steps are defined by the Identity provider’s configuration.  Therefore the SimplyE client must support the different configurations that may be present.

Auth_document used for this example

Authentication Document
  "authentication": [
    {
      "type": "http://librarysimplified.org/authtype/SAML-2.0",
      "description": "SAML 2.0 Web SSO",
      "links": [
        {
          "privacy_statement_urls": [],
          "logo_urls": [],
          "display_names": [
            {
              "language": "en",
              "value": "Shibboleth Test IdP"
            }
          ],
          "href": "http://cm.hilbertteam.net/SAML/saml_authenticate?idp_entity_id=http%3A%2F%2Fidp.hilbertteam.net%2Fidp%2Fshibboleth&provider=SAML+2.0+Web+SSO",
          "descriptions": [
            {
              "language": "en",
              "value": "Shibboleth Test IdP"
            }
          ],
          "rel": "authenticate",
          "information_urls": []
        },
        {
               "Shibboleth Test IdP 2" DETAILS WERE HERE
    }
  ]

Use Case: Logging In


Step 1:

Go to settings and select a library account


 

Step 2: 

Select IDP that you’d like to use for authentication, in this case it will be Shibboleth Test IdP. An in-app webview shall be presented.


The URL loaded into webview would be the one located in href variable in auth_document + added redirect_url parameter. The url used in this parameter would be the last redirection made during log in process. An app should observe for this redirection. The final URL loaded into webview would look like:
http://cm.hilbertteam.net/SAML/saml_authenticate?idp_entity_id=http://idp.hilbertteam.net/idp/shibboleth&provider=SAML+2.0+Web+SSO&redirect_uri=https://skyneck.pl/login
Where the first part comes from auth_document and the second part is a redirect url appended by the app. 


Step 3: 

Enter credentials and tap log in. Depending on the used IDP, there may, or may not be more steps. For the one in this example, there is a give consent step which follows the credentials page.

Once you finish all the steps required by IDP, you will be redirected to the redirect_uri link that you provided earlier. In this example it is:
https://skyneck.pl/login?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6…..&patron_info=%7B%7D

Where:

  • green part is redirect_uri that you provided when opening a webview
  • red part is oauth 2 token that you need to use during communication with circulation manager
  • blue part is patron info which you need to store as you would do it for any other authentication method, in my case it’s an empty url encoded: { }

Step 4: 

Close the webview

After you receive the last redirection (step 4), you need to store all necessary variables:

  • auth_token from the url
    • patron_info from the url
  • Cookies - you need to dump all the cookies from the webview, which were set during the authentication process. Once you dump them, you need to store them as you store oauth token and patron info.

Step 5: 

You are fully logged in

During this process you obtained variables necessary for future communication.




Functional Requirements Tests

Use Case: Borrowing Content, logged in.


Step 1:
Select a book which you’d like to download and press the Download button

Step 2:

Given that the authentication type is SAML, the download process will begin inside the invisible web view. Bearer token needs to be set inside the request header. Cookies from storage need to be set inside the webview. 

During this page loading process, webview will observe for several things:

  • on redirect response callback, it will check response content-type, whether it is one of the supported book types (eg. “application/pdf”). If it is a supported book type (and in this case it is), app shall:
    • Dump and store cookies from webview
    • Return the last request details. Those details are: latest cookies, the url that contained the supported book content type, and a Refferer header. On iOS the simplest solution was to return the configured NSURLRequest (standard object containing all informations required to perform a network request) from webview
  • page loading finished callback, but it doesn’t matter in this scenario

Step 3:

In the previous step, the webview returned NSURLRequest and updated stored cookies. Invisible webview can be removed from memory at this point, and old downloading process may begin. Instead of using the same url you used in step 2, you need to redo the request that you just obtained. Don’t forget to set all the cookies inside your HTTP session (class that performs the network request).


Use Case: Borrowing Content - Logged In with subsequent verification


Step 1:
Select a book which you’d like to download and press the Download button

Step 2:

Given that the authentication type is SAML, the download process will begin inside the invisible web view. Bearer token needs to be set inside the request header. Cookies from storage need to be set inside the webview. 

During this page loading process, webview will observe for several things:

  • on redirect response callback, it will check response content-type, whether it is one of the supported book types (eg. “application/pdf”). If it is a supported book type (it will be, but not during the first batch of redirects), app shall:
    • Dump and store cookies from webview
    • Return the last request details. Those details are: latest cookies, the url that contained the supported book content type, and a Refferer header. On iOS the simplest solution was to return the configured NSURLRequest (standard object containing all informations required to perform a network request) from webview
  • on page loading finished callback, it will wait for 0.5 second, after which it will verify that webview doesn’t load anything else.
    • It may occur that the redirects are finished indeed, but the loaded page will begin another batch of redirections, and in such case, we don’t want to make a decision whether or not to present the webview to user.
    • In case there is no activity inside the webview, it means that the redirect response callback didn’t catch usable book data and IDP requires some input from the user. Webview should be presented to the user now.

Step 3:

User gave input to the webview and after a series of redirections, redirect response callback finally detected a book. 

Step 4:

In the previous step, the webview returned NSURLRequest and updated stored cookies. Invisible webview can be removed from memory at this point, and old downloading process may begin. Instead of using the same url you used in step 2, you need to redo the request that you just obtained. Don’t forget to set all the cookies inside your HTTP session (class that performs the network request).



Use Case: Borrowing Content, not logged in


Step 1:

It may occur that you will receive “application/api-problem+json” or “application/problem+json” content-type response. In case the oauth token is invalid, the problem type will be "http://librarysimplified.org/terms/problem/credentials-invalid”. This occurred to me when borrowing a book, downloading a book, or trying to return one, and the expired meantime. In such case, present the in-app sign in scene to let the user log in (refresh stored session data). Once a user finishes the login process, redo the action that failed. This scene was already available in the app, but it’s functionality was extended in the same way as in the library account details.




Interaction diagrams and more info about how the flow works is available here:

https://wiki.lyrasis.org/display/SIM/SAML+Authentication

Here’s the documentation about the work that was done on the server:

https://docs.google.com/document/d/1MZwEgJlEXZjEdG-04AGNLD-z07v8uEK5prMwqk0odww/edit

  • No labels