Show / Hide Table of Contents

    Script library

    Introduction

    Safewhere Identify has many scripting extensible points where you can add custom business logics to Identify runtime pipeline using C# scripts. Problems arise when you have many resources, e.g. multiple connections, and you need to configure the same script for all of them. As a consequence, if you want to make a small change to your script, you will need to update it for all connections.

    Using scripts is also a flexible approach for customizing business logic for Interceptor and Generic provider without the need to redeploy DLLs across a single or multiple nodes after each upgrade.

    Scripting library is a new way to manage your scripts. You can define your scripts on the Scripting library page. To use them, you can then add the name of a script to a scripting setting. You can see that the new scripting library feature is very similar to how Scripting claims transformation works.

    Script library page

    Script library page is a place to manage all your scripts.

    Script library menu

    A script has the following properties:

    • Name: name of a script

    • Script type: please see section Script type

    • Script: a script is written in C# language (version 8.0) and compiled against the .NET framework 4.8

      • Support functions by placing them in a predefined #region (#region additional methods --- #endregion additional methods) Creating a new script library

      • Some script types such as Generic provider or interceptors are full class scripts which means you must define a class for the script.

    • Additional assembly references: please see the Additional assembly references section.

    • Additional namespaces: please see the Additional namespaces section.

    • Validation: when saving a script, the system will validate whether the script has correct syntax and structure, and then try to compile the script.

    Compiler threw an error message

    Script types

    There are totally 23 supported script types grouped into 9 different categories:

    script categories

    Each script types will have different input data types. Below is the specification for each type of script:

    Validate authentication context class that is sent via an AuthnRequest from a SAML Service Provider

    Script usage

    You can use a script of this type to customize validation of an authentication context class that is sent via an AuthnRequest from a Service Provider

    Script type Validate authentication context class that is sent via an AuthnRequest from this Service Provider

    Script input parameters

    Name Type
    authnRequest AuthnRequest
    httpContext HttpContextBase
    samlAuthnRequestInformation SamlAuthnRequestInformation
    configSection SamlSPMetadataConfigurationSection
    requestedAuthenticationContextModel RequestedAuthenticationContextModel

    Example scripts

    • Validate the authentication context comparison
    if (authnRequest.RequestedAuthnContext != null && authnRequest.RequestedAuthnContext.Comparison != AuthnContextComparison.Minimum)
    {
        SystemLogger.Instance.WriteDebug("Write some information for debugging...");
        Func<string> errorMessageFunc = () => "Write a detailed error here to throw an validation exception";
    
        throw new SamlSignOnValidationException(errorMessageFunc) { ResponseErrorCode = StatusCodes.Requester };
    }
    
    • Assign an authentication context class
    if (requestedAuthenticationContextModel.MinimumNeededAuthnContext == "https://data.gov.dk/concept/core/nsis/loa/Low")
    {
        requestedAuthenticationContextModel.Comparison = AuthenticationContextComparison.Minimum;
        requestedAuthenticationContextModel.MinimumNeededAuthnContext = "https://data.gov.dk/concept/core/nsis/loa/Substantial";
    }
    

    Validate authentication context class that is returned from an upstream SAML Identity Provider

    Script usage

    You can use a script of this type to customize validation of authentication context class that is returned from an Identity Provider Script type Validate authentication context class that is returned from an upstream Identity Provider

    Script input parameters

    Name Type
    assertion Saml2Assertion
    httpContext HttpContextBase
    samlResponseRequestInformation SamlResponseRequestInformation
    authConfig SamlSignOnConfigurationSection
    requestedAuthenticationContextModel RequestedAuthenticationContextModel
    passiveProtocolContext PassiveProtocolContext

    Example scripts

    • Validate duplicated security levels
    var attributes = assertion.Statements.OfType<Saml2AttributeStatement>().SelectMany(x => x.Attributes);
    if (attributes.Any(a => a.Name.Equals("dk:gov:saml:attribute:AssuranceLevel", StringComparison.OrdinalIgnoreCase)) &&
                    attributes.Any(a => a.Name.Equals("https://data.gov.dk/concept/core/nsis/loa", StringComparison.OrdinalIgnoreCase)))
    {
        throw new SamlSignOnValidationException(() => "Duplicated security level.")
        {
            ResponseErrorCode = StatusCodes.Responder,
            ResponseSubErrorCode = StatusCodes.NoAuthnContext
        };
    } 
    
    • Validate the received security level
    var claims = assertion.Statements.OfType<Saml2AttributeStatement>().SelectMany(x => x.Attributes)
                .Where(x => x.Name.Equals("https://data.gov.dk/concept/core/nsis/loa", StringComparison.OrdinalIgnoreCase)).ToList();
    
    if (!claims.Any())
    {
        throw new SamlSignOnValidationException(() => "Security level is not found.")
        {
            ResponseErrorCode = StatusCodes.Responder,
            ResponseSubErrorCode = StatusCodes.NoAuthnContext
        };
    }
    var assuranceLevel = claims[0].Values[0];
    
    if(assuranceLevel == "Low")
    {
        throw new SamlSignOnValidationException(() => "'Low' security level is not allowed.")
        {
            ResponseErrorCode = StatusCodes.Responder,
            ResponseSubErrorCode = StatusCodes.NoAuthnContext
        };
    }
    
    

    Customize authentication context class that is sent via an AuthnRequest to an upstream SAML Identity Provider

    Script usage

    You can use a script of this type to customize authentication context class mapping from a value sent by a Service Provider to a value that will be sent to an Identity Provider. The script is configured for the Identity Provider. Customize authentication context class that is sent via an AuthnRequest to an upstream Identity Provider

    Script input parameters

    Name Type
    authnRequest AuthnRequest
    httpContext HttpContextBase
    samlAuthnRequestInformation SamlAuthnRequestInformation
    logOnConfig SamlSignOnConfigurationSection
    requestedAuthenticationContextModel RequestedAuthenticationContextModel

    Example scripts

    • Set custom values for requested authentication context method class
    var sessionLoginContext = samlAuthnRequestInformation.LoginContext;
    if (authnRequest.RequestedAuthnContext == null)
    {
        authnRequest.RequestedAuthnContext = new RequestedAuthnContext();
    }
    
    if (sessionLoginContext.TwoFactorContextModel.UseTwoFactor)
    {
        string customAssuranceLevel = requestedAuthenticationContextModel.StepUpAuthnContext;
    
        SystemLogger.Instance.WriteDebug("Set assuranceLevel to {0}.", customAssuranceLevel);
        authnRequest.RequestedAuthnContext.Comparison = AuthnContextComparison.Minimum;
        authnRequest.RequestedAuthnContext.AuthnContextRefs.Add(new Uri(customAssuranceLevel));
        authnRequest.RequestedAuthnContext.AuthnContextRefType = AuthnContextRef.AuthnContextClassRef;
    }
    

    Customize step-up behavior of a SAML Service Provider

    Script usage

    You can use a script of this type to customize step-up behaviors of a SAML Service Provider

    Script type Customize step-up behavior

    Script input parameters

    Name Type
    authnRequest AuthnRequest
    httpContext HttpContextBase
    samlAuthnRequestInformation SamlAuthnRequestInformation
    configSection SamlSPMetadataConfigurationSection
    reusableContext PassiveProtocolContext
    requestedAuthenticationContextModel RequestedAuthenticationContextModel
    supportsScope bool

    Example scripts

    • Set Step-up behavior based on the current context
    if (reusableContext == null && requestedAuthenticationContextModel.AuthnRequestHasRequestedAuthnContext)
    {
        SystemLogger.Instance.WriteDebug("AuthnRequestSignOnRequestArrivedObserver: reusableContext is null. Set IsForcingAuthnDueToScopingOrStepUp = true");
        temporaryProtocolContext.IsForcingAuthnDueToStepUp = true;
    }
    

    Select which Identity Providers a SAML Service Provider can use (connection dependency customization)

    Script usage

    You can use a script of this type to specify what Identity Providers that a Service Provider can use. This script overrides the default behavior which uses the connection dependency list.

    Script type Select what Identity Providers that this Service Provider can use

    Script input parameters

    Name Type
    connWithMethodClasses IList<AuthenticationConnectionWithMethodClass>
    requestedAuthenticationContextModel RequestedAuthenticationContextModel
    httpContext HttpContextBase
    loginContext SessionLoginContext

    Return value

    This scripting requires to return a list of AuthenticationConnection.

    Example scripts

    • Filler out Identity providers by authentication context method class
    string requestedAssuranceLevel = requestedAuthenticationContextModel.MinimumNeededAuthnContext;
    List<AuthenticationConnection> matchConditionConnections = new List<AuthenticationConnection>();
    
    foreach (AuthenticationConnectionWithMethodClass connectionWithMethodClass in connWithMethodClasses)
    {
        SystemLogger.Instance.WriteDebug(string.Format("Dependent Authentication Connection - {0}: {1}", connectionWithMethodClass.EntityIdentifier, connectionWithMethodClass.MethodClass));
    
        if (requestedAssuranceLevel == connectionWithMethodClass.MethodClass)
        {
            matchConditionConnections.Add(connectionWithMethodClass.AuthenticationConnection);
        }
    }
    
    return matchConditionConnections;
    

    Customize second factor authentication policy script

    Script usage

    You can use a script of this type to customize the second factor policy of an Identity Provider.

    Script type Customize second factor authentication

    Script input parameters

    Name Type
    Rules PolicyRules

    Here is the PolicyRules class:

    PolicyRules

    You can learn more about Policy script here

    Example scripts

    • Apply the policy that requires the first factor Assurance level
    {
        Rules.ApplyExpression(EvaluateAssuranceLevel);
    }
    
    #region additional methods
    public bool EvaluateAssuranceLevel(RuleContext ruleContext)
    {
        var assuranceLevel = ruleContext.FirstFactorPrincipal.Claims.FirstOrDefault(c => c.Type == "dk:gov:saml:attribute:AssuranceLevel");
        return assuranceLevel != null;
    }
    #endregion additional methods
    

    Note that #region additional methods and #endregion additional methods are required when you need to split your script into smaller functions.

    Policy that specifies whether a user is allowed to register an MFA method

    Script usage

    You can use a script of this type to to control the conditions in which your users can register their second factor methods and log on.

    MFA script policy

    Script input parameters

    Name Type
    Rules PolicyRules

    Example scripts

    Check out the guide on Conditional access policy.

    Policy that specifies whether a token can be issued for a specific login

    Script usage

    You can use a script of this type to customize whether a token can be issued for a specific login.

    Token issuance script policy

    Script input parameters

    Name Type
    Rules PolicyRules

    Example scripts

    Check out the guide on How to write Token issuance access policy scripts

    Policy that specifies whether an authentication request should be processed or rejected

    Script usage

    You can use a script of this type to customize whether an authentication request should be processed or rejected.

    authentication request script policy

    Script input parameters

    Name Type
    Rules PolicyRules

    Example scripts

    Check out the guide on How to write authentication requests access policy scripts

    Claims transformations

    Script usage

    This script type is similar to the existing Scripting claims transformation but has more advanced features such as additional namespaces and references. After defining a script, you can use it for a Scripting claims transformation.

    Script type Claim Transformations

    Script input parameters

    Name Type
    claimsPrincipal ClaimsPrincipal
    claimDefinitionRepository ClaimDefinitionRepository
    nameIdService INameIdService
    httpContext HttpContextBase
    claimTransformationPipelineContext IClaimTransformationPipelineContext

    Example scripts

    • An example of script claims transformation to manipulate claims on the claimsPrincipal
    var requestInformation = (RequestInformation)claimTransformationPipelineContext.RequestInformation;
    var temporaryProtocolContext = requestInformation.LoginContext;
    if (temporaryProtocolContext.TwoFactorContextModel.UseTwoFactor)
    {
        var uuidClaim = claimsPrincipal.FindFirst("https://data.gov.dk/model/core/eid/professional/uuid/persistent");
        if (uuidClaim != null)
        {
            Issue("i-want-this-type", uuidClaim.Value);
            Remove("https://data.gov.dk/model/core/eid/professional/uuid/persistent");
        }
    }
    

    Check out the Scripting claims transformation for more information.

    Home realm discovery

    Script usage

    This script type is similar to the existing Scripting HRD but has more advanced features such as additional namespaces and references. After defining a script, you can use it for a Scripting HRD.

    Script Hrd

    Script input parameters

    Name Type
    controllerContext ControllerContext
    protocolConnection IProtocolConnection
    authenticationConnections IList<IAuthenticationConnection>
    loginContext SessionLoginContext

    Return value

    This kind of script requires to return an ASP.NET ActionResult

    Example scripts

    • A simple script to show an error page if the HRD can not find an expected Identity provider
    if (authenticationConnections.Count != 1 && !string.IsNullOrEmpty(controllerContext.HttpContext.Request.Params.Get(WhrParameter.ParameterName)))
    {
        var result = new ViewResult
        {
            ViewName = "HRDNoIdentityProviderDetermined",
            ViewData = {
                Model = new HRDNoIdentityProviderDeterminedViewModel
                {
                    CustomTitle = string.Empty,
                    CustomMessage = string.Empty
                }
            }
        };
        return result;
    }
    
    return null;
    

    Check out the Scripting home realm discovery rule for more information.

    Customize an AuthnRequest that is sent to an upstream SAML Identity Provider

    Script usage

    You can use a script of this type to customize the AuthnRequest before sending it to the upstream Identity Provider.

    custom-authnrequest-to-upstream-idp

    Script input parameters

    Name Type
    authnRequest AuthnRequest
    httpContext HttpContextBase
    endpointContext IEndpointContext
    logOnConfig SamlSignOnConfigurationSection
    samlAuthnRequestInformation SamlAuthnRequestInformation

    Example scripts

    Check out the guide on How to customize AuthnRequest by scripting for examples.

    Map authentication context method class of the second factor to a desired value

    Script usage

    You can use a script of this type to customize authentication context method class of the second factor to a desired value. The script is configured for the Identity Provider. map authentication context method class of the second factor to a desired value

    Script input parameters

    Name Type
    claimsPrincipal ClaimsPrincipal
    runtimeOptions RuntimeOptions
    temporaryProtocolContext SessionLoginContext

    Example scripts

    • Set custom second factor authentication context method class to claimsPrincipal
    claimsPrincipal.SetSecondFactorAuthenticationContextMethodClass("https://data.gov.dk/concept/core/nsis/loa/Substantial");
    claimsPrincipal.SetComparableSecondFactorAuthenticationContextClass(3);
    

    Select second factor methods that users can use

    Script usage

    You can use a script of this type to customize second factor methods that users can use. The script is configured for OTP authentication connection. Select second factor methods that users can use

    Script input parameters

    Name Type
    requestedAuthenticationContextModel RequestedAuthenticationContextModel
    context ControllerContext
    otpOptions OtpOptions
    orderOfFactors string[]
    tokenProviders IList<IUserTwoFactorTokenProvider>

    Return value

    This script must return a OtpMethodsByRequestedAuthenticationContextClass object.

    Example scripts

    • Picking an OTP method based on the requested authentication context method class
    OtpMethodsByRequestedAuthenticationContextClass otpMethod = new OtpMethodsByRequestedAuthenticationContextClass();
    Uri requestedAuthnContextClass = requestedAuthenticationContextModel.RequestedAuthenticationContextClass.FirstOrDefault();
    otpMethod.RequestedAuthenticationContextClass = requestedAuthnContextClass != null ? requestedAuthnContextClass.ToString() : string.Empty;
    SystemLogger.Instance.WriteInformation("Requested authentication context class is: " + otpMethod.RequestedAuthenticationContextClass);
    switch (otpMethod.RequestedAuthenticationContextClass)
    {
        case "urn:dk:gov:saml:attribute:AssuranceLevel:4":
            otpMethod.Methods = new List<OtpType> { OtpType.WebAuthn }; 
            break;
        case "urn:dk:gov:saml:attribute:AssuranceLevel:3":
            otpMethod.Methods = new List<OtpType> { OtpType.Authenticator }; 
            break;
        default:
            otpMethod.Methods = new List<OtpType> { OtpType.Email, OtpType.Sms, OtpType.OS2faktor, OtpType.Authenticator, OtpType.Device, OtpType.WebAuthn };
            break;
    };
    return otpMethod;
    

    Validate authentication context class that is sent via an Authorization request from an OAuth/OIDC client application

    Script usage

    You can use a script of this type to validate authentication context class that is sent via an Authorization request from an OAuth/OIDC client application

    Script type Validate authentication context class that is sent via an Authorization request from an OAuth/OIDC client application

    Script input parameters

    Name Type
    httpContext HttpContextBase
    request OpenIdConnectRequest
    oauthRequestInformation OAuthRequestInformation
    configSection OAuthMetadataConfigurationSection
    requestedAuthenticationContextModel RequestedAuthenticationContextModel

    Example scripts

    // Validate the authentication context
    
    var acrValues = request.AcrValues;
    SystemLogger.Instance.WriteInformation(string.Format("Authentication Context: {0}", acrValues));
    
    if (acrValues != null && acrValues.Contains("urn:dk:gov:saml:attribute:AssuranceLevel:2"))
    {
        throw new ArgumentException("urn:dk:gov:saml:attribute:AssuranceLevel:2");
    }
    

    Customize step-up behavior of an OAuth/OIDC client application

    Script usage

    You can use a script of this type to customize the step-up behavior of an OAuth/OIDC client application

    Script type Customize step-up behavior of an OAuth/OIDC client application

    Script input parameters

    Name Type
    httpContext HttpContextBase
    openIdConnectRequest OpenIdConnectRequest
    oauthRequestInformation OAuthRequestInformation
    configSection OAuthMetadataConfigurationSection
    reusableContext PassiveProtocolContext
    requestedAuthenticationContextModel RequestedAuthenticationContextModel
    supportsScope bool

    Example scripts

    string contextId = httpContext.Items[ProtocolConnectionContextItems.ContextIdKey] as string;
    var temporaryProtocolContext = oauthRequestInformation.LoginContext; 
    if (reusableContext != null && oauthRequestInformation.IsSignOnRequest)
    {
        var authenticationConnectionId = reusableContext.Principal.GetAuthenticationConnectionId();
        SystemLogger.Instance.WriteDebug("Set ReuseAuthenticationConnectionId = {0} and IsForcingAuthnDueToScopingOrStepUp = true", authenticationConnectionId);
        ForceAuthenticationAndReuseIdentityProvider(reusableContext, temporaryProtocolContext);
        return;
    }
    
    if (reusableContext == null && requestedAuthenticationContextModel.AuthnRequestHasRequestedAuthnContext)
    {
        SystemLogger.Instance.WriteDebug("AuthnRequestSignOnRequestArrivedObserver: reusableContext is null. Set IsForcingAuthnDueToScopingOrStepUp = true");
        temporaryProtocolContext.IsForcingAuthnDueToStepUp = true;
    }          
    
    #region additional methods
    private static void ForceAuthenticationAndReuseIdentityProvider(PassiveProtocolContext reusableContext, SessionLoginContext temporaryProtocolContext)
    {
        SystemLogger.Instance.WriteDebug("ForceAuthenticationAndReuseIdentityProvider");
        temporaryProtocolContext.ReuseAuthenticationConnectionId = reusableContext.Principal.GetAuthenticationConnectionId();
        temporaryProtocolContext.IsForcingAuthnDueToStepUp = true;
    }
    #endregion additional methods
    
    

    Select which Identity Providers an OAuth/OIDC client application can use (connection dependency customization)

    Script usage

    You can use a script of this type to specify which Identity Providers that an OAuth/OIDC client application can use. This script overrides the default behavior which uses the connection dependency list.

    Script type Select which Identity Providers an OAuth/OIDC client application can use (connection dependency customization)

    Script input parameters

    Name Type
    connWithMethodClasses AuthenticationConnectionWithMethodClass
    requestedAuthenticationContextModel RequestedAuthenticationContextModel
    httpContext HttpContextBase
    loginContext SessionLoginContext

    Return value

    This scripting requires to return a list of AuthenticationConnection.

    Example scripts

    // Take 2 AuthenticationConnection from the list AuthenticationConnectionWithMethodClass
    
    return connWithMethodClasses.Select(x => x.AuthenticationConnection).Take(2).ToList();
    
    

    Validate authentication context class that is returned from an upstream OAuth/OIDC Identity Provider

    Script usage

    You can use a script of this type to validate authentication context class that is returned from an upstream OAuth/OIDC Identity Provider

    Script type Validate authentication context class that is returned from an upstream OAuth/OIDC Identity Provider

    Script input parameters

    Name Type
    oauthTokenResponse OAuthTokenResponse
    httpContext HttpContextBase
    requestInformation RequestInformation
    authConfig OAuthProviderConnectionConfigurationSection

    Example scripts

    SystemLogger.Instance.WriteDebug("Validate authentication context class that is returned from an upstream OAuth/OIDC Identity Provider");
     
    var responseAccessToken = oauthTokenResponse.AccessToken;
     
    SystemLogger.Instance.WriteDebug("oauthTokenResponse.AccessToken: {0}", oauthTokenResponse.AccessToken);
     
    var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
    var jsonTokenSecurity = jwtSecurityTokenHandler.ReadToken(responseAccessToken.TrimStart()) as JwtSecurityToken;
    

    Customize authentication context class that is sent via an Authorization request to an upstream OAuth/OIDC Identity Provider

    Script usage

    You can use a script of this type to customize authentication context class that is sent via an Authorization request to an upstream OAuth/OIDC Identity Provider.

    Script type Customize authentication context class that is sent via an Authorization request to an upstream OAuth/OIDC Identity Provider

    Script input parameters

    Name Type
    httpContext HttpContextBase
    requestInformation RequestInformation
    authConfig OAuthProviderConnectionConfigurationSection

    Return value

    This scripting requires to return a string of authentication context class values.

    Example scripts

    // Return the authentication context class value
    
    return "urn:dk:gov:saml:attribute:AssuranceLevel:2";
    
    

    Customize an Authorization request that is sent to an upstream OAuth/OIDC Identity Provider

    Script usage

    You can use a script of this type to cutomize the content of an Authorization request that is sent to an upstream OAuth/OIDC Identity Provider.

    Script type Customize an Authorization request that is sent to an upstream OAuth/OIDC Identity Provider

    Script input parameters

    Name Type
    parameters Dictionary<string, string>
    httpContext HttpContextBase
    requestInformation RequestInformation
    authConfig OAuthProviderConnectionConfigurationSection

    Return value

    This scripting requires to return a Dictionary<string, string> of authorization request.

    Example scripts

    // Customize Authorization request dictionary
    
    if (parameters.ContainsKey("acr_values"))
    {
        parameters["acr_values"] += " urn:dk:gov:saml:attribute:AssuranceLevel:1";
    }
    else
    {
        parameters["acr_values"] = "urn:dk:gov:saml:attribute:AssuranceLevel:1";
    }
    
    return parameters;
    

    Generic provider

    You can use a script of this type to create a credentical validator for a Generic Provider. Learn more about Scripting Generic provider here.

    Identity Provider interceptor

    You can use a script of this type to create an interceptor for a Identity Provider. Learn more about Identity Provider scripting interceptor here.

    Service Provider interceptor

    You can use a script of this type to create an interceptor for a Service Provider. Learn more about Service Provider scripting interceptor here.

    Syntax

    To reference a script defined in the Script library, you can use the following syntax:

    UseScriptLibrary::{name-of-your-script-library}
    

    For example:

    UseScriptLibrary::CustomizeClaimsTransformation
    

    Syntax to apply a script library

    Note that you cannot append more code after UseScriptLibrary::{} because Identify treats everything after the "::" portion as a part of the script name

    Incorrect syntax to apply a script library

    Additional assembly references

    Normal scripting features have a fixed set of referenced assemblies. With Script library, you can add references to additional assemblies. Note that your custom assembly references must either exist in the [your tenant folder]\Admin\bin and [your tenant folder]\Runtime\bin folders or in GAC.

    Warning: due to Identify's caching mechanism, making changes to the Additional assembly references setting only does not force a cache reload on Identify runtime. To force cache reload, you can add a space character at the end of the script and save.

    Syntax:

    name-of-the-file.dll
    

    For example:

    Safewhere.External.dll
    

    Additional assembly references syntax

    Additional namespaces

    Warning: due to Identify's caching mechanism, making changes to the Additional assembly references setting only does not force a cache reload on Identify runtime. To force cache reload, you can add a space character at the end of the script and save.

    Like additional references, you can also specify additional namespaces for your scripts.

    Missing an additional namespace

    Provided an invalid namespace

    Syntax:

    using {your-additional-namespace};
    

    For example:

    using System.Collections;
    

    Provided a valid namespace

    Some very common .NET namespaces and Identify's namespaces have been added by default already. You can find that list below:

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Reflection;
    using System.Security.Claims;
    using System.Text;
    using System.Web;
    using System.Web.Mvc;
    using System.Xml;
    using System.IO;
    using System.IdentityModel;
    using System.IdentityModel.Tokens;
    using Safewhere.ModelFoundation.Kernel;
    using Safewhere.ModelFoundation.Kernel.CommonLogging;
    using Safewhere.ServiceProvider.Xml.RequestTypes;
    using Safewhere.IdentityProviderModel;
    using Safewhere.IdentityProviderModel.ContextualClaimTransformation;
    using Safewhere.IdentityProviderModel.Claims;
    using Safewhere.IdentityProviderModel.PolicyScript;
    using Safewhere.IdentityProviderModel.SessionState;
    using Safewhere.IdentityProvider.RuntimeModel;
    using Safewhere.IdentityProvider.Saml2.Authentication;
    using Safewhere.IdentityProvider.Saml2.Protocol;
    using Safewhere.IdentityProvider.Saml2;
    using Safewhere.IdentityModel.Core;
    using Safewhere.ServiceProvider.ServiceProviderConstants;
    using Safewhere.IdentityProvider.Otp;
    using Safewhere.IdentityProviderModel.DomainEvent;
    

    Note that, for the "full class script" such as Generic provider or interceptor scripts, you can use extra using statements at the begin of the script:

    using statements in full class script

    Delete a script library that is in use

    You cannot delete a script library that is currently in use:

    Script library in use cannot be deleted

    Debug information

    A script can trigger an error when applied during runtime. To pinpoint the specific line of code responsible for the error, you can enable debug information by adding a key to the web.config file in the Runtime.

    <add key="KeepCompileFiles" value="true"/>
    

    For example:

    Debug information

    In this example, the temporary script file 'yqjmhqk3.0.cs' is retained, and "Debug information" is enabled to precisely identify the line of code responsible for the error.

    Please be aware that this key is intended solely for debugging purposes, and it should be removed promptly after completing your debugging tasks.

    Back to top Generated by DocFX