Handle SoapException 300 „BadAuthenticationToken“ in Vault Extensions

Did you or your customers ever run into a SoapException 300 when using a custom command of a Vault Add-In you have developed? Usually, you should not see this exception unless you call an “iisreset” on the server. By default the authentication ticket that is used for initializing the WebServiceManager or IExplorerUtils becomes invalid after 29 days. That’s a rather long vacation and not everybody keeps Vault Explorer running for such a long time.

But probably on the customer site the “Recycling Regular Time Interval” is set to a much smaller value. For more details see: http://crackingthevault.typepad.com/crackingthevault/2009/04/badauthenticationtoken-300.html

Anyway, a custom command should behave correctly when this exception occurs.

First of all, can we probably avoid this exception?
Typically, we’re using the WebServiceManager class for web service calls or sometimes the IExplorerUtil interface for other useful functions. This is how the instances of these classes can be initialized:

private WebServiceManager _webSvcMgr;
private IExplorerUtil _explorerUtil;

void IExtension.OnLogOn(IApplication application)
{
    InitializeWebServiceManager(application);
}

void InitializeWebServiceManager(IApplication application)
{
    if (_webSvcMgr != null)
        _webSvcMgr.Dispose();

    // Use the IApplication object to create IExplorerUtil object.
    _explorerUtil = ExplorerLoader.GetExplorerUtil(application);

    // Use the IApplication object to create a credentials object.
    var cred = new UserIdTicketCredentials(
        application.VaultContext.RemoteBaseUrl.ToString(),
        application.VaultContext.VaultName,
        application.VaultContext.UserId,
        application.VaultContext.Ticket);

    // Use the credentials to create a new WebServiceManager object.
    _webSvcMgr = new WebServiceManager(cred);
}

The WebServiceManager allows automatic re-signin which takes care of the SoapException 300. But only if the credentials provided support re-signin. UserIdTicketCredentials does not. IExplorerUtil also does not support re-signin.

So, initializing the WebServiceManager only once in the function OnLogOn() is probably not the best idea.
When the custom command is invoked a CommandItemEventArgs object is passed in. This provides the IApplication object that can be used to initialize the WebServiceManager every time a user runs your custom command:

void cOCmdItemExecute(object sender, CommandItemEventArgs e)
{
    try
    {
        IApplication application = e.Context.Application;
        InitializeWebServiceManager(application);
        …

Unfortunately, this doesn’t avoid SoapException 300 for all cases. If the user calls the custom command (e.g. from a context menu) after the timeout on an already selected item in a list view, the IApplication object that gets passed in does not have a valid authentication ticket.

That means we cannot avoid the exception and there is also no way to do the re-signin within our custom command. Therefore, we need to catch the exception and tell the user to perform the operation again. To make sure it runs the next time a refresh is required by setting the ForceRefresh property of the context to true. This causes the Vault Explorer to re-signin and calling the OnLogOn() function for each Vault Add-In again:

void cOCmdItemExecute(object sender, CommandItemEventArgs e)
{
    try
    {
        IApplication application = e.Context.Application;
        InitializeWebServiceManager(application);

        Folder rootFolder = _webSvcMgr.DocumentService.GetFolderRoot();
    }
    catch (SoapException se)
    {
        if (se.Detail["sl:sldetail"]["sl:errorcode"].InnerText.Trim() == "300")
        {
            MessageBox.Show("Please refresh and try performing the operation again!");
            e.Context.ForceRefresh = true;
        }
    }
}
This entry was posted in Vault API and tagged , . Bookmark the permalink.

One Response to Handle SoapException 300 „BadAuthenticationToken“ in Vault Extensions

  1. Jan Liska says:

    Another option how to force re-sign from custom command is to use IApplication.RefreshSecurityContext method.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s