EPR类企业管理系统

在我们现有系统基础上或全新开发,提供定制服务
为您的企业高效快速实施ERP,WMS,MES,CRM管理系统
全面管控物料仓库、销售业务、采购业务、仓库业务
生产过程、质量检验、组织架构、业务报表


定制
QQ:460-3528

开发
QQ群:3360-90194

源码
微信:136-3650-3721

中间层安全-WCF服务

重点

本主题演示了可由解决方案向导自动生成的代码。如果要在现有XAF解决方案中实现演示的功能,请继续。如果要创建新的XAF解决方案,请改用向导。

当安全性引擎在客户端应用程序中运行时,数据库将公开给客户端工作站。最终用户可以在应用程序的配置文件中看到连接字符串,并可以使用它直接访问数据库表,而无需绕过安全引擎。本主题演示如何在应用程序和数据库服务器之间放置中间层应用程序服务器。服务器将使用Windows Communication Foundation(WCF)。服务器将过滤掉受限制的数据,并且客户端可能无法直接访问数据库服务器,甚至可能不知道其实际的网络位置。下图说明了这种配置。

MiddleTier_Diagram

注意
  • 中间层不支持实体框架数据模型,仅用于XPO。
  • 从逻辑,维护和性能的角度来看,中间层对于ASP.NET或移动应用程序没有多大意义。这些应用程序默认为客户端-服务器。

  • 中间层和数据库引擎可以物理上位于同一服务器上。从技术上讲,应用程序服务器也可以与应用程序本身一起安装在最终用户工作站上,但是从安全角度来看,这种配置没有任何意义。
  • 中间层应用程序服务器是常规的WCF服务,您可以使用标准方法来保护和部署它(请参阅“编程WCF安全性”)。
提示

DevExpress代码示例数据库(http://www.devexpress.com/example=E4036)中提供了完整的示例项目。

创建和配置服务器

调试时,使用作为简单控制台应用程序实现的Application Server会很方便。稍后,您将能够将其转换为Windows服务,该服务可以部署在生产环境中(请参阅将应用程序服务器作为Windows服务运行)。要将Console Application Server项目添加到XAF解决方案中,请使用DevExpress v 19.2 XAF Solution Wizard的Application Server Project模板。

  • 解决方案资源管理器中右键单击解决方案。
  • 在调用的上下文菜单中,选择添加|。新项目...
  • 选择DevExpress v 19.2 XAF解决方案向导模板。
  • 指定项目名称(例如MySolution.AppServer),然后单击OK
  • 在解决方案向导中选择Application Server Project,然后单击Next
  • 指定您使用的身份验证类型(标准Active Directory),选择WCF服务数据库安全性类型,然后单击完成

创建的应用程序服务器将直接连接到应用程序的数据库,并处理初始数据库的创建和更新。因此,应用程序服务器必须知道客户端应用程序名称,安全系统设置,客户端应用程序中使用的模块以及数据库连接字符串。要配置新添加的服务器,请修改以下两个文件:Program.csProgram.vb)和App.config

下面是对Program.csProgram.vb)文件的必要修改的列表。

  • ServerApplication.ApplicationName属性值。它应该与您的客户端应用程序名称相同(即XafApplication.ApplicationName);
  • ServerApplication.Modules集合。它应包含客户端应用程序直接引用的模块。若要查看所需的客户端应用程序模块,请参阅WinApplication / WebApplication后代中的InitializeComponent方法代码。添加所需的模块项目引用(例如MySolution.Module.Win和MySolution.Module.Web)。右键单击新创建的应用服务器项目,然后选择添加引用...。在调用的对话框中,切换到“项目”选项卡,选择模块项目,然后单击“确定”。将平台相关的模块添加到ServerApplication.Modules收藏。不需要添加与平台无关的模块,因为与平台无关的模块包括它。
  • 服务器要侦听的网络端口。此设置是由所提供的ServiceHost.AddServiceEndpoint在该方法中的地址参数。

下面的代码段说明了Program.csProgram.vb)文件中的这些修改。

