Dynamics CRM插件如何跨执行存储全局变量(如OAuth令牌)
Dynamics CRM插件跨执行存储OAuth令牌的可行方案
首先明确:SharedVariables的作用范围仅限同一次插件执行会话——比如同一个事件触发的多个插件步骤之间传递临时数据,完全无法跨不同时间的插件执行存储内容,你用它失败是符合预期的。
下面是几种能实现跨执行存储令牌的方案:
1. 自定义实体存储(最通用方案)
专门创建一个自定义实体(比如命名为OAuth令牌存储),设计以下核心字段:
- 令牌内容(单行文本/多行文本,视令牌长度而定)
- 过期时间(日期时间)
- 标识字段(比如API名称、租户ID,区分不同场景的令牌)
插件执行逻辑:
- 先查询该实体,过滤出对应API的未过期令牌
- 如果找到有效令牌,直接使用;如果没有或已过期,重新获取令牌后,用
Upsert操作更新或创建记录存储
示例代码片段:
// 构建查询,查找目标API的未过期令牌 var tokenQuery = new QueryExpression("new_oauthtokenstore") { ColumnSet = new ColumnSet("new_tokencontent", "new_expirytime"), Criteria = new FilterExpression { Conditions = { new ConditionExpression("new_apiname", ConditionOperator.Equal, "YourTargetAPI"), new ConditionExpression("new_expirytime", ConditionOperator.GreaterThan, DateTime.UtcNow) } } }; var tokenResults = service.RetrieveMultiple(tokenQuery); string validToken = null; if (tokenResults.Entities.Any()) { // 读取已存储的有效令牌 var tokenRecord = tokenResults.Entities.First(); validToken = tokenRecord.GetAttributeValue<string>("new_tokencontent"); } else { // 重新获取OAuth令牌 var newTokenData = FetchNewOAuthToken(); validToken = newTokenData.TokenValue; // 存储新令牌到自定义实体 var tokenEntity = new Entity("new_oauthtokenstore") { ["new_apiname"] = "YourTargetAPI", ["new_tokencontent"] = validToken, ["new_expirytime"] = newTokenData.ExpiryDateTime }; // 使用Upsert避免重复创建 service.Upsert(tokenEntity); } // 使用validToken调用目标API CallTargetAPI(validToken);
注意:如果存在并发执行的情况,建议加事务逻辑或使用乐观锁,避免重复获取令牌。
2. 沙盒插件专用缓存
如果你的插件运行在沙盒隔离模式下,可以使用IPluginExecutionContext.PluginCache属性:
- 该缓存是按插件类型+组织隔离的,默认有效期24小时,也可以自定义过期时间
- 执行逻辑:先从
PluginCache读取令牌并检查过期时间;无效则重新获取,再写入缓存
示例代码片段:
var cache = context.PluginCache; string tokenKey = "YourTargetAPIToken"; OAuthToken storedToken = null; // 尝试从缓存读取 if (cache.Contains(tokenKey)) { storedToken = JsonConvert.DeserializeObject<OAuthToken>(cache[tokenKey].ToString()); if (storedToken.ExpiryTime > DateTime.UtcNow) { // 使用缓存的有效令牌 validToken = storedToken.Token; } } // 缓存无有效令牌,重新获取并写入 if (validToken == null) { var newToken = FetchNewOAuthToken(); validToken = newToken.TokenValue; cache.Add(tokenKey, JsonConvert.SerializeObject(newToken), newToken.ExpiryTime); }
注意:这个方案仅适用于沙盒环境,且缓存可能被系统回收,必须做好降级逻辑(缓存失效时重新获取令牌)。
3. Azure Key Vault存储(高安全场景)
如果你的环境已集成Azure,可以将令牌存储在Azure Key Vault中:
- 利用Key Vault的秘密存储功能,设置秘密的过期时间
- 插件通过Azure AD身份验证访问Key Vault,读取秘密;若已过期,重新获取令牌后更新Key Vault中的秘密
该方案优势是安全性高,无需在CRM实体中存储敏感数据,但需要额外配置Azure资源和权限。
内容的提问来源于stack exchange,提问作者Charles Boyung
相关产品推荐
相关产品推荐

