我正在通过 BO SDK (.NET) 为 BusinessObjects 实现 Web GUI,并且需要一种在多个用户之间持久和共享身份验证令牌的方法。一个特定的业务要求是只有一次登录(在本例中是来自 ActiveDirectory 的服务帐户)。我最初登录没有问题,然后通过第一次登录生成的默认令牌执行后续登录。问题是,当使用令牌在第二次尝试登录时,令牌会被覆盖。
我需要一种方法来检查令牌是否有效,而无需完成覆盖原始令牌值的完整登录。我的计划是将令牌保存在缓存中,并在发出每个报告请求时通过 WCF 提供服务,只有在令牌不再有效时才重新生成令牌值。每个报告的最终请求是通过将令牌作为查询字符串参数包含在 OpenDocument url 中来完成的,以提供身份验证。
我可以使用以下代码通过令牌完成完整登录: //Original login SessionMgr ses = new SessionMgr(); EnterpriseSession es = ses.Logon(user, pass, server, type);
//Get the token
LogonTokenMgr myToken = es.LogonTokenMgr;
string BOToken = myToken.DefaultToken;
//Login with the generated token
EnterpriseSession esToken = ses.LogonWithToken(BOToken);
我找不到将原始令牌作为参数并确定它是否与有效的 BusinessObjects 会话相关联的方法。覆盖每次登录时的令牌(在使用 LogonWithToken 方法时发生)不是一种选择,因为它是一个多用户环境,并且覆盖会使先前的令牌/会话无效,如果用户依赖于无效的令牌,他们就会陷入困境.
有谁知道 BO SDK 库中的一种方法可以检查令牌的有效性而不覆盖它?我可以访问堆栈附带的所有 DLL...
更新:
由于 SDK 似乎缺少验证令牌的专用方法,因此我创建了一个有效的 HACK。创建有效令牌后,我将其放入缓存中,并通过尝试从缓存的令牌初始化 EnterpriseSession 在后续调用中“验证”它。如果会话创建失败,则假定令牌无效并生成一个新令牌并将其返回到缓存服务以进行存储(对不起,如果格式关闭 - 我是 markdown 新手):
希望有人为这个问题创建了一个“真正的”解决方案,但以下代码运行良好:
public static class BusinessObjectsAuth
{
public static string GetBOToken (string currentToken = null)
{
if (!ValidateToken(currentToken))
{
//This is aprt a custom encryption piece - needed unless you are comfortable storing pw in plain text in config file
Crypt decrypter = new Crypt();
//Generate a new token
SessionMgr ses = new SessionMgr();
EnterpriseSession es = ses.Logon(AppSettings.BusinessObjectsUser, decrypter.DecryptString(AppSettings.BusinessObjectsPass), AppSettings.BusinessObjectsUrl, "secWinAD");
LogonTokenMgr myToken = es.LogonTokenMgr;
//The token generated below is good on any client for an unlimited number of logins for 24 hours
//This may or may not be a good idea based on the security of your network
return myToken.CreateLogonTokenEx("", 1440, -1);
}
else
{
//If the token is still valild return it
return currentToken;
}
}
public static bool ValidateToken(string currentToken = null)
{
SessionMgr ses = new SessionMgr();
try
{
//Check to see if the token can be used for logon - close the session afterwards
EnterpriseSession es = ses.LogonWithToken(currentToken);
es.Logoff();
return true;
}
catch (Exception ex)
{
//This is a workaround for the fact that the BO SDK does not include a built in method for verifying
//that a token is valid - we can only assume it's a bad token if the logon attempt in the try block fails
string message = ex.Message;
return false;
}
}
}