2015-07-28 70 views
2

我有一个ODataController作为MEF插件实现。此控制器在启动时从服务器应用程序加载。我在服务器应用程序内创建了另外3个ODataController,它允许获取当前用户的Id,Permssions和角色(从ServerApplicationContext获取的信息)。在这些控制器中创建了一个服务引用,它允许将插件与服务器应用程序分离,以便我不需要引用插件中的ServerApplicationContext。 在插件/扩展程序如下服务引用将用于(静态类的方法实际上封装 - >服务将与团结,只要它的工作注入):在ODataController中使用服务引用无法在IIS上工作

Contracts.CurrentUserData.Administration _administrationService = new Contracts.CurrentUserData.Administration(new Uri(ConfigurationManager.AppSettings["A.Key"])); 
_administrationService.Credentials = CredentialCache.DefaultCredentials; 
_administrationService.CurrentUsers.ToList().First().Identity 

这一切都为正常工作只要应用程序没有直接从VS2013运行IIS。一旦应用程序部署到一个独立的IIS,以从控制器插入的服务引用调用抛出异常:

Microsoft.LightSwitch.Server: Unable to authenticate. Access is denied. 
    at Microsoft.LightSwitch.Utilities.ServerGenerated.Internal.ServerApplicationContextFactoryCore.AuthenticateUser() 
    at Microsoft.LightSwitch.Server.ServerApplicationContextFactory.CreateContext(ServerApplicationContextCreationOptions options) 
    at Microsoft.LightSwitch.Framework.Server.ServerApplicationContext`3.CreateContext() 
    at LightSwitchApplication.Controllers.CurrentUserPermissionsController.GetCurrentUserPermissions(ODataQueryOptions`1 queryOptions) 
Microsoft.Data.Services.Client: An error occurred while processing this request. 
    at System.Data.Services.Client.DataServiceRequest.Execute[TElement](DataServiceContext context, QueryComponents queryComponents) 
    at System.Data.Services.Client.DataServiceQuery`1.Execute() 
    at System.Data.Services.Client.DataServiceQuery`1.GetEnumerator() 
    at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) 
    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) 
    at ODataExtensions.CurrentUserDataHelper.GetPermissionsOfCurrentUser() 
    at ODataExtensions.CurrentUserDataHelper.HasCurrentUserPermission(String permissionId) 
    at ODataExtensions.Controllers.HealthChecksController.<GetHealthChecks>d__2.MoveNext() 

重要:的服务引用的URL配置正确。用于获取有关当前用户信息的ODataController可以访问,并返回正确的数据(如果直接访问它们)。一旦他们通过服务引用calld发生上述错误发生。

回答

1

下面的代码的问题是,DefaultCredentials表示当前运行该应用程序的安全上下文的系统凭据。

Contracts.CurrentUserData.Administration _administrationService = new Contracts.CurrentUserData.Administration(new Uri(ConfigurationManager.AppSettings["A.Key"])); 
_administrationService.Credentials = CredentialCache.DefaultCredentials; 
_administrationService.CurrentUsers.ToList().First().Identity 

在IIS Express上,应用程序在管理员的安全上下文中运行 - 与我用于本地测试的用户相同。在独立IIS实例上,应用程序正在用户IIS APPPOOL\DefaultAppPool的安全上下文中运行。

解决方案

为了解决我只好冒充服务引用调用问题。以下代码是从ODataController中调用的,因此可以从HttpContext获取模拟的用户身份。

public static String GetCurrentUserId() 
    { 
     var administrationService = GetServiceReferenceInstance(); 
     var identity = (WindowsIdentity)HttpContext.Current.User.Identity; 
     administrationService.Credentials = CredentialCache.DefaultCredentials; 
     using (var impersonationContext = identity.Impersonate()) 
     { 
      return administrationService.CurrentUsers.ToList().First().Identity; 
     } 
    } 

    private static Contracts.CurrentUserData.Administration GetServiceReferenceInstance() 
    { 
     return new Contracts.CurrentUserData.Administration(new Uri(ConfigurationManager.AppSettings["AKey"])); 
    } 
相关问题