System User MVC Example

Introduction to the system user example for SuperOffice CRM Online


This introduction assumes that you understand what SuperOffice CRM Online is, and that you have a working knowledge of programming in C#, Certificates and SAML/JWT tokens.


You need Visual Studio 2013. (or higher)
.Net 4.5.1 Framework
This example is based on C# ASP.NET MVC and a Console Application


This article outlines the steps necessary to build applications that work in the SuperOffice Online Development (SOD) environment. SOD is a sandbox environment that mirrors what exists in the SuperOffice Online production environment, but is different in that it does not share any data at all with, and is isolated from, the production environment. SOD and Production contain different set of customers and require different set of credentials.

This article explains how to a use a system user when interacting with SuperOffice Online tenant web services. There are three individual components that work together to demonstrate the system user concept.

Private keys and shared certificates are also important and must be configured correctly for this example to work successfully. See the How to Configure Certificates for Online Apps article to learn more about configuring certificates.



The three functional components of the System User example are:

  1. The ASP.NET MVC application. This is an application that represents the minimum an App Store application is required to handle, including authenticating an administrator installing the application and obtaining an system user ticket.
  2. The console application. This is a mockup of a partner service that periodically checks the file for new tenants and demonstrates how to obtain a system user ticket from a system user token.
  3. Shared partner datasource. This example uses an XML file to store system user tokens for SuperOffice online tenants.

The following diagram depicts the workflow of this example.

  1. Administrator installs, or user navigates to, partner application.
  2. Unauthenticated attempt to access to SuperOffice functionality and is therefore redirected.
  3. User is redirected to SuperID with application ID for authentication.
  4. User is successfully authenticated and redirected to the partner applications redirect URL.
  5. Partner application receives SuperID request and SAML/JWT token. Validated using certificates.
  6. Partner application processes/configures user and stores system user token in database.
  7. Partner service polls database for new tenant user tokens.
  8. Partner service signs user token with private key and sends it to SuperID to exchange for a system user ticket.
    (demo private key is in the service console certificates folder).
  9. Partner service validates system user token using certificates.
  10. Partner service calls tenant web services using system user ticket.



Setup requires installing certificates on the development machine and a Temp folder on the C:\ drive to store system user tokens.

Before you continue, you must either configure the certificates on the development machine, or decide to use a local certificate stored in the App_Data folder. More information about understand and installing certificate requirements is located in the certificates section of the Security and Authentication article



There are four projects in the SystemUserApps.sln solution.


An ASP.NET MVC site that hosts the callback (redirect URL) and demonstrates how to validate a SAML token, extract tokens from the SAML token, and stores the system user token in the datasource.


Classes used by both the MVC Application and ServiceConsole for accessing the customer datasource.


Contains several context-related and helper classes for security-related tasks.


A console application that simulates a service that periodically polls the database, demonstrates how to exchange the system user token for a system user ticket and call the tenant web services.



The first time the web application runs, the default page will detect that the current user has not logged into this application and it will redirect the user to SuperOffice federation gateway (SuperID) for authentication.

The applicationId is appended in the URL passed to SuperID. The applicationId is registered inside SuperID’s Operations Center (OP), and knows all it needs to about the partners application, such as installation URL, authentication redirect URL, uninstallation URL, as these were provided when the application was registered.


Upon successful authentication, the customer is presented with the application approval page. The application approval page displays an “I approve” button that must be clicked to allow the application to access to the customers’ web services and database. In the Future the approval page may expose additional controls such as checkboxes for more specific rights.


Upon a success authentication, SuperID will uses the application id to determine where the user is redirected. The example application has “http://localhost/SuperOffice.Online.SuperIdDemoWeb/Callback” as its default redirect URL.

SuperID passes the SAML/JWT token with claims in the redirect response.

The redirect URL can be changed upon request. Future capabilities will enable you to change it yourself, but for now you must send an email to have it changed for you. Redirect URL change requests can be sent to
The callback controller CallbackController.cs, performs tasks that establish the current user context, as well as inserts the system user token into a database. Once completed, the user is redirected to the application default page.


The default page displays two action links.

  1. Create Company with Login User
  2. Create Company with System User

The first link uses the current users' SoSession (Principal Context) to create a new company in the tenant SuperOffice. This is standard functionality used to contrast how to perform the same operation as a system user.

The second link using a system user token to get a system user ticket, and then uses the system user ticket to authenticate and create a new company in the tenant database. This scenario is not the recommended way to leverage a system user in an application. Threading with a NetServer SoSession instance is a complex topic, and it is only here in this example as a demonstration of signing the token, sending the signed token to SuperID, and then validating the returned SAML/JWT token containing the system user ticket.

The preferred way to use a system user token is demonstrated in the System Console project.


In the first version of this example existed a SQL Server dependency. A database with a single table to hold customer information was used as a means to share data between both the MVC application and the console service application. That proved to be cumbersome for those unfamiliar with SQL Server and over complicated this example. This has since been replaced with a shared XML Serialization Datasource that reads and writes customer data to an XML Document.

The CustomerDataSource is located in the SuperOffice.DevNet.Online.SystemUser.PartnerDBLibrary project.


This project has several helper classes that help facilitate many common operations such as securing access, providing models for and hosting user context.

The following sections detail key classes in the Login library and describe their purpose.

PartnerHttpContext Class: SuperOffice Context Provider

When SuperOffice API code is executed, a context provider is required to supply an authenticated principal to the executing code. During initial authentication, NetServer validates a set of credentials and then delegates where to store the session containing the principal. This is delegated to the context provider.

The default memory storage location options for a SuperOffice session are: Process, Context and Thread. These do not scale well in web applications. Therefore, a context provider must be created that stores the session in such a way that ASP.NET web applications can manage. This example implementation uses ASP.NET Session state as a storage medium.

Please refer to the code in the SuperOffice.DevNet.Online.Login.SoPlugins.HttpContextProvider.cs file for details.

SuperOfficeAuthorizeAttribute Class: Access Security

Protecting data and resources, and requiring user context, is a necessity. In this example, the SuperOfficeAuthorizeAttribute class is the gatekeeper. Its job is stand in front of each method containing SuperOffice API code and verify that an authenticated session exists. If an authenticated session exists, the method is allowed to proceed. If an authenticated session does not exist, the user is redirected to the SuperOffice SuperID federated login page, defined in the appSettings>SoFederationGateway property. Upon successful authentication, the user is then redirected from SuperID to the predefined callback URL set in OC. More information about the callback URL is in section

The URL that defines the SuperOffice SuperID login page is defined in the SoFederationGateway appSettings value, and will change when moving to the production environment.


The Service Console project is used to demonstrate how to submit a request to SuperID to exchange a System User token for a System User ticket, as well as use the shared datasource. 

Other than the console window, there is not GUI for this application. The console window will only display log messages that indicate the process steps.


This section will present the technical details to understand what is required to get the example running on your machine. This section also explain how the example application works.

Run Visual Studio As Administrator

The web application is configured to run a web site on your machine, IIS localhost. To make it easier on yourself, open visual studio as an administrator so that Visual Studio can create the site in IIS automatically for you.

If you open the solution and notice that the SuperOffice.Online.SuperIdDemoApp project has failed to load, this is probably because your visual studio is not run as administrator.

Your instance of Visual Studio should have (Administrator) in the title bar.

Web.Config Configuration Overview

The key sections in Listing One are SuperOffice>Data>Session, SuperOffice>Service and appSettings.

Listing One: Relevant web.config sections.

    <sectionGroup name="SuperOffice">

        <sectionGroup name="Data">
        <section name="Session" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        <section name="Services" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
            <!-- HttpContext means session information is stored, vs being recreated all the time -->
            <add key="Mode" value="PartnerHttpContext" />
    <!-- Mode can be Local, Remote, Switch; local for web + appserver on same machine, remote otherwise -->
    <add key="DefaultMode" value="Remote" />
    <add key="ApplicationToken" value="df2d5bd84dd3848a8235e1d7e40d5b64" />
    <add key="SoAuthCookie" value="PartnerAuth" />
    <add key="SoAppId" value="c2f1cee99dfab952d7f3cbda30d9762a" />
    <add key="SoFederationGateway" value="" />
    <add key="SystemTokenCertificatePath" value="certificates\partnerprivatekey.xml" />
    <add key="SuperIdCertificate" value="16b7fb8c3f9ab06885a800c64e64c97c4ab5e98c" />

The Session Mode property instructs NetServer to use the PartnerHttpContext provider to store the users context during application execution.

SuperOffice Services DefaultMode

DefaultMode must be “Remote” to work with SuperOffice Online web services.

SuperOffice Services ApplicationToken

ApplicationToken must be set to identify partner applications defined in SuperOffice Online Operations Center (OC). Online services will reject unidentified callers. This property is expected and used by the NetServer proxy assemblies.
The token is only exchanged after a secured http connection is established.

An application is the SuperOffice Online Development environment must have a different ApplicationId and ApplicationToken value than one in production.

appSettings SoAuthCookie

SoAuthCookie is an identity used when persisting a Cookie.

appSettings SoAppId

SoAppId is a public application identifier. It is used by the AuthenticationHelper class and is appended to the URL used when forwarding your application to the SoFederationGateway URL (also defined in AppSettings). The SoAppId does appears in the in the browser address bar when forwarded to SuperId, and is susceptible to a man in the middle attacks. However, token validation upon successful authentications mitigate this threat. The SoAppId is relevant when a new user attempts to access your partner application for the first time. That user will be prompted to allow your application to run within the users’ context. This also feature also allows a partner to revoke access if necessary. Although inaccessible to partners today, this feature will be made accessible in the future.

An application is the SOD environment must have a different SoAppId value than one in production.

appSettings SoFederationGateway

SoFederationGateway specifies the URL where SuperID resides. This will change between the development environments and production.

SuperOffice SuperID Development:
SuperOffice SuperID Production:

appSettings SystemTokenCertificatePath

SystemTokenCertificatePath is a local file path to the partner private key. The contents of the example private key file appears as:

F9TL6DI6+XJOw==</P> <Q>uZNfZNXMnZt50G/SJewg3TqsfT9N3QyAqsifoSV1xoNhVpNL6A64iD8OyVrSzp50Rwnh1QS1
  byp/9xQ==</DP >


appSettings SuperIdCertificate

SuperIdCertificate is the certificate thumbprint identifier on the machine hosting the web site. The thumbprint is used by the SuperIdTokenHandler class to verifying the token (SAML or JWT) returned by SuperID to the partner web application.

This thumbprint value is different for targeting SuperOffice Online Development and Production environments.


This section will focus on the main files of the site and define the purpose and use of each page.

The key files in this example are:

  • Private Key                     => partnerprivatekey.xml
  • HomeController             => HomeController.cs
  • CallbackController         => CallbackController.cs
  • ContactEntityController => ContactEntityController.cs
  • SystemUserController   => SystemUserController.cs
  • System User Helper      => SystemUserHelper.cs

These files demonstrate the key aspects of this installation.







Private Key

This file is responsible for signing the system user token prior to sending a request to receive a system user ticket from SuperID. This was step 8 in the Functional Overview (section 1.2).
When a user clicks “Install SuperOffice Maps”, the application checks to see if you are already logged into SuperID. If not, the application redirects to the SuperID login page. If logged in, the user is redirected to the LoginRedirect.aspx page.

Home Controller

HomeController.cs is the default action and its responsibility is to check if the current user is signed in. If the current user is not signed in the home controller will redirect the user to the SuperID sign in URL.

The home controller makes use of a security attribute class defined in SuperOfficeAuthorizeAttribute.cs, located in the SuperOffice.Online.PartnerLogin project. Its purpose is to determine if the current user has been previously authenticated or not. This class is described in more later on.

If the current user has not been authenticated, the user is redirected to SuperID, the SuperOffice Federation Gateway. The URL for SuperID is located in the appSettings section of the App.Config file and Web.Config file.

The application id is appended to the URL when redirected to SuperID. This is done so that SuperID knows what application sent the user to sign in, and where SuperID must redirect the user once the user has been successfully authenticated.

Callback Controller

The responsibility of the callback controller is to validate the Security Assertion Markup Language (SAML) or JSON Web Token (JWT) token issued by SuperID and establish a user context.

CallbackController.cs is called after a user is successfully authenticated by SuperID.
The SAML token contains all of the claims a partners application needs to connect to and communicate with the user tenant in SuperOffice Online.

The user context will be used by the web application for all successive calls to the tenant web services. The user context is managed in another class defined in the SuperOffice.Online.PartnerLogin project, the PartnerHttpContext class.

ContactEntity Controller

ContactEntityController.cs is used to demonstrate how to create a new company using the current user.

System User Controller

SystemUserController.cs is used to demonstrate how to create a new company using the system user. This controller leverages the SystemUserHelper class, and then redirects the results to the ContactEntityController for displaying the new company details.

System User Helper

SystemUserHelper.cs contains the code that demonstrates the key aspects of this example. SystemUserHelper demonstrates how to; sign a system user token with a private key, exchange a system user token for a security token that contains a system user ticket, validate a security token and how to use the security token to establish a tenant context (Database Context) and authenticate as a system user using the system user ticket.


The purpose of the service console is to mimic a long running service that performs periotic operations against multiple tenants.

This example mimic functionality by employing a System.Threading.Timer. Every 15 seconds the timer is elapsed and executes a query against the example database. The query gets all customers who are marked as Active, and for each customer who is active the service exchanges that customers system user token for a system user ticket. With the new ticket, the service established a tenant database context and then authenticates the system user using the system user ticket.

The primary objective of this example is to demonstrate how to use a certificate to sign a system token, and use the signed system token, context identifier, and application token to get a SystemIdToken – which contains the system user ticket.


The SuperOffice.DevNet.Online.SystemUser.PartnerDBLibrary project contains one customer model and one customer data source class.

The customer model CustomerInfo contains 6 properties that represent a single tenant customer.

namespace SuperOffice.DevNet.Online.SystemUser.PartnerDBLibrary.Models
    public class CustomerInfo
        public int ID { get; set; }
        public int AssociateID { get; set; }
        public bool IsActive { get; set; }
        public string SystemUserToken { get; set; }
        public string ContextIdentifier { get; set; }
        public DateTime LastSync { get; set; }


The CustomerDataSource class could not be more simple. It's sole responsibility is to read CustomerInfo data from, and save new CustomerInfo data to, an XML file. This project and data source classes are used by both the MVC web site and the console application.

public class CustomerDataSource
    private const string _dataSource = @"C:\Temp\Customers.xml";

    public CustomerDataSource()

    public List<CustomerInfo> Customers = new List<CustomerInfo>();

    public void Save()
         XmlSerializer serializer = new XmlSerializer(typeof(List<CustomerInfo>));

        using (TextWriter writer = new StreamWriter( _dataSource))
             serializer.Serialize(writer, Customers);

    private void Deserialize()
        if (!File.Exists(_dataSource))

        XmlSerializer deserializer = new XmlSerializer(typeof(List<CustomerInfo>));
        using(TextReader reader = new StreamReader(_dataSource))
            object obj = deserializer.Deserialize(reader);
            Customers = (List<CustomerInfo>)obj;



This list contains the currently supported claims inside a SAML or JWT token. The strongly defined type is SuperOffice.SuperID.Client.Tokens.SuperIdToken.

*AssociateId Associate ID of the current in user
Context Identifier name of the customer instance, i.e. Cust1234
Email Email address of the current user
*Firstname First name of the current user
Identity Provider Identity provider used for authentication
*Lastname Last name of the current user
NetServer[version]_URL URL address of the current user tenant web services
Ticket Hash value representing current user identity
SystemToken System user token, used to get a system user ticket credential.






Partner registration is by an online form, and approval of submissions is manual process. 

Application ID’s and Application Token's are sent to the email address after an application has been registed by the Register an App online form.

Run the example and step through the code to see how it functions as a unit with SuperID.

Any questions can be submitted to SuperOffice DevNet via:


  • Q: After signin to SuperID, the application seems to run in an infinite loop. First I signin, then the web application appears, and then I’m redirected back to SuperID signin screen, and then back to the web application.
    • A: Once a user has successfully logged into SuperID, and has been redirected back to the Redirect.aspx page, the application calls into the SuperOfficeAuthorizer.RedirectAfterLogin method. Here the application gets the claims returned by SuperID and has all of the information necessary to authenticate the user (locally) so as to establish an SoPrincipal in an SoSession (stored in the PartnerHttpContext), and create an authentication cookie for the user. If the user does not authenticate in the application environment, the application may experience an infinite loop where the user is constantly asked to authenticate via SuperID, be redirected back to the application, which then redirects back to SuperID, etc. Set a breakpoint in the breakpoint in the CallbackController.cs file on line 80 and read the exception being thrown.
Legg ut kommentar Til toppen