Friday, March 16, 2012

SQL Server 2012, as it's now known, is currently available as an RC, and it's expected to become available during the first half of 2012 in three versions: Enterprise, Business Intelligence and Standard.

Further, Microsoft has advertized a new feature in SQL Server 2012 called Always On, which is a tool for disaster recovery and high-availability features in SQL Server.

In addition, Always On will allow users to experience clear scales of reporting and backup workloads, and it will also provide support for FileTable and FILESTREAM, which brings first-class high-availability to complex data types.

Another new feature is the ability to create the so-called availability groups, or groups of databases to which users can assign failovers to move.

From the article:

"Microsoft Dynamics AX 2012 can be configured to work with SQL Server AlwaysOn Availability Groups. SQL Server AlwaysOn enhances the capabilities of Database Mirroring, helps ensure availability of application databases, provides an integrated set of options including automatic and manual failover of a group of databases and simplifies deployment of high availability using integrated configuration wizard. A Microsoft Dynamics AX 2012 instance that is configured against a SQL Server AlwaysOn Availability Group can provide high availability and failover capabilities like many other applications that are built on SQL Server AlwaysOn technology. "

Thursday, March 15, 2012

As promised, this is the second portion on Security for Developers. If you missed the first part of this series, you can get it HERE.

Today we are going to learn about code access security in Microsoft Dynamics AX 2012. And to start I would like to talk about a little bit about code access security in C#.

In C# (.NET) as well as in AX 2012, we work with security demands. And what is a security demand?

We can probably figure that demands are used to ensure that every caller who calls your code (directly or indirectly) has been granted the demanded permission.

In a regular environment this happens when demanded for permission; the runtime's security system walks the call stack, by comparing the granted permissions of each caller to the permission being demanded. At this point, like in any high security building in New York City, if any caller in the call stack is found without the demanded permission then a SecurityException is thrown. In the case of a New York City building, you will be thrown out of the building. Simple ah?

Well, the same type of process exists in AX 2012 as AX 2012 Code Access Security is used by developers to protectSecuredAPIs from being invoked by un-trusted code (code that does not originate from the AOT). Code access security does this by verifying the following:

The code asserted the appropriate permission on the call stack to use the secured class.

The assert (the request to use the secured class) is executed in trusted code and saved in the AOT.

The assert is executed on the same tier as the secured class.

In addition, Code Access Security covers the use of secured classes on the server tier only and we don’t need to modify client callas of secured classes, which is cool and scalable.

So here is how this works:

Code Access Security must be implemented by the secured class owner and all consumers of the secured class.

The owner secures the secured class by implementing a specific type of permission class and calling the demand()(remember the C# demands above?) method on that class.

Each class consumer must explicitly request permission to invoke a secured class by calling the assert() method on the permission class. (this is where the permissions are compared)

Application code will break unless both of these steps are completed. (This is similar to theSecurityException in .NET)

NOTE: Code Access Security does not guarantee the validity of any data or parameters passed to the secured class. Data validation is still the responsibility of the consumer.

Now, in AX 2012, there are six groups of protected classes in AX 2012 Code Access Security:

Direct SQL

Run-time compilation and execution of X++

Data-controlled execution of X++

File handling

Win32 Interop

Windows API

The follow first code shows how to consume the TextBuffer class. So, we first need to create a new FileIOPermission object, then pass the file name as a parameter, and then we call the assert() method. The second example shows how to call a CAS-enabled API.

server void MyServerFunction()

{

// Declare the code access security permission object.

FileIOPermission fileIOPermission;

TextBuffer txtb = new TextBuffer();

Filename filename ="c:\\temp\\myfile.txt";

// Assert that it is okay to read and write files

fileIOPermission = newFileIOPermission(filename, 'rw');

fileIOPermission.assert();

// From file will demand CAS permission (read)

txtb.fromFile(filename); // Read text from file

// To clipboard will demand CAS permission (write)

txtb.toClipboard(); // Copy it to the clipboard

// To file will demand CAS permission (write)

txtb.toFile(filename); // Write text to file

}

server void callCASEnabledAPI()

{

DictClass dictClass;

anytyperetVal;

strresultOutput;

// Variable for the permission class.

ExecutePermission perm;

;

perm = new ExecutePermission();

// Grants permission to execute the DictClass.callObject method.

// DictClass.callObject is protected by code access security.

perm.assert();

dictClass = new DictClass(classidget(infolog));

if (dictClass != null)

{

retVal = dictClass.callObject("toString", infolog);

resultOutput = strfmt("Return value of is %1", retVal);

print resultOutput;

pause;

}

// Closes the code access permission scope.

CodeAccessPermission::revertAssert();

}

In the above example, if permission to use the API is not asserted, the following error is generated:

Request for the permission of type '%1' failed.

The following, and sadly, the last example shows how to execute permissions to a direct SQL statement within X++.

static void getCustomersDirectSQL(Args _args)

{

ConnectionuserConnection;

Statementstmt;

strsqlString;

;

userConnection = new Connection();

stmt = userConnection.createStatement();

sqlString = 'select * from custTable';

new SqlStatementExecutePermission(sqlString).assert();

stmt.executeQuery(sqlString);

CodeAccessPermission::revertAssert();

}

It is important to remember that these tools are critical when developing our modifications to the system (AX 2012). Now that AX 2012 X++ language is compiled in the IL, we need to take advantage of the .NET CLR code access security when integration internal/external applications with AX 2012.

I hope you enjoyed reading this post and stay tune for my last post of this series about display methods authorizations in AX 2012.

Thursday, March 8, 2012

Roles, duties and privileges security levels cover access to single elements, for example forms, and groups of elements needed to perform a duty. As developers we are responsible for defining more granular security levels by setting access on tables and controls in a form, and/or by associating classes that perform an action with permission (i.e. an action menu item)

In this article I would like to discuss, in detail, form permissions, code access permissions and how to create security policies using the extensible data security (XDS) method.

Form Permissions

Each form in the Application Object Tree (AOT) has a permissions node. It contains either four or five sub-nodes - Read, Update, Create, Delete and Correct. Now, correct is only displayed if a table in the form has Date Effective data.

Further, under the above nodes are four additional nodes - Controls, Tables, Server Methods and Associated Forms. When we add a table to a form data source, this table is automatically added to the Tables node for each of the Permissions sub-nodes. In addition, each of the nodes under the Tables node has an EffectiveAccess property which sets what access is allowed to the table and the EffectiveAccess property is automatically set based on properties on the data source.

So, this is where all makes sense, if the data source property AllowDelete is set to No, the EffectiveAccess property is set to Update. If the data source property AllowEdit is set to No, the EffectiveAccess property is set to Read.

NOTE: To set the security access for a form control, we need to set the Securable property on the control to Yes. Then, this control can then be added to the Controlsnode under each of the permissions nodes.

Code Permissions

These are a set of custom permissions that are created manually in the AOT under Security > Code Permissions.

For example, action menu items, can use these by setting the LinkedPermissionType property to CodePermission and the LinkedPermissionObject to the name of the code permission. Now, the great benefit about code permissions is that it can be extended to Service operations as well. This can be done by setting the Code Permission property under the Serviceoperation > Operation method > Permissions > Associated Code Permissions node.

The following image depicts an access to post a Free-Text Invoice

Security policies - Developing an XDS Policy

The following walkthrough will show how to create a security policy that limits users from viewing other user’s prospects. This can be seen a lot in a sales environment, where one sales person does not want the other to see his/her prospects, well who wouldn’t?

So for this example, we are going to use the smmBusRelTable where leads can hopefully become the future buyers of our products.

A lead/prospect is stored in smmBusRelTable, and the employee who is responsible for the prospect is stored in the MainContactWorker field. In AX 2012, an employee is connected to the current user through the DirPerson and DirPersonUser tables.

There are two stages in creating the XDS policy:

1-Create the policy query.

2-Create the security policy.

Creating a Policy Query

The steps to create the policy query are as follows:

In the AOT, create a new query, rename it to HcmWorkerUser.

From a second AOT, locate the table Data Dictionary > Tables > HcmWorker. Drag the table HcmWorker to the Data Sources node of the query.

In the property sheet of the Fields node of the HcmWorker_1 data source, set the Dynamic property to Yes.

From the second AOT (Press CTRL + D to open a new AOT), locate the table Data Dictionary > Tables > DirPerson.

Drag the table DirPerson to the Data Sources node of the HcmWorker_1 data source.

In the property sheet for the DirPerson_1 data source, set the Relations property to Yes.

In the property sheet for the Fields node of the DirPerson_1 data source, set the Dynamic property to Yes.

From the second AOT, drag the table DirPersonUser to the Data Sources node of the DirPerson_1 data source.

In the property sheet for the DirPersonUser_1 data source, set the Relations property to Yes.

In the property sheet for the Fields node of the DirPersonUser_1 data source, set the Dynamic property to Yes.

Right-click the Ranges node of the DirPersonUser_1 data source, and select New Range.

In the property sheet for the new range, set the Field property to User, and the Value property to (currentUserId()) as it appears.

Save your changes to the query.

Creating a Security Policy

Follow these steps to create the security policy:

In the AOT, expand the Security node.

Right-click the Policies node and select New Security Policy.

In the property sheet for the security policy, set the Name property to SmmBusRelUser, set the Label property to Limit Prospects by User, set the Primary Table property to HcmWorker, set the Query property to HcmWorkerUser, set the ContextType property to RoleName, set the RoleName property to TradeSalesRepresentative, and set the Enabled property to Yes.

Expand the SmmBusRelUser security policy.

Right-click the Constrained Tables node and select New > Add table by relation.

In the property sheet for the new constrained table, set the Table property to smmBusRelTable, set the TableRelation property to MainContactWorker. Save your changes to the policy.

Now, if you were to login with the name of a sales person, you could see that you will only have access (view) your prospects because when creating the policy query we set the currentUserId() to the value of the query range.Also, because a user is related in DirPerson and DirPersonUser tables, the policy is able to associate the user id with records in the smmBusRelTable.

That is all for now, and stay tune for the next series of security for developers as I will go in detail on consuming a secured class and setting authorization for display methods.

Saturday, March 3, 2012

As you probably already know, in AX 2012, the account and financial dimensions framework has been modified from its previous version (AX 2009). It is really interesting to see an evolution in the financial dimensions framework since AX 2009.

Let's go back a little bit. In AX 2009, a ledger account was represented by a single string value and was considered to be separate from the financial dimensions. In addition, Ledger accounts were stored in the LedgerTable table.

For example, financial dimensions. (Financial dimensions were referenced as an array of up to 10 array elements that each held the string value of a foreign key to the Dimensions table. All financial dimension values were stored in the Dimensions table.)

Based on my recent research, Microsoft has dramatically enhanced the account and financial framework to provide substantially more functionality. Further, to support this new functionality, the data model has also been completely redesigned. Ok, sounds great and impressive but what does this means for us?

Well, our job is about to get more interesting. Why? Because...

We will need to update every reference to ledger accounts and financial dimensions in existing applications to reference the new data model.

Each of the account and financial dimensions patterns has a corresponding AX form control.

Form controls provide a consistent implementation of the functionality across the application and a simplified programming model for the framework.

Account form controls combine the Segmented Entry control and a controller class. Further. the Segmented Entry control is a general-purpose Microsoft Dynamics AX client control that is being introduced in AX 2012.

The controller class is an X++ class that handles the events raised by the Segmented Entry control.

The combination of a control and an underlying class allows the user to see a dynamic number of segments, based on the values the user provides.

This is indeed a great opportunity for us to keep learning, adjusting and evolving around this new changes. However, this opportunity comes with great challenges, lots of study, and practice. Well, let's not be too worried about it as AX 2012 still has ledger accounts and financial dimensions, but the definition of these terms has changed slightly to account for the new functionality.