static void Main(string[] args) {
    try {
        // ...
        ServerApplication serverApplication = new ServerApplication();
        serverApplication.ApplicationName = "MySolution";

        serverApplication.Modules.BeginInit();
        serverApplication.Modules.Add(new DevExpress.ExpressApp.Security.SecurityModule());
        serverApplication.Modules.Add(new MySolution.Module.Win.MySolutionWindowsFormsModule());
        serverApplication.Modules.Add(new MySolution.Module.Win.MySolutionAspNetModule());
        serverApplication.Modules.EndInit();

        // ...
        Func dataServerSecurityProvider = () => {
            SecurityStrategyComplex security = new SecurityStrategyComplex(
                typeof(PermissionPolicyUser), typeof(PermissionPolicyRole), new AuthenticationStandard());
            security.SupportNavigationPermissionsForTypes = false;
            return security;
        };
        serviceHost = new WcfXafServiceHost(connectionString, dataServerSecurityProvider);
        serviceHost.AddServiceEndpoint(typeof(IWcfXafDataServer), 
            WcfDataServerHelper.CreateNetTcpBinding(), "net.tcp://localhost:1451/DataServer");
        serviceHost.Open();
        // ...
    }
    catch(Exception e) {
        Console.WriteLine("Exception occurs: "   e.Message);
        Console.WriteLine("Press Enter to close.");
        Console.ReadLine();
    }
}
提示

请记住将必需的引用添加到模块项目中(例如,MySolution.Module.WinMySolution.Module.Web)。右键单击新创建的应用服务器项目,然后选择添加引用...。在调用的对话框中,切换到“项目”选项卡,选择模块项目,然后单击“确定”。

注意
  • 如果使用自定义权限请求自定义登录参数或其他要序列化的类型(例如,非持久对象),请在初始化数据服务器之前使用静态WcfDataServerHelper.AddKnownType方法注册它们。在服务器端和客户端都注册了这些类型。不要使用此方法添加业务类
  • 如果要使用自定义Binding对象,请不要使用WcfDataServerHelper.CreateDefaultBinding方法。自己创建所需的Binding对象,并将其传递给ServiceHost.AddServiceEndpoint方法。
  • 使用AuthenticationActiveDirectory时,应在调用者的上下文(运行客户端应用程序的Windows帐户)中调用应用程序服务器的所有方法。有关如何完成此操作的详细信息,请参阅MSDN中的“远程处理中的WCF安全性的委派和模拟”文章,具体取决于所使用的传输技术。例如,对于WCF,您可以在服务代码中修改ServiceAuthorizationBehavior.ImpersonateCallerForAllOperations属性。

  • InstanceContext对象的范围内,不会更改安全系统环境。将为每个新的InstanceContext对象创建一个新的Security System实例(包括来自数据库的更新权限,新的清除的缓存等)。默认情况下,WCF服务器使用InstanceContextMode.PerSession模式。安全系统为每次登录创建一个新会话,并在每次注销时进行处理。如果要更改InstanceContextMode,请使用另一个带有InstanceContextMode参数的WcfXafServiceHost构造函数。

最后,在App.config文件中提供将用于访问数据库服务器的连接字符串。

<?xml version="1.0"?>
<configuration>
  <connectionStrings>
    <add name="ConnectionString" connectionString=
        "Integrated Security=SSPI;Pooling=false;
        Data Source=.\SQLEXPRESS;Initial Catalog=MySolution" />
  </connectionStrings>
</configuration>

配置客户端

与客户端安全相反,我们将使用代码执行所有配置,而无需使用应用程序设计器。要配置Windows Forms应用程序,请添加对System.ServiceModel.dllDevExpress.ExpressApp.Security.v 19.2 .dll程序集的引用,然后修改Program.csProgram.vb)文件。

using System.ServiceModel;
using DevExpress.ExpressApp.Security.ClientServer.Wcf;
// ...  
string connectionString = "net.tcp://localhost:1451/DataServer";
winApplication.DatabaseUpdateMode = DatabaseUpdateMode.Never;
WcfSecuredClient wcfSecuredClient = new WcfSecuredClient(WcfDataServerHelper.CreateNetTcpBinding(), new EndpointAddress(connectionString));
MiddleTierClientSecurity security = new MiddleTierClientSecurity(wcfSecuredClient);
security.IsSupportChangePassword = true;
winApplication.Security = security;
winApplication.CreateCustomObjectSpaceProvider  =
    delegate(object sender, CreateCustomObjectSpaceProviderEventArgs e) {
        e.ObjectSpaceProvider = new MiddleTierServerObjectSpaceProvider(wcfSecuredClient);
    };
winApplication.Setup();
winApplication.Start();
wcfSecuredClient.Dispose();

ServerSecurityClient.IsSupportChangePassword属性指示是否用户密码可以通过改变ChangePasswordByUserResetPasswords操作。如果在服务器端使用AuthenticationStandard身份验证,则将此属性设置为true。如果正在使用AuthenticationActiveDirectory,则无需初始化IsSupportChangePassword属性,因为其默认值为false。请注意,此设置仅影响ChangePasswordByUserResetPasswords操作的可见性,而不授予用户的写权限。StoredPassword属性。创建相应的成员级别权限,以允许非管理用户更改其密码。

注意

调试时,服务器主机名在连接字符串中为“ localhost”。根据服务器端设置更改端口号。您还可以使用ConfigurationManager对象从配置文件中读取连接字符串(如在默认应用程序项目中所做的那样)。在此,为简单起见,对连接进行了硬编码。

使用应用程序服务器时,兼容性检查在服务器端执行。XafApplication.DatabaseVersionMismatch事件发生时,您应该无条件抛出异常。如下编辑WinApplication.csWinApplication.vb)和WebApplication.csWebApplication.vb)文件。

public partial class MySolutionWindowsFormsApplication : WinApplication {
    //...
   private void MySolutionWindowsFormsApplication_DatabaseVersionMismatch(
        object sender, DevExpress.ExpressApp.DatabaseVersionMismatchEventArgs e) {
        throw new InvalidOperationException(
            "The application cannot connect to the specified database "  
            "because the latter does not exist or its version is older "  
            "than that of the application.");
        }
    }
}

在与平台无关的模块内注册安全性使用的类型。以以下方式编辑Module.csModule.vb)文件。

using DevExpress.Persistent.BaseImpl.PermissionPolicy;
// ...
public sealed partial class MySolutionModule : ModuleBase {
    // ...
    protected override IEnumerable<Type> GetDeclaredExportedTypes() {
        List<Type> result = new List<Type>(base.GetDeclaredExportedTypes());
        result.AddRange(new Type[] { typeof(PermissionPolicyUser), typeof(PermissionPolicyRole) });
        return result;
    }
}

编译上面的代码需要引用DevExpress.ExpressApp.Security.v 19.2程序集。

重点

应用程序服务器不会将当前使用的角色类型传递给客户端。这是设计的行为。这就是默认情况下“角色”导航项不可用的原因。若要添加它,请使用“将项目添加到导航控件”主题中描述的方法。(默认情况下,所需的列表视图标识符为“ PermissionPolicyRole_ListView”。)

运行服务器和客户端。

解决方案资源管理器中将Application Server项目设置为启动,然后运行服务器。您将看到带有以下输出的控制台窗口:

开始...

设置...

检查兼容性...

正在启动服务器...

服务器已启动。按Enter停止。

注意

如果还显示“ Windows安全警报”对话框,请在此对话框中单击“允许访问”

要运行客户端应用程序,请在解决方案资源管理器中右键单击该应用程序项目,然后选择“调试” |“调试”。启动新实例。下图说明了服务器和客户端。

ClientServer_Wcf_StandardAuth

在客户端应用程序中显示服务器端异常详细信息

出于调试目的,您可能希望启用将服务器错误信息传递到客户端的功能。这将允许您调试“由于内部错误服务器无法处理请求”之类的错误。通过以下方式修改ServiceHost对象的初始化。

WcfXafServiceHost serviceHost = new WcfXafServiceHost(connectionString, dataServerSecurityProvider);
ServiceDebugBehavior debug = serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
if(debug == null) {
    serviceHost.Description.Behaviors.Add(
    new ServiceDebugBehavior() { IncludeExceptionDetailInFaults = true });
}
else {
    if(!debug.IncludeExceptionDetailInFaults) {
        debug.IncludeExceptionDetailInFaults = true;
    }
}

仅在调试时使用此代码。在将服务部署到生产环境之前,请先删除它。有关详细信息,请参阅MSDN中的ServiceBehaviorAttribute.IncludeExceptionDetailInFaults属性主题。

故障排除

如果客户端出现“应用程序无法连接到指定的数据库”错误,请确保客户端和服务器具有相同的模块集。请参阅Visual Studio输出窗口内容,或查看客户端应用程序日志(eXpressAppFramework.log)。例如,以下消息指示SystemAspNetModule模块未添加到服务器的Modules集合中。(缺少的模块版本显示为“ 0.0.0.0”。)

模块'SystemAspNetModule'(DevExpress.ExpressApp.Web.v 19.2)。本地版本:19.2.7.0,数据库版本:0.0.0.0

若要解决此问题,请将该模块添加到ServerApplication.Modules集合中,如本主题的“创建和配置服务器”部分所示。

相关文章

转载保留此链接,注明出处