By Barbara Han
Sometimes an "Error 300 - BadAuthenticationToken" occurs when executing our program. What is the cause of this error and how can we handle it?
The server has a security feature introduced since Vault 2008. When users log in they get an encrypted security ticket. In Vault R5 this ticket will be valid forever. Starting from Vault 2008, the server is allowed to change its encryption key which effectively invalidates the security ticket. What this means for a client developer is that at any time, the user's security information could be suddenly invalidated. Almost every API call requires a security ticket so your program needs to handle the situation where the security ticket is invalid.
How to reproduce:
1 - Sign in to Vault through your application and do a couple of basic operations.
2 - Run "iisreset /restart" from the command line on the server. This will cause IIS to reset and the encryption key to change.
3 - Go back to your program. Everything that involves a Vault API call should now fail with the 300 error.
How to solve:
The best way to deal with this is for your application is to silently re-authenticate and re-run the API call. If all goes well the user will never know that an error occurred.
With Vault 2008 ~ 2010, you can leverage partial classes feature from .NET 2.0 to create a single choke point per service.
For each class you can create the following partial implementation:
C#:
namespace // TODO: set namespace same as service class
{
partial class DocumentServiceWse
{
protected new object[] Invoke(string methodName,
object[] parameters)
{
try
{
return base.Invoke(methodName, parameters);
}
catch (Exception ex)
{
string errorCodeString = GetErrorCodeString(ex);
if (errorCodeString != "300")
// TODO: handle or re-throw the error
}
// Ran into error 300.
// Log in again and re-run the command
try
{
// TODO: re-authenticate
return base.Invoke(methodName, parameters);
}
catch (Exception)
{
// TODO: handle or re-throw the error
}
}
}
}
VB.NET:
Namespace ' TODO: set namespace same as service class
Partial Class DocumentServiceWse
Protected Shadows Function Invoke(ByVal methodName As String,
ByVal parameters As Object()) As Object()
Try
Return MyBase.Invoke(methodName, parameters)
Catch ex As Exception
Dim errorCodeString As String = GetErrorCodeString(ex)
If (errorCodeString <> "300") Then
' TODO: Handle or re-throw the error
End If
End Try
' Ran into error 300
' Log in again and re-run the command
Try
' TODO: re-authenticate
Return MyBase.Invoke(methodName, parameters)
Catch
' TODO: Handle or re-throw the error
End Try
End Function
End Class
End Namespace
With Vault 2011 and afterward releases, you can use the Autodesk.Connectivity.WebServices.dll. Partial classes won't work with DLLs, so please use subclasses instead. For more details of Autodesk.Connectivity.WebServices.dll, please see:
http://justonesandzeros.typepad.com/blog/2010/04/autodeskconnectivitywebservicesdll.htm
There is another new dll “Autodesk.Connectivity.WebServicesTools.dll” having been added starting from Vault 2012. This DLL is a set of tools built on top of the WebServices DLL. The main tool is the WebServiceManager, which makes it easier to construct new IWebService objects, also adds the re-signin feature, which automatically logs your user back in if a timeout occurs, so the recommended way is to use WebServiceManager to take care of this issue.