Jump to: navigation, search

Difference between revisions of "HowTo:Integrate UBIK in an SSO Environment"


(Client)
(Important information)
 
(41 intermediate revisions by 3 users not shown)
Line 1: Line 1:
Single Sign On (SSO) allows an end-user to interact with multiple services without logging in more than once.  
+
[[Single_Sign-On|Single Sign-On (SSO)]] allows an end-user to interact with multiple services without logging in more than once.  
  
 
This page shows how to integrate {{UBIK}} into such an SSO environment.
 
This page shows how to integrate {{UBIK}} into such an SSO environment.
Line 6: Line 6:
  
 
= Instructions =
 
= Instructions =
<!-- DO NOT MODIFY THE NAME OF THIS SECTION, BUT REMOVE IT IF NOT REQUIRED -->
 
  
The customer's Identity Provider must know {{{UBIK}}} as a Service Provider. We need to provide an SSO mediator server in order to relay SSO responses for the client; this is our ACS (Assertion Consumer Service).
+
== Important information ==
 +
Single Sign-On (SSO) offers benefits beyond reusing a central account, such as ensuring only the identity provider and browser see user credentials, and enforcing two-factor authentication (2FA). Organizations often secure HTTPS interactions by ensuring requests carry a session cookie from the identity provider or redirecting requests to the identity provider.
  
There are two major use-cases for SSO:
+
While this works for web applications in browsers, it poses challenges for non-browser applications like daemon services or mobile apps. UBIK® addresses this by requiring a valid SSO login via a web browser to create session tokens for its own back channels, making interception by an application gateway not only ineffective but also problematic, as it prevents UBIK® from functioning. Therefore, UBIK® web service URLs must be excluded from 2FA rules on the application gateway to implement SSO securely.
* Authentication: Establishing or re-using an SSO session (logging in)
+
* Authorization: Interaction with external systems (interfacing)
+
  
In order to configure {{{UBIK}}} for SSO integration, we need to address both.
+
{{Hint|It is necessary to exclude {{UBIK}} web service URLs from any application gateway's 2FA redirect rules!}}
  
== Authentication ==
+
Concerns about breaching cybersecurity protocols are unfounded, as UBIK® ensures all sessions are secured via the identity provider. The responsibility for securing the back channel lies with UBIK®, as it is not a web application.
* In the UBIK client profile, adjust the SSO relevant settings (enabling SSO and specifying the Identity Provider Endpoint URL for an IdP-initiated flow).
+
* On the server side, make sure that an SSO Processor is configured able to process the responses from the Identity Provider.
+
  
== Authorization ==
+
If there are further questions, support is available to help.
When a {{{UBIK}}} object is synchronized between client and server, the {{{UBIK}}} customizing can interact with external systems. There, we might require authorization, and we need to make sure the client provides a respective token. In order to do so, we have to identify the specific authorization use-cases:
+
 
* For which types of objects (meta classes) do I need to interact with external systems, requiring SSO authorization?
+
[[Category:How-To|Integrate UBIK in an SSO Environment]]
* For which synchronization operations (e.g., update, commit, create, etc.) do I need authorization?
+
[[Category:SSO|Integrate UBIK in an SSO Environment]]
* Which IdP endpoint is used in this case?
+
[[Category:Version 3.6|Integrate UBIK in an SSO Environment]]
 +
 
 +
== Login ==
 +
As explained in the [[Single_Sign-On]] article, we want the mobile application to receive a token of authenticity from an authority the user has provided their credentials to. Next, the mobile application should ask the USAM web service to accept this token as credentials and establish a {{UBIK}} session.
 +
Of course, the USAM web service must verify whether the token is valid. If so, an internal {{UBIK}} login object is created for the user, if it doesn't exist yet.
 +
This can be customized in order to add further information to the login object (like a name, group relations or other arbitrary information), or to restrict which users may log in, now that their identity is verified.
 +
 
 +
To implement this, the following steps must be done:
 +
* {{UBIK}} must be registered as a client application (or "service provider" in SAML) at the customer's authority or identity provider (IdP).
 +
** The service engineer must provide a callback URL at which we want to receive the result. In case of OIDC, this is the app's deep link URL "com.augmensys.ubik://SSO". For SAML, an intermediate server (assertion consumer service, ACS) is required to relay the token for the app - we provide the {{UBIK}} auth mediator server for this.
 +
** In return, the customer must provide a client ID and client secret for us to configure.
 +
** In case of OIDC, the customer can decide which scopes/claims should be delivered with the token and whether they want to use the ID token or the access token for authentication.
 +
* In the {{UBIK}} client profile, the SSO relevant settings must be adjusted (enabling SSO, specifying the protocol, the IdP URL, client ID, client secret, scopes and whether to use the access token).
 +
* On the server side, make sure that an SSO Processor is configured able to process the responses from the IdP. Also, the processor can be customized for managing the login in greater detail and according to the project's requirements.
 +
 
 +
== Interfacing  with SSO ==
 +
When a {{UBIK}} object is synchronized between client and server, the {{UBIK}} customizing can interact with external systems. There, we might require authentication, and we need the user to provide a respective token so we can act on their behalf. In order to do so, we have to clarify the following details:
 +
* For which types of objects (meta classes) do I need to interact with external systems, requiring SSO authentication?
 +
* For which synchronization operations (e.g., update, commit, create, etc.) do I need authentication?
 +
* Which SSO client configurations (identity provider base URL, scopes, etc. - see "login") are used in this case?
 
For each resulting combination we have to create an [[SYSCLS_EXTERNALAUTHCONFIG|External Auth Config]] object and give it to the client in the infrastructure list.
 
For each resulting combination we have to create an [[SYSCLS_EXTERNALAUTHCONFIG|External Auth Config]] object and give it to the client in the infrastructure list.
  
Further, we have to make sure the authorization tokens can be transported to the server. Therefore, add the [[SYSCLS_EXTERNALENTITY|External Entity Classification]] to all meta classes of objects that need external authorization.
+
Further, we have to make sure the authentication tokens can be transported to the server. Therefore, add the [[SYSCLS_EXTERNALENTITY|External Entity Classification]] to all meta classes of objects that need external authentication.
 +
 
 +
With this, the {{UBIK}} session in the web service's {{UBIK}} Environment is tagged with the SSO token, and the customizing code can use it to interact with 3rd party systems.
 +
 
 +
 
 +
 
 +
 
  
 
= Studio =
 
= Studio =
<!-- DO NOT MODIFY THE NAME OF THIS SECTION, BUT REMOVE IT IF NOT REQUIRED -->
+
 
 +
== Login ==
 +
* Install the Auth Processor plugin (SAMLProcessor or OIDCProcessor plugin) in your web service's injection folder
 +
* Customize your UBIK Context, overriding the method "GetSSOProcessor" so it returns an instance of the authentication processor
 +
 
 +
=== Applying an SSO Processor ===
 +
 
 +
<div class="toccolours mw-collapsible mw-collapsed" style="width:100%; overflow:auto;">
 +
<div style="font-weight:bold;line-height:1.6;">OIDC</div>
 +
<div class="mw-collapsible-content">
 +
{{Version/ServerSince|4.6.0}}In the case of a periodic rolling of the signing key, use the DynamicOIDCProcessor which fetches the JWKS automatically via the base URL of the chosen OIDC Provider:
 +
<syntaxhighlight lang="csharp">
 +
public override UBIK.Kernel.SSO.ISSOProcessor GetSSOProcessor(System.String token)
 +
{
 +
if (this.Name == "MyContextName")
 +
{
 +
string authorityBaseUrl = "...";
 +
return new UBIK.SSO.OIDCProcessor.DynamicOIDCProcessorExt(Environment, token, authorityBaseUrl);
 +
}
 +
return base.GetSSOProcessor(token);
 +
}
 +
</syntaxhighlight>
 +
Instead of "..." you will need to insert the correct URL from your OIDC Provider where the JWKS should originate from.
 +
 
 +
If the JWKS does not roll periodically: 
 +
<syntaxhighlight lang="csharp">
 +
public override UBIK.Kernel.SSO.ISSOProcessor GetSSOProcessor(System.String token)
 +
{
 +
if (this.Name == "MyContextName")
 +
{
 +
string jwks = "...";
 +
return new UBIK.SSO.OIDCProcessor.OIDCProcessorExt(Environment, token, jwks);
 +
}
 +
return base.GetSSOProcessor(token);
 +
}
 +
</syntaxhighlight>
 +
You will need to insert the correct jwks from your OIDC Provider instead of "...".
 +
 
 +
</div></div>
 +
 
 +
<div class="toccolours mw-collapsible mw-collapsed" style="width:100%; overflow:auto;">
 +
<div style="font-weight:bold;line-height:1.6;">SAML</div>
 +
<div class="mw-collapsible-content">
 +
<syntaxhighlight lang="csharp">
 +
public override UBIK.Kernel.SSO.ISSOProcessor GetSSOProcessor(System.String token)
 +
{
 +
if (this.Name == "MyContextName")
 +
{
 +
byte[] certificate= null; // load from file
 +
return new UBIK.SSO.SAMLProcessor.SAMLProcessorExt(Environment, token, certificate);
 +
}
 +
return base.GetSSOProcessor(token);
 +
}
 +
</syntaxhighlight>
 +
You will need to load the correct certificate from your SAML Identity Provider instead of null. It's recommended to save the certificate on the server and load it from file storage. The certificate must be the one the IdP uses to sign its SAML responses with.
 +
 
 +
</div></div>
 +
 
 +
=== Customizing the SSO processor ===
 +
 
 +
There are several use-cases where we need to customize the SSO processor. We can define what should be done when a login object is required or found, and we can use the information delivered with the SSO token in the form of assertions or claims. In any case, we must override the SSO processor implementation, e.g.:
 +
 
 +
<div class="toccolours mw-collapsible mw-collapsed" style="width:100%; overflow:auto;">
 +
<div style="font-weight:bold;line-height:1.6;">Example Code</div>
 +
<div class="mw-collapsible-content">
 +
<syntaxhighlight lang="csharp" >
 +
public class MyOIDCProcessor : UBIK.SSO.OIDCProcessor.DynamicOIDCProcessorExt
 +
{
 +
    // Example for a claim type identifier used to get a value from the Assertions() dictionary.
 +
    public const string KEY_MAIL = @"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress";
 +
 
 +
    public MyOIDCProcessor(UBIKEnvironment environment, string token, string authorityBaseUrl) : base(environment, token, authorityBaseUrl)
 +
    {  }
 +
 
 +
    protected override Login CreateLogin(string loginName, string domain, UBIK.Service.DTO.V220.OSTypes osType)
 +
    {
 +
        // In this example, we use the default login creation, but add the email address as the human-readable login name.
 +
        // However, we could also use a special MetaClass for creating the login instance or do anything else we require.
 +
        Login login = base.CreateLogin(loginName, domain, osType);
 +
       
 +
        // The Assertions() method yields a Dictionary<string, object>, where the values usually are strings, too.
 +
        // The keys correspond to the claim type identifiers.
 +
        if (Assertions().ContainsKey(KEY_MAIL) && !string.IsNullOrEmpty(Assertions()[KEY_MAIL] as string))
 +
        {
 +
            login.Name = Assertions()[KEY_MAIL] as string;
 +
            UBIKKernel.LogCustomizing(MethodBase.GetCurrentMethod(),
 +
            $"Login name for {login.ID} was set to {login.Name} -> Key: {KEY_MAIL}");
 +
        }
 +
        return login;
 +
    }
 +
 
 +
    public override string GetLoginID()
 +
    {
 +
        // Here, we could influence the login ID used in UBIK, if we have a good mapping.
 +
        return base.GetLoginID();
 +
    }
 +
 
 +
    public override Login GetLogin(UBIK.Service.DTO.V220.OSTypes osType)
 +
    {
 +
        Login login = base.GetLogin(osType);
 +
        if (login != null)
 +
        {
 +
            // Here, we could update groups assignment or other account information.
 +
            // If the login object is modified here, please remember to call the login.Save() method before returning!
 +
        }
 +
        return login;
 +
    }
 +
 
 +
    public override bool IsValid()
 +
    {
 +
        // Here, we could only accept trusted accounts, for example.
 +
        return base.IsValid();
 +
    }
 +
}
 +
</syntaxhighlight>
 +
 
 +
</div></div>
 +
 
 +
[[Category:How-To|Integrate UBIK in an SSO Environment]]
 +
[[Category:SSO|Integrate UBIK in an SSO Environment]]
 +
[[Category:Version 3.6|Integrate UBIK in an SSO Environment]]
 +
 
 +
== Interfacing ==
 
* Add [[SYSCLS_EXTERNALAUTHCONFIG|External Auth Config]] objects to the client's infrastructure  
 
* Add [[SYSCLS_EXTERNALAUTHCONFIG|External Auth Config]] objects to the client's infrastructure  
* Add the [[SYSCLS_EXTERNALENTITY|External Entity Classification]] to all affected meta classes
+
* Add the [[SYSCLS_EXTERNALENTITY|External Entity Classification]] to all affected meta class scopes
 +
 
 +
An external auth config object specifies for which meta class and sync action (e.g., when uploading instruction documents), which SSO configuration should be used. The result of a correct configuration will be that the client sends an SSO token to the server when performing the sync action for an instance of the meta class. On the server side, you can use that token to interact with the external system. This only works if there is a scope with the external entity classification for that meta class, because it provides the means to transport the token.
 +
 
 +
Here's how the SSO token can be retrieved by the server side customizing (only when executed by the web service that received the content though, for security reasons):
 +
<syntaxhighlight lang="csharp">
 +
public string GetOIDCToken(UBIKSession session, BaseClass c, UBIK.Kernel.Classification.SSO.IOOperation op)
 +
{
 +
    UBIKKernel.LogDebugOutput(MethodBase.GetCurrentMethod(), 1234, "Getting OIDC Token", this);
 +
    UBIK.Kernel.Classification.SSO.SSOCacheKey key = new UBIK.Kernel.Classification.SSO.SSOCacheKey(op, c.ClassID);
 +
    if (session.Tags.TryRetrieveTag(key, out object tag))
 +
    {
 +
        string oidcToken = tag as string;
 +
        return oidcToken;
 +
    }
 +
    else
 +
    {
 +
        UBIKKernel.LogDebugOutput(MethodBase.GetCurrentMethod(), 1234, "No OIDC token found in session " + session.ID + " for ioOperation " + op + " and class ID " + c.ClassID, this);
 +
    }
 +
    return null;
 +
}
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
 
  
 
= Client =
 
= Client =
<!-- DO NOT MODIFY THE NAME OF THIS SECTION, BUT REMOVE IT IF NOT REQUIRED -->
 
  
* Set up an SSO mediator backend server to relay SSO responses to the client  
+
== OIDC ==
* Configure the SSO profile settings respectively
+
 
 +
* Set up an identity provider if necessary
 +
* Assemble a client configuration JSON string, .e.g. for Entra:
 +
<syntaxhighlight lang="javascript">
 +
      {'AuthorityURL' : 'https://login.microsoftonline.com/{tenantid}/v2.0',
 +
      'ClientID' : '{clientid}',
 +
      'ClientSecret' : null,
 +
      'RedirectURL' : 'com.augmensys.ubik://SSO',
 +
      'Scope' : 'openid',
 +
      'UseAccessToken' : 'false'}
 +
</syntaxhighlight>
 +
* Integrate client configuration in profile:
 +
<syntaxhighlight lang="xml">
 +
  <InternalSSOSettings>
 +
    <EnableSSO>true</EnableSSO> 
 +
    <SSOConfiguration>
 +
      ...
 +
    </SSOConfiguration>
 +
    <SSOProtocol>OIDC</SSOProtocol>
 +
  </InternalSSOSettings>
 +
</syntaxhighlight>
 +
 
 +
{{Hint|Entra requires a client secret for web applications (to be configured both in Entra as well as in the client profile's OIDC settings described above). For native/mobile applications, the client secret must be null though!}}
 +
 
 +
[[Category:How-To|Integrate UBIK in an SSO Environment]]
 +
[[Category:SSO|Integrate UBIK in an SSO Environment]]
 +
[[Category:Version 3.6|Integrate UBIK in an SSO Environment]]
 +
 
 +
== SAML ==
 +
 
 +
* Set up an identity provider if necessary
 +
* Set up an SSO mediator backend server to relay SSO responses to the client
 +
 
 +
To set up an Authentication Mediator Server first go to http://release.augmensys.com/ and download the provided Zip File.
 +
After you downloaded the Zip create a new IIS applicatio (https://docs.microsoft.com/en-us/iis/configuration/system.applicationhost/sites/site/application/).
 +
Open the just created app in your file explorer, unpack the downloaded ZIP file and copy all files of that ZIP into the app-folder.
 +
If IIS prohibites you to copy files you need to first stop the server. After successfully copying the Files you need to Restart/Start the IIS server again.
 +
Now you have set up the Authentication-Backend and it is ready to use.
 +
 
 +
* Assemble a client configuration JSON string, .e.g.:
 +
<syntaxhighlight lang="javascript">
 +
{"AuthUser": "user", "AuthUserPw": "test", "BackendURL": "https://ubik.test.com/UBIK/DEV/AUTH_SERVICE/", "IdpURL": "https://idp.com/idpssoinit?metaAlias=ubik;spEntityID=ubik", "IdpLogoutURL": "", "IsPivotEnabled": false, "Env_Broadcast" : null, "Env_Data": null}
 +
</syntaxhighlight>
 +
* Integrate client configuration in profile:
 +
<syntaxhighlight lang="xml">
 +
  <InternalSSOSettings>
 +
    <EnableSSO>true</EnableSSO> 
 +
    <SSOConfiguration>
 +
      ...
 +
    </SSOConfiguration>
 +
    <SSOProtocol>SAML</SSOProtocol>
 +
  </InternalSSOSettings>
 +
</syntaxhighlight>
 +
 
 
<!-- DO NOT REMOVE THIS -->{{Template:HowTo/End}}<!-- DO NOT REMOVE THIS -->
 
<!-- DO NOT REMOVE THIS -->{{Template:HowTo/End}}<!-- DO NOT REMOVE THIS -->
  
 
==See also==
 
==See also==
 
<!-- DO NOT MODIFY THE NAME OF THIS SECTION, BUT REMOVE IT IF NOT REQUIRED -->
 
<!-- DO NOT MODIFY THE NAME OF THIS SECTION, BUT REMOVE IT IF NOT REQUIRED -->
 +
* [[Single_Sign-On]]
 
* [[SYSCLS_EXTERNALAUTHCONFIG|External Auth Config Classification (SSO)]]
 
* [[SYSCLS_EXTERNALAUTHCONFIG|External Auth Config Classification (SSO)]]
 
* [[SYSCLS_EXTERNALENTITY|External Entity Classification (SSO)]]
 
* [[SYSCLS_EXTERNALENTITY|External Entity Classification (SSO)]]
  
 
[[Category:How-To|Integrate UBIK in an SSO Environment]]
 
[[Category:How-To|Integrate UBIK in an SSO Environment]]
 +
[[Category:SSO|Integrate UBIK in an SSO Environment]]
 +
[[Category:Version 3.6|Integrate UBIK in an SSO Environment]]

Latest revision as of 07:33, 9 October 2024

Single Sign-On (SSO) allows an end-user to interact with multiple services without logging in more than once.

This page shows how to integrate UBIK® into such an SSO environment.


[edit]

Instructions

Important information

Single Sign-On (SSO) offers benefits beyond reusing a central account, such as ensuring only the identity provider and browser see user credentials, and enforcing two-factor authentication (2FA). Organizations often secure HTTPS interactions by ensuring requests carry a session cookie from the identity provider or redirecting requests to the identity provider.

While this works for web applications in browsers, it poses challenges for non-browser applications like daemon services or mobile apps. UBIK® addresses this by requiring a valid SSO login via a web browser to create session tokens for its own back channels, making interception by an application gateway not only ineffective but also problematic, as it prevents UBIK® from functioning. Therefore, UBIK® web service URLs must be excluded from 2FA rules on the application gateway to implement SSO securely.

IC Hint square.pngIt is necessary to exclude UBIK® web service URLs from any application gateway's 2FA redirect rules!

Concerns about breaching cybersecurity protocols are unfounded, as UBIK® ensures all sessions are secured via the identity provider. The responsibility for securing the back channel lies with UBIK®, as it is not a web application.

If there are further questions, support is available to help.

Login

As explained in the Single Sign-On article, we want the mobile application to receive a token of authenticity from an authority the user has provided their credentials to. Next, the mobile application should ask the USAM web service to accept this token as credentials and establish a UBIK® session. Of course, the USAM web service must verify whether the token is valid. If so, an internal UBIK® login object is created for the user, if it doesn't exist yet. This can be customized in order to add further information to the login object (like a name, group relations or other arbitrary information), or to restrict which users may log in, now that their identity is verified.

To implement this, the following steps must be done:

  • UBIK® must be registered as a client application (or "service provider" in SAML) at the customer's authority or identity provider (IdP).
    • The service engineer must provide a callback URL at which we want to receive the result. In case of OIDC, this is the app's deep link URL "com.augmensys.ubik://SSO". For SAML, an intermediate server (assertion consumer service, ACS) is required to relay the token for the app - we provide the UBIK® auth mediator server for this.
    • In return, the customer must provide a client ID and client secret for us to configure.
    • In case of OIDC, the customer can decide which scopes/claims should be delivered with the token and whether they want to use the ID token or the access token for authentication.
  • In the UBIK® client profile, the SSO relevant settings must be adjusted (enabling SSO, specifying the protocol, the IdP URL, client ID, client secret, scopes and whether to use the access token).
  • On the server side, make sure that an SSO Processor is configured able to process the responses from the IdP. Also, the processor can be customized for managing the login in greater detail and according to the project's requirements.

Interfacing with SSO

When a UBIK® object is synchronized between client and server, the UBIK® customizing can interact with external systems. There, we might require authentication, and we need the user to provide a respective token so we can act on their behalf. In order to do so, we have to clarify the following details:

  • For which types of objects (meta classes) do I need to interact with external systems, requiring SSO authentication?
  • For which synchronization operations (e.g., update, commit, create, etc.) do I need authentication?
  • Which SSO client configurations (identity provider base URL, scopes, etc. - see "login") are used in this case?

For each resulting combination we have to create an External Auth Config object and give it to the client in the infrastructure list.

Further, we have to make sure the authentication tokens can be transported to the server. Therefore, add the External Entity Classification to all meta classes of objects that need external authentication.

With this, the UBIK® session in the web service's UBIK® Environment is tagged with the SSO token, and the customizing code can use it to interact with 3rd party systems.



Studio

Login

  • Install the Auth Processor plugin (SAMLProcessor or OIDCProcessor plugin) in your web service's injection folder
  • Customize your UBIK Context, overriding the method "GetSSOProcessor" so it returns an instance of the authentication processor

Applying an SSO Processor

OIDC

In the case of a periodic rolling of the signing key, use the DynamicOIDCProcessor which fetches the JWKS automatically via the base URL of the chosen OIDC Provider:

public override UBIK.Kernel.SSO.ISSOProcessor GetSSOProcessor(System.String token)
{
        if (this.Name == "MyContextName")
        {
                string authorityBaseUrl = "...";
                return new UBIK.SSO.OIDCProcessor.DynamicOIDCProcessorExt(Environment, token, authorityBaseUrl);
        }
        return base.GetSSOProcessor(token);
}

Instead of "..." you will need to insert the correct URL from your OIDC Provider where the JWKS should originate from.

If the JWKS does not roll periodically:

public override UBIK.Kernel.SSO.ISSOProcessor GetSSOProcessor(System.String token)
{
        if (this.Name == "MyContextName")
        {
                string jwks = "...";
                return new UBIK.SSO.OIDCProcessor.OIDCProcessorExt(Environment, token, jwks);
        }
        return base.GetSSOProcessor(token);
}

You will need to insert the correct jwks from your OIDC Provider instead of "...".

SAML
 
public override UBIK.Kernel.SSO.ISSOProcessor GetSSOProcessor(System.String token)
{
        if (this.Name == "MyContextName")
        {
                byte[] certificate= null; // load from file
                return new UBIK.SSO.SAMLProcessor.SAMLProcessorExt(Environment, token, certificate);
        }
        return base.GetSSOProcessor(token);
}

You will need to load the correct certificate from your SAML Identity Provider instead of null. It's recommended to save the certificate on the server and load it from file storage. The certificate must be the one the IdP uses to sign its SAML responses with.

Customizing the SSO processor

There are several use-cases where we need to customize the SSO processor. We can define what should be done when a login object is required or found, and we can use the information delivered with the SSO token in the form of assertions or claims. In any case, we must override the SSO processor implementation, e.g.:

Example Code
public class MyOIDCProcessor : UBIK.SSO.OIDCProcessor.DynamicOIDCProcessorExt
{
    // Example for a claim type identifier used to get a value from the Assertions() dictionary.
    public const string KEY_MAIL = @"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress";

    public MyOIDCProcessor(UBIKEnvironment environment, string token, string authorityBaseUrl) : base(environment, token, authorityBaseUrl)
    {  }

    protected override Login CreateLogin(string loginName, string domain, UBIK.Service.DTO.V220.OSTypes osType)
    {
        // In this example, we use the default login creation, but add the email address as the human-readable login name.
        // However, we could also use a special MetaClass for creating the login instance or do anything else we require.
        Login login = base.CreateLogin(loginName, domain, osType);
       
        // The Assertions() method yields a Dictionary<string, object>, where the values usually are strings, too.
        // The keys correspond to the claim type identifiers.
        if (Assertions().ContainsKey(KEY_MAIL) && !string.IsNullOrEmpty(Assertions()[KEY_MAIL] as string))
        {
            login.Name = Assertions()[KEY_MAIL] as string;
            UBIKKernel.LogCustomizing(MethodBase.GetCurrentMethod(),
            $"Login name for {login.ID} was set to {login.Name} -> Key: {KEY_MAIL}");
        }
        return login;
    }

    public override string GetLoginID()
    {
         // Here, we could influence the login ID used in UBIK, if we have a good mapping.
         return base.GetLoginID();
    }

    public override Login GetLogin(UBIK.Service.DTO.V220.OSTypes osType)
    {
        Login login = base.GetLogin(osType);
        if (login != null)
        {
            // Here, we could update groups assignment or other account information.
            // If the login object is modified here, please remember to call the login.Save() method before returning!
        }
        return login;
    }

    public override bool IsValid()
    {
        // Here, we could only accept trusted accounts, for example.
        return base.IsValid();
    }
}

Interfacing

An external auth config object specifies for which meta class and sync action (e.g., when uploading instruction documents), which SSO configuration should be used. The result of a correct configuration will be that the client sends an SSO token to the server when performing the sync action for an instance of the meta class. On the server side, you can use that token to interact with the external system. This only works if there is a scope with the external entity classification for that meta class, because it provides the means to transport the token.

Here's how the SSO token can be retrieved by the server side customizing (only when executed by the web service that received the content though, for security reasons):

public string GetOIDCToken(UBIKSession session, BaseClass c, UBIK.Kernel.Classification.SSO.IOOperation op)
{
    UBIKKernel.LogDebugOutput(MethodBase.GetCurrentMethod(), 1234, "Getting OIDC Token", this);
    UBIK.Kernel.Classification.SSO.SSOCacheKey key = new UBIK.Kernel.Classification.SSO.SSOCacheKey(op, c.ClassID);
    if (session.Tags.TryRetrieveTag(key, out object tag))
    {
        string oidcToken = tag as string;
        return oidcToken;
    }
    else
    {
        UBIKKernel.LogDebugOutput(MethodBase.GetCurrentMethod(), 1234, "No OIDC token found in session " + session.ID + " for ioOperation " + op + " and class ID " + c.ClassID, this);
    }
    return null;
}



Client

OIDC

  • Set up an identity provider if necessary
  • Assemble a client configuration JSON string, .e.g. for Entra:
      {'AuthorityURL' : 'https://login.microsoftonline.com/{tenantid}/v2.0',
      'ClientID' : '{clientid}',
      'ClientSecret' : null,
      'RedirectURL' : 'com.augmensys.ubik://SSO',
      'Scope' : 'openid',
      'UseAccessToken' : 'false'}
  • Integrate client configuration in profile:
  <InternalSSOSettings>
    <EnableSSO>true</EnableSSO>  
    <SSOConfiguration>
      ...
    </SSOConfiguration>
    <SSOProtocol>OIDC</SSOProtocol>
  </InternalSSOSettings>
IC Hint square.pngEntra requires a client secret for web applications (to be configured both in Entra as well as in the client profile's OIDC settings described above). For native/mobile applications, the client secret must be null though!

SAML

  • Set up an identity provider if necessary
  • Set up an SSO mediator backend server to relay SSO responses to the client

To set up an Authentication Mediator Server first go to http://release.augmensys.com/ and download the provided Zip File. After you downloaded the Zip create a new IIS applicatio (https://docs.microsoft.com/en-us/iis/configuration/system.applicationhost/sites/site/application/). Open the just created app in your file explorer, unpack the downloaded ZIP file and copy all files of that ZIP into the app-folder. If IIS prohibites you to copy files you need to first stop the server. After successfully copying the Files you need to Restart/Start the IIS server again. Now you have set up the Authentication-Backend and it is ready to use.

  • Assemble a client configuration JSON string, .e.g.:
{"AuthUser": "user", "AuthUserPw": "test", "BackendURL": "https://ubik.test.com/UBIK/DEV/AUTH_SERVICE/", "IdpURL": "https://idp.com/idpssoinit?metaAlias=ubik;spEntityID=ubik", "IdpLogoutURL": "", "IsPivotEnabled": false, "Env_Broadcast" : null, "Env_Data": null}
  • Integrate client configuration in profile:
  <InternalSSOSettings>
    <EnableSSO>true</EnableSSO>  
    <SSOConfiguration>
      ...
    </SSOConfiguration>
    <SSOProtocol>SAML</SSOProtocol>
  </InternalSSOSettings>


See also