Version 17.2 has the updated Middle Tier Security implementation. Data is secured on the server, but permission information is passed to the client along with data, so that UI updates are done without extra requests and the client application works faster. When you create a new application with the Solution Wizard 17.2+, the wizard adds the new Middle Tier code automatically. However, if you want to get the benefits of the new approach for an existing project, you'll need to update the Middle Tier Security implementation in your code.
Follow the steps below to manually update the Middle Tier Security implementation in your existing project.
1. Server Application Modifications
In the Program.cs file, find this code:
C#QueryRequestSecurityStrategyHandler securityProviderHandler = delegate () {
SecurityStrategyComplex securityStrategyComplex = new SecurityStrategyComplex(typeof(PermissionPolicyUser), typeof(PermissionPolicyRole), new AuthenticationStandard());
securityStrategyComplex.SupportNavigationPermissionsForTypes = false;
return securityStrategyComplex;
};
SecuredDataServer dataServer = new SecuredDataServer(connectionString, XpoTypesInfoHelper.GetXpoTypeInfoSource().XPDictionary, securityProviderHandler);
ServiceHost serviceHost = new ServiceHost(new WcfSecuredDataServer(dataServer));
serviceHost.AddServiceEndpoint(typeof(IWcfSecuredDataServer), WcfDataServerHelper.CreateNetTcpBinding(), "net.tcp://127.0.0.1:1451/DataServer");
Visual BasicDim securityProviderHandler As QueryRequestSecurityStrategyHandler = Function()
Dim securityStrategyComplex As New SecurityStrategyComplex(GetType(PermissionPolicyUser), GetType(PermissionPolicyRole), New AuthenticationStandard())
securityStrategyComplex.SupportNavigationPermissionsForTypes = False
Return securityStrategyComplex
End Function
Dim dataServer As New SecuredDataServer(connectionString, XpoTypesInfoHelper.GetXpoTypeInfoSource().XPDictionary, securityProviderHandler)
Dim serviceHost As New ServiceHost(New WcfSecuredDataServer(dataServer))
serviceHost.AddServiceEndpoint(GetType(IWcfSecuredDataServer), WcfDataServerHelper.CreateNetTcpBinding(), "net.tcp://127.0.0.1:1451/DataServer")
…and replace it with the following:
C#Func<IDataServerSecurity> securityProviderHandler = () => new SecurityStrategyComplex(typeof(PermissionPolicyUser), typeof(PermissionPolicyRole), new AuthenticationStandard());
string serviceEndPoint = @"net.tcp://127.0.0.1:1451/DataServer";
ServiceHost serviceHost = new WcfXafServiceHost(connectionString, securityProviderHandler);
serviceHost.AddServiceEndpoint(typeof(IWcfXafDataServer), WcfDataServerHelper.CreateNetTcpBinding(), serviceEndPoint);
Visual BasicDim securityProviderHandler As Func(Of IDataServerSecurity) = _
Function() New SecurityStrategyComplex(GetType(PermissionPolicyUser), GetType(PermissionPolicyRole), New AuthenticationStandard())
Dim serviceEndPoint As String = "net.tcp://127.0.0.1:1451/DataServer"
Dim serviceHost As ServiceHost = New WcfXafServiceHost(connectionString, securityProviderHandler)
serviceHost.AddServiceEndpoint(GetType(IWcfXafDataServer), WcfDataServerHelper.CreateNetTcpBinding(), serviceEndPoint)
If your existing code uses the SecuredDataServer constructor with the committingDelegate parameter, replace it with the code provided in the How to use the custom CommittingDelegate with the new WcfXafServiceHost ticket.
If you use logging in an app server, you can switch the detail level of information written into an application's log file to the Verbose(4) level. With this level, all Security System loggers (Permission Processors, Middle Tier loggers, security rule loggers) are enabled automatically. For more information, see the Log Files article.
As an alternative, you can create a custom class derived from the WcfXafServiceHost class and override its GetInstanceCore method. In this method, return a WcfSecuredServerLogger instance with required parameters (e.g. you can pass your custom ILogger implementation in it). See the code below that illustrates it:
C#public class CustomWcfXafServiceHost : WcfXafServiceHost
{
...
protected override object GetInstanceCore(InstanceContext instanceContext, Message message, IDataLayer dataLayer, IDataServerSecurity serverSecurity, bool allowICommandChannelDoWithSecurityContext, InstanceContextMode contextMode)
{
return new WcfSecuredServerLogger(dataLayer, serverSecurity, allowICommandChannelDoWithSecurityContext, contextMode, Logger.Instance);
}
}
Visual Basic Public Class CustomWcfXafServiceHost
Inherits WcfXafServiceHost
...
Protected Overrides Function GetInstanceCore(instanceContext As InstanceContext, message As Message, dataLayer As IDataLayer, serverSecurity As IDataServerSecurity, allowICommandChannelDoWithSecurityContext As Boolean, contextMode As InstanceContextMode) As Object
Return New WcfSecuredServerLogger(dataLayer, serverSecurity, allowICommandChannelDoWithSecurityContext, contextMode, Logger.Instance)
End Function
End Class
2. Client WinForms Application Modifications
In the Program.cs file, find this code:
C#string connectionString = "net.tcp://127.0.0.1:1451/DataServer";
WcfSecuredDataServerClient clientDataServer = new WcfSecuredDataServerClient(WcfDataServerHelper.CreateNetTcpBinding(),
new EndpointAddress(connectionString));
ServerSecurityClient securityClient = new ServerSecurityClient(clientDataServer, new ClientInfoFactory());
securityClient.SupportNavigationPermissionsForTypes = false;
securityClient.IsSupportChangePassword = true;
winApplication.Security = securityClient;
winApplication.CreateCustomObjectSpaceProvider += delegate(object sender, CreateCustomObjectSpaceProviderEventArgs e) {
e.ObjectSpaceProvider = new DataServerObjectSpaceProvider(clientDataServer, securityClient);
};
Visual BasicDim connectionString As String = "net.tcp://127.0.0.1:1451/DataServer"
Dim clientDataServer As New WcfSecuredDataServerClient(WcfDataServerHelper.CreateNetTcpBinding(), New EndpointAddress(connectionString))
Dim securityClient As New ServerSecurityClient(clientDataServer, New ClientInfoFactory())
securityClient.SupportNavigationPermissionsForTypes = False
securityClient.IsSupportChangePassword = True
winApplication.Security = securityClient
AddHandler winApplication.CreateCustomObjectSpaceProvider, Sub(sender As Object, e As CreateCustomObjectSpaceProviderEventArgs) e.ObjectSpaceProvider = _
New DataServerObjectSpaceProvider(clientDataServer, securityClient)
…and replace it with the following:
C#string connectionString = @"net.tcp://127.0.0.1:1451/DataServer";
WcfSecuredClient client = new WcfSecuredClient(WcfDataServerHelper.CreateNetTcpBinding(), new EndpointAddress(connectionString));
winApplication.Security = new MiddleTierClientSecurity(client) { IsSupportChangePassword = true };
winApplication.DatabaseUpdateMode = DatabaseUpdateMode.Never;
winApplication.CreateCustomObjectSpaceProvider += delegate (object sender, CreateCustomObjectSpaceProviderEventArgs e) {
e.ObjectSpaceProviders.Add(new MiddleTierServerObjectSpaceProvider(client));
};
Visual BasicDim connectionString As String = "net.tcp://127.0.0.1:1451/DataServer"
Dim client As New WcfSecuredClient(WcfDataServerHelper.CreateNetTcpBinding(), New EndpointAddress(connectionString))
winApplication.Security = New MiddleTierClientSecurity(client) With {.IsSupportChangePassword = True}
winApplication.DatabaseUpdateMode = DatabaseUpdateMode.Never
AddHandler winApplication.CreateCustomObjectSpaceProvider, Sub(sender As Object, e As CreateCustomObjectSpaceProviderEventArgs) _
e.ObjectSpaceProviders.Add(New MiddleTierServerObjectSpaceProvider(client))
Additionally, replace this line:
C#clientDataServer.Close();
Visual BasicclientDataServer.Close()
…with the following:
C#client.Dispose();
Visual Basicclient.Dispose()
3. ASP.NET and Mobile Applications:
If you previously configured your ASP.NET or Mobile application to use the Middle Tier, this configuration will be incompatible with the server modifications described above. It is recommended to use the Integrated Mode instead of the Middle Tier in these applications. The Middle Tier does not make sense for an ASP.NET or Mobile application from the logical, maintenance and performance point of view. These applications are client-server by default.
See Also:
Security permissions processing mechanism optimization and other important changes in XAF v17.2+
Hi,
Can you please confirm the correct usage of cache node:
Func<IDataLayer> dataLayerProvider = () => { // enable data cache store var mainDataStore = XpoDefault.GetConnectionProvider(connectionString, AutoCreateOption.DatabaseAndSchema); var root = new DataCacheRoot(mainDataStore); var node = new DataCacheNode(root); var dataLayer = new ThreadSafeDataLayer(XpoTypesInfoHelper.GetXpoTypeInfoSource().XPDictionary, node); return dataLayer; }; Func<IDataServerSecurity> dataServerSecurityProvider = () => { SecurityStrategyComplex security = new SecurityStrategyComplex(typeof(PermissionPolicyUser), typeof(PermissionPolicyRole), new AuthenticationStandard()); security.SupportNavigationPermissionsForTypes = false; return security; }; WcfXafServiceHost serviceHost = new WcfXafServiceHost(dataLayerProvider, dataServerSecurityProvider, true, InstanceContextMode.PerSession); serviceHost.AddServiceEndpoint(typeof(IWcfXafDataServer), WcfDataServerHelper.CreateNetTcpBinding(), "net.tcp://127.0.0.1:1451/DataServer");
@Maxime MERIAUX: I've created a separate ticket on your behalf (T579483: Cache node usage with the new middle-tier implementation in v17.2). It has been placed in our processing queue and will be answered shortly.
Hello,
I'm trying to move my application to the new WcfXafServiceHost, however I noticed there seems to be no apparent replacement for the EventHandler<DataServiceOperationEventArgs> comittingDelegate that was available in the SecuredDataServer constructor.
This was my previous call:
var securedDataServer = new SecuredDataServer(dataLayer, securityProviderHandler, DevExpress.ExpressApp.MiddleTier.Logger.Instance, myCommittingDelegate, false);
This is the constructors signature:
public SecuredDataServer(IDataLayer dataLayer, QueryRequestSecurityStrategyHandler querySecurityEnvironmentHandler, ILogger logger, EventHandler<DataServiceOperationEventArgs> committingDelegate, bool allowICommandChannelDoWithSecurityContext) {...}
Is there any way to include the myCommittingDelegate with the new WcfXafServiceHost?
Hello,
I've created a separate ticket on your behalf (T594017: How to use the custom CommittingDelegate with the new WcfXafServiceHost). It has been placed in our processing queue and will be answered shortly.