External Claims Transformation

Although the different transformation rules that exist in Safewhere*Identify will cover a lot of different situations, there will still be many scenarios where standard rules do not suffice. It is possible to create your own transformation rule and plug in to Safewhere*Identify. Briefly speaking, an external claims transformation module enables third parties to write claim transformation rules that are independent from the Safewhere*Identify build. Some of the important features are:

  • It is possible to change an external DLL by simply copying the new DLL to the Safewhere*Identify server and recycling the app pool.
  • There is no dependency between the external DLL and a specific build of Safewhere*Identify. The only dependency between the two is the interface that is implemented by the external DLL.
  • The interface is defined in a strongly named assembly, but its version is fixed as long as there are no breaking changes.
  • A new build of Safewhere*Identify does not require that the external DLL be recompiled.

Before we set up the external claims transformation rule in Safewhere*Identify, we must first prepare the plug-in.

The processing flow for External Transformation

The processing flow for how a claims principal is exposed to the claim transformation pipeline:

  1. The principal is then passed through the configurable claims transformation rules that are configured to run after the rule that loads claims from the local store. External transformations can also be among the rules that are run after claims are loaded from the local store.
  2. The principal then loads claims from the local store.
  3. The principal is then passed through the configurable claims transformation rules that are configured to run before the rule that loads claims from the local store. External transformations can be among the rules that run before claims are loaded from the local store.
  4. The principal is passed through Safewhere*Identify’s built-in, hard-coded transformation rules.
  5. The user authenticates.
  6. A claims principal is created.
  7. The principal is finally passed through Safewhere*Identify’s other built-in, hard-coded transformation rules.

Steps to implement a new External Transformation

There are three steps:

  1. Reference the Safewhere.External assembly.
  2. Implement the IExternalClaimsTransformation interface.
  3. Set up the External Transformation to be used in the normal way from Safewhere*Identify’s Administrator pages.

An external custom claims transformation must implement the IExternalClaimsTransformation interface:

  • By design, the claims principal object may have more identities.
  • Each Identity Provider may add its own identity to the claims principal object at the time the principal object is passed to this transformation rule. The number of identities it contains depends on what previous transformation rules it has passed through.
  • Typically what happens is:
    • After Safewhere*Identify receives a token from an upstream Identity Provider or from the UserNamePassword login, it creates the principal with one identity.
    • There is a special, built-in transformation that loads claims from the local store into another identity and adds it to the principal (two identities so far).
    • There is a setting called "Execute before loading claims from local store" in the claims transformation configuration page, which controls if a transformation should be executed before or after the second identity is added.
    • Note 1: It is safe to add a claim to multiple identities because all but one will be filtered out before returning them to the service provider..
    • Note 2: Other transformations may add more identities to the claims principal.

Exception handling and logging

The interface assembly will provide an interface for logging:

External assemblies can use this interface to log exceptions as well as other information to event logs at their will.

For unhandled exceptions from an external custom transformation, Safewhere*Identify will log them to the event log. Safewhere*Identify will then either halt the processing pipeline or progress to the next transformation based on the relevant settings.

In order to enable logging to the Safewhere event log, simply add a dependency to the IIdentifyLogWriter interface. For example:



The external plug-ins will need their own text resources. These text resources will also be used for the custom views.

Safewhere*Identify’s text resource framework is built in a way that allows customized default language. In addition, it is also possible to override default texts with some company-specific resources. But because external DLLs are used for a specific installation, where you know what the default language is, you can make the plug-in use a simpler text resource model:

  • Add text resource files to the project.
  • Text resources files' properties must be set correctly:
    • Build Action: None
    • Copy to output: Do not copy
    • Custom tool: GlobalResourceProxyGenerator
  • Upon deploying the DLL, also copy the resource files to appropriate folders.

It is recommended that when logging messages to the event log, the external DLL should hard-code messages in the language of its choice instead of reading from text resources. Otherwise, messages may be logged in the user’s preferred language.

How to use the Plugin

Drop your DLL into the Tenants\Runtime\bin folder then reset the IIS.

Go to Identify*Admin and create a new external transformation rule.


The Transformation consists of five sections.

Claim Transformation Name: Give the Transformation object a name that will make it easy to recognize when adding to the Pipelines of Authentication and Protocol connections.

Culture: Since expression may be using and comparing numbers, it is important for the system to know what culture is used in order to know whether comma or dot indicates a decimal point. Currently only two cultures are supported, Danish (comma is decimal point) and American (dot is decimal point). These should cover the needs of other cultures in regards to this issue.

Owner Organization: The organization that the Claim Transformation is added to.

Execute before loading claims from local store: By default, a claim transformation rule is executed after claims from local store are loaded for a principal. Check this option to let it execute before the load.

Conditions: It is possible to specify that the Transformation object is only applied to a Pipeline given certain conditions of the token or user is in place, include:

External Claims Transformation: Select the assembly qualified name of the transformation into the Transformation type name drop-down box. The options in this drop-down list will be updated immediately after the DLL files are put into the Bin folder.

If you do not want the pipeline to break down in case the External Plug-in failed, enable the Continue on error check box.

Additional settings: Give some predefined settings, which will be used on transform on the selected external claims transformation above.

Questions and Answers on Using External Transformations

  • Question: Do I need to wire up my transformation in some Windsor file?
  • Answer: No, Safewhere*Identify can do the registration job for you at runtime.
  • Question: What if my transformation has dependency to another service? For example, what if it has a dependency to IMyCompanyEmailSender service?
  • Answer: Then unfortunately, you will need to wire your transformation up the IMyCompanyEmailSender in some Windsor file. You still don't need to wire up the transformation itself, though.
  • Question: How many identities does a claims principal have?
  • Answer: A claims principal, by the time it is passed to an external claims transformation, should have two identities: a name claim identity and a local user identity, which contains all the claims that are issued by the local store. The second identity is for claim issuance purpose only. An external transformation can add new claims to either of the two or add to both. Duplicate claims will be filtered out later.

Event IDs

Event IDs used by Safewhere*Identify for this plug-in are:

  • 140: External claims transformation error.