Symplified Mobile Identity Management SDK

The Symplified Identity Provider (IdP) Sandbox

Use our SAML 2.0 environment with a hosted IdP and test account to quickly build a functional app. Swap in your production IdP when you're ready to deploy. The default test credentials are:

username: sdkuser password: Symple123

Need help understanding single sign-on terminology, like IdP and SP? The folks at have provided a good overview: About Identity Providers and Service Providers.

0. Acquire SAML 2.0 metadata

SAML metadata provides information about the identity provider (IdP) used for the authentication and single sign-on service. It is an XML document containing data such as server URIs, protocols, certificates, and so on.

We've provided an example to get you up and running.

    <?xml version="1.0" encoding="UTF-8" ?>
    Metadata for Symplified IdP:

        xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:metadata saml-schema-metadata-2.0.xsd
                            urn:mace:shibboleth:metadata:1.0 shibboleth-metadata-1.0.xsd
                            urn:oasis:names:tc:SAML:metadata:ui sstc-saml-metadata-ui-v1.0.xsd
        <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
                <mdui:UIInfo xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui">
                    <mdui:DisplayName xml:lang="en">Symplified Identity Provider</mdui:DisplayName>
                    <mdui:InformationURL xml:lang="en"></mdui:InformationURL>
                    <mdui:Logo height="77" width="192" xml:lang="en"></mdui:Logo>
                    <mdui:Logo height="16" width="16" xml:lang="en"></mdui:Logo>

            <ArtifactResolutionService index="2"


            <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest"
            <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
            <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"

1. Create and configure an IdP

Let's get the website information required to use Symplified's IdP for your application. We'll load the load the XML document containing SAML 2.0 metadata, and send it off to a metadata parser:

    XmlDocument xDoc = new XmlDocument ();
    xDoc.PreserveWhitespace = true; // This is important do not remove
    xDoc.Load ("");

    Saml20MetadataDocument idpMetadata = new Saml20MetadataDocument (xDoc);

2. Create and configure a SAML 2.0 authenticator

To verify an assertion that returns from the IdP, we'll configure an authenticator using the IdP metadata:

    Saml20Authenticator authenticator = new Saml20Authenticator (

The authenticator will:

  • Create a SAML assertion
  • Send it to the IdP
  • Get an assertion back The assertion is issued depending on conditions such as the user's log in state
  • Verify the signature on the assertion
  • Request resource

3. Authenticate the user via the IdP

Although third-party authenticators control their own UI, you decide how to show the authenticator's UI on the screen. You can manage how the authentication UI is presented–modally, in navigation controllers, in popovers, and so on.

Prior to displaying the UI, we must first listen for the Completed event which triggers when user successfully authenticates or cancels. Find out whether the authentication succeeded by examining the IsAuthenticated property of eventArgs:

    authenticator.Completed += (s, e) => {
        loginViewController.DismissViewController (true, null);

        if (!e.IsAuthenticated) {
            samlLoginStatusStringElement.Caption = "Not authorized";
            samlLoginStatusStringElement.GetActiveCell ().BackgroundColor = UIColor.Red;
        else {
            SamlAccount authenticatedAccount = (SamlAccount)e.Account;

            samlLoginStatusStringElement.Caption = String.Format ("Name: {0}", authenticatedAccount.Assertion.Subject.Value);
            samlLoginStatusStringElement.GetActiveCell ().BackgroundColor = UIColor.Green;

        loginViewController.ReloadData ();

All the information collected from a successful authentication is accessible in eventArgs.Account.

We are now ready to display the login UI from ViewDidAppear on iOS:

    UIViewController vc = authenticator.GetUI ();
    loginViewController.PresentViewController (vc, true, null);

The GetUI method returns UINavigationControllers on iOS, and Intents on Android. Here is how we would write the code to display the UI from OnCreate:

    var intent = authenticator.GetUI (this);
    StartActivityForResult (intent, 42);

4. Store the account

The Symplified Mobile Developer SDK securely stores Account objects so you don't always have to reauthenticate the user. The AccountStore class is in charge of storing Account information, supported by the Keychain on iOS and a KeyStore on Android:

    // On iOS:
    AccountStore.Create ().Save (eventArgs.Account, "");

    // On Android:
    AccountStore.Create (this).Save (eventArgs.Account, "");

Saved Accounts are uniquely identified wiht a key composed of the account's Username property and a "Service ID". The "Service ID" is any string that is used when retrieving accounts from the store.

If an Account was saved earlier, calling Save again will overwrite it. This is helpful for services that expire the credentials stored in the account object.

5. Retrieve stored accounts

You can get all Account objects stored for a given service:

    // On iOS:
    IEnumerable<Account> accounts = AccountStore.Create ().FindAccountsForService ("");

    // On Android:
    IEnumerable<Account> accounts = AccountStore.Create (this).FindAccountsForService ("");

Next Steps

Exchange SAML 2.0 assertion for OAuth 2.0

You can bridge SAML 2.0 to REST APIs using the Symplified Mobile Developer SDK. For example, you can enable a third-party IdP such as Salesforce, then federate authentication.

    SamlAccount authenticatedAccount = (SamlAccount)eventArgs.Account;

    authenticatedAccount.GetBearerAssertionAuthorizationGrant (
        new Uri ("")
    ).ContinueWith (t => {
        if (!t.IsFaulted) {
            accessTokenStringElement.Caption = t.Result ["access_token"];
            scopeStringElement.Caption = t.Result ["scope"];

            BeginInvokeOnMainThread (delegate {
                loginViewController.ReloadData ();
                ListSalesforceResources (t.Result ["instance_url"], t.Result ["access_token"]);
        else {
            Console.WriteLine ("error");