0

我正在尝试使用 TFS 事件订阅服务通过 Web 界面动态创建订阅。订阅将转到一个中间帐户。出于我们的目的,我们将这两个帐户称为“非管理员用户”和“订阅存储”。

管理员可以为“订阅存储”帐户创建警报,订阅存储帐户可以为自己创建警报,但非管理员用户无法在存储帐户中创建订阅。我收到以下错误消息:

访问被拒绝:{user account name} 需要对资源 $SUBSCRIPTION 的以下权限:才能执行此操作:编辑

我正在使用的代码是:

IEventService eventService = (IEventService)this.tfsCollection.GetService(typeof(IEventService));
eventService.SubscribeEvent(userAccountIdentity.Sid, Strings.WorkItemChangedEvent, string.Format(Strings.Condition0, workItem.ToString(CultureInfo.InvariantCulture)), deliveryPreference, string.Format(Strings.AlertTag0, workItem.ToString(CultureInfo.InvariantCulture)));

请相信所有参数都是正确的,并且它们的值与本次讨论无关。:)tfsCollectionTfsTeamProjectCollection来自页面Connection.TeamProjectCollection属性的对象。

我的第一个想法是打破模拟,以便它使用服务帐户(在本例中为 NetworkService),因此我制作了一个扩展方法,它接受Action并在不模拟的情况下执行它,如下所示:

    public static void WithoutImpersonation(this Action actionToPerform)
    {
        using (var ctx = WindowsIdentity.Impersonate(IntPtr.Zero))
        {
            try
            {
                actionToPerform();
            }
            finally
            {
                ctx.Undo();
            }
        }
    }

这会在持续时间内正确中断模拟Action(检查WindowsIdentity.GetCurrentUser()返回 NetworkService 帐户而不是用户帐户),但仍然无法创建具有相同错误的事件订阅。的经过身份验证的用户TfsTeamProjectCollection也是 NetworkService 帐户。

4

1 回答 1

1

我解决了!事实证明我以错误的方式接近它。从实例化我的类的页面中,我必须使用EnterTfsImpersonationContext,然后查找存储帐户的标识并为该帐户创建一个新TfsTeamProjectCollection帐户。这解决了问题。

于 2012-07-04T20:52:43.703 回答