Вы находитесь на странице: 1из 79

Microsoft Dynamics

AX

Developing secure mobile
apps for Microsoft Dynamics
AX 2012
White Paper

This document describes how to develop mobile client apps to
communicate with Microsoft Dynamics AX from phone or tablet
platforms.


Authors: Jagruti Pandya and Rob Drollinger, Software Engineers

May 2013

http://go.microsoft.com






2

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Table of Contents
Introduction ................................................................................................ 4
Technical overview ................................................................................................................ 4
An Application Integration Framework custom service ............................................................... 5
Active federation for claims-based authentication to the Windows Azure Service Bus by using ACS
and ADFS on the client .......................................................................................................... 6
Outline of the walkthroughs........................................................................ 6
Design and create the AIF service in Microsoft Dynamics AX 2012 ............. 7
Overview ............................................................................................................................. 7
Development requirements .................................................................................................... 7
Create the data contract ........................................................................................................ 8
Create the data members for the data contract......................................................................... 8
Create the service class ......................................................................................................... 9
Create the service operations ................................................................................................. 9
Create the service contract ...................................................................................................10
Create a privilege to secure the service operation ....................................................................11
Create a basic inbound integration port ..................................................................................11
Verify that the service has been correctly deployed ..................................................................12
Establish a listener to the Windows Azure Service Bus ............................. 12
A middle-tier WCF service .....................................................................................................13
AIF Windows Azure Service Bus Adapter .................................................................................14
Comparing the Middle-tier WCF Service and the AIF Windows Service Bus Adapter ......................14
Create the middle-tier WCF service ........................................................................................15
Prerequisites .................................................................................................................... 15
Overview ......................................................................................................................... 16
Development requirements ................................................................................................ 16
Create the service contract and operation contract ................................................................ 16
Add a service reference of the AIF service ............................................................................ 18
Call the AIF service operations ........................................................................................... 20
Set up the Service Bus relay and deploy the listening endpoint for the middle-tier WCF service .. 22
Validate and extract contents from incoming messages ......................................................... 27
Build and deploy the middle-tier WCF Windows service .......................................................... 30
Deploy the AIF service using the AIF Windows Azure Service Bus Adapter. ..................................30
Prerequisites .................................................................................................................... 30
Overview ......................................................................................................................... 31
Authentication Overview .................................................................................................... 31
Create Custom Authentication Classes ................................................................................. 31
Registering the authentication component ........................................................................... 33
Encryption Key Containers ................................................................................................. 34
Publish AIF Service using the Service Bus Adapter ................................................................ 35


3

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Develop the client to communicate data to the middle-tier WCF service ... 38
Development requirements ...................................................................................................38
Overview ............................................................................................................................38
Create a Windows Phone application ......................................................................................38
Add the middle-tier WCF service reference ........................................................................... 38
Lay out and set up the UI controls for required user input ...................................................... 40
Implement active federation and claims-based authorization for the mobile
client ......................................................................................................... 42
Prerequisites (configuring the trusts) ......................................................................................42
Overview ............................................................................................................................43
Development requirements ...................................................................................................44
Implementation ...................................................................................................................44
Setup .............................................................................................................................. 44
Get user input .................................................................................................................. 46
Create and send the request for security token ..................................................................... 48
Create the ACS payload ..................................................................................................... 52
Additional notes and guidelines .......................................................................................... 56
Authenticate the user and send the data to the service ............................ 56
Developing RESTful JavaScript mobile apps for Microsoft Dynamics AX
2012 ......................................................................................................... 60
Design and create the AIF service in Microsoft Dynamics AX 2012..............................................61
Create the middle-tier RESTful service ....................................................................................61
Prerequisites .................................................................................................................... 62
Development requirements ................................................................................................ 62
Create the data contract, service contract, and operation contract .......................................... 62
Add a service reference of the AIF service ............................................................................ 65
Call the AIF service operations ........................................................................................... 65
Configure the RESTful service bindings and deploy the listening endpoint on Service Bus........... 65
Validate and extract contents from incoming JSON messages ................................................. 68
Create an HTML5/JavaScript app to communicate data to the WCF middle-tier RESTful service ......71
Implement active federation and claims-based authorization for the mobile client by using
JavaScript ...........................................................................................................................71
Send the request payload to the REST service .........................................................................74
Additional resources ................................................................................. 77


4

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012

Introduction
This document describes how to create mobile client applications (apps) that enable Microsoft
Dynamics AX users to communicate information with Microsoft Dynamics AX 2012.
Microsoft offers applications for key mobile scenarios on certain platforms and devices that are
compatible with Microsoft Dynamics AX 2012. Microsoft Dynamics customers and partners have a rich
ecosystem and powerful story for customizing and extending Microsoft Dynamics AX for the needs of
individual organizations and industries. One important goal of this document is to empower our
customers and partners to use Microsoft Dynamics AX to create delightful user experiences from any
device that works with their customizations.
This document provides walkthroughs of a solution that addresses the simple user scenario of an
employee capturing information about expenses that the employee incurred while traveling. The
document is only meant to teach you the fundamentals of getting devices anywhere in the world
talking to Microsoft Dynamics AX. The scenarios you can choose to implement with these lessons are
up to your business requirements and your imagination. You can easily envision several exciting
scenarios, such as time management, access to customer information while traveling to a customer
site, creating sales orders, managing your projects on the road, or just checking up on the factory
from across town on your phone or tablet.
Technical overview
The solution architecture described in this document lets users receive information and send
transactions to Microsoft Dynamics AX 2012, even if they are not in the same domain or network as
the on-premises instance of Microsoft Dynamics AX. For example, the solution lets clients access a
Microsoft Dynamics AX service that is running behind a firewall. The solution has the following
requirements:
An Application Integration Framework (AIF) service communicates data to and from Microsoft
Dynamics AX 2012.
Users provide their corporate credentials in the mobile client to interact with Microsoft Dynamics
AX 2012 services created for their scenarios.
Only authenticated and authorized users can communicate with Microsoft Dynamics AX services by
using client applications.


5

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
The following diagram illustrates how different components interact to enable the mobile app to
communicate with Microsoft Dynamics AX.

F
I
R
E
W
A
L
L
MOBILE
CLIENT APPLICATION
Active Directory
Federation Services
(ADFS)
AD DOMAIN CONTROLLER
AX 2012
AOS, SQL + AIF service
Windows Azure
SERVICE BUS
ACCESS CONTROL
SERVICE (ACS)
TOKEN SIGNING
CERTIFICATE
HTTP RELAY BINDING
S
H
A
R
E
D

S
E
C
R
E
T
MIDDLE-TIER WCF SERVICE
OR
IIS 7.5 AIF ROUTING SERVICE
RST: REQUEST FOR SECURITY TOKEN
RSTR: REQUEST FOR SECURITY TOKEN RESPONSE

Figure 1 Architectural overview of the entire mobile solution
An Application Integration Framework custom service
Design an AIF service that can be consumed for the necessary business scenario. To do this, you will
need to do the following:
Create AIF service and data contracts, and deploy a basic inbound port to expose the service
operations for consumption.
Implement the service methods in an X++ classes to perform data operations with Microsoft
Dynamics AX 2012.
The AIF service alone works well for clients who want to consume the service when they are in the
same network or domain. However, for mobile scenarios, this would not be useful, because the mobile
client will need to communicate with the AIF service hosted on an Application Object Server (AOS)
instance that is deployed behind a corporate firewall. Instead of configuring changes in the firewall,
such as exposing an Internet Information Services (IIS) server externally to expose the on-premises
service, we make use of a secured Service Bus relay.
The Microsoft Windows Azure Service Bus and its relayed messaging capability enable applications
on other networks to communicate with a system or application that reside on-premises on another
network or behind a firewall.


6

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
We provide two development patterns that leverage the Service Buss relayed message capability:
A custom-built middle-tier WCF service
This pattern involves building a middle-tier WCF service that establishes a listener for the
Service Bus and routes messages to Microsoft Dynamics AX services according to the routing
behavior that the developer chooses.
Publishing a service using the AIF Windows Azure Service Bus Adapter
This pattern leverages the AIF Windows Azure Service Bus Adapter, which provides a Service
Bus listener, hosts the listener in IIS, and routes messages to the AIF service that was
deployed using the adapter.
You have the flexibility to decide which pattern best fits your application and business requirements.
The development patterns are described in Establish a listener to the Windows Azure Service Bus. A
table comparing their features is included.
Note: The example mobile application described in this document uses the middle-tier WCF service. A
service deployed with the AIF Windows Azure Service Bus Adapter can be consumed by following the
same guidance.
Active federation for claims-based authentication to the Windows
Azure Service Bus by using ACS and ADFS on the client
The Service Buss dedicated Access Control Service (ACS) plays a very important role in this solution,
controlling the authorization to call a service registered on the Service Bus. It enforces authorization
by requiring that the client provide a security token that is issued by a trusted identity provider that
authenticates the user.
We use active federation to authenticate the user and acquire the users identity claims. This involves
the mobile client actively requesting a security token (containing a set of claims identifying the user)
from the corporate Active Directory Federation Services (AD FS) 2.0 by using the WS-Trust protocol.
The client will then present this security token containing the claims to the ACS, which will then grant
a simple web token (SWT) as a form of authorization for the client to securely send messages via the
Service Bus.
For the mobile solution, you will need to use an existing corporate AD FS as an identity provider (IdP)
to authenticate the user credentials originating from the app. The AD FS will also be used as the
security token service (STS) to provide identity claims about the user that will eventually be consumed
by the Microsoft Dynamics AX 2012.
We will walk you through implementing the described solution in detail. We will also provide sample
code and configuration guidance to help you develop mobile applications for Microsoft Dynamics AX
2012 by using services.
Outline of the walkthroughs
The rest of the document will walk you through the components that you need to implement to create
secure mobile applications for Microsoft Dynamics AX 2012.
In these walkthroughs, we will be using a simple unreconciled expense capture scenario to illustrate a
sample mobile application. In this scenario, an employee of a company that uses the Microsoft
Dynamics AX 2012 Time and expense management feature will use the mobile application to capture
details of an expense that the employee incurs when on the move.
We will use this scenario in all our services, and also in client code samples.
You will need to do the following walkthroughs in this document:
1. Design and create the AIF service in Microsoft Dynamics AX 2012
2. Establish a listener to the Windows Azure Service Bus


7

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
3. Develop the client to communicate data to the middle-tier WCF service
4. Implement active federation and claims-based authorization for the mobile client
5. Authenticate the user and send the data to the service
Design and create the AIF service in Microsoft Dynamics
AX 2012
Overview
As mentioned in earlier, our example illustrates how a Microsoft Dynamics AX user employee can
submit expenses from a mobile client when the user is on the move. When the expense makes it into
Microsoft Dynamics AX, the expense shows up in the system as an unreconciled expense, which the
employee can then add to an expense report.
We need to implement an AIF service that accepts this expense data coming from the middle-tier WCF
Service, processes it, and then pushes it into the Microsoft Dynamics AX 2012 database.
In this walkthrough, we will guide you through the implementation and deployment of the custom AIF
service for our mobile example. We will be using some of the existing expense data types and also the
existing TrvUnreconciledExpenseTransaction table (which comes with the Travel and expense
module in Microsoft Dynamics AX 2012).
We will create a service contract for the AIF service that will be exposed to the clients consuming this
service. In our expense capture example, the middle-tier WCF service will consume the AIF service
that we create (named UnreconciledExpenseService).
For more guidance about creating custom AIF services, see Walkthrough: Exposing an X++ Class as a
Data Contract [AX 2012].
Note: The following example uses a standard implementation of custom AIF service functionality. If
you are already familiar with this, you can skip this section.
Note: Although this example walks you through exposing a custom AIF service, you can apply the
same principles to utilize Microsoft Dynamics AX document services or system services, such as the
query service.
The following points summarize the walkthrough article mentioned earlier:
1. Create the data contract. This is the data object that is passed into the service call.
2. Create the data members that will be exposed as part of the data contract.
3. Define the service class.
4. Implement the service operations offered by the service contract.
5. Add the service class to the Application Object Tree (AOT).
6. Create a basic inbound port for the service to deploy the service.
7. Activate the port to make it consumable by external clients.
Development requirements
To complete this walkthrough, you will need the following:
Microsoft Dynamics AX 2012 installed and configured, together with the Active Directory server
A development license for Microsoft Dynamics AX 2012


8

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
For our sample code, which covers an expense capture scenario:
The Travel and expense management module in Microsoft Dynamics AX 2012
The Human resources module in Microsoft Dynamics AX 2012
Microsoft Dynamics AX users added and mapped to workers, with the Employee role
Create the data contract
1. In the Developer Workspace, create a class in the AOT named UnreconciledExpenseRecord. Set
the RunOn property to Called from.
2. In the class declaration, define the data members. For our expense capture scenario, we want the
user to send the expense amount, currency, expense date, and some notes.
3. Apply the DataContractAttribute attribute to the class.
X++
[DataContractAttribute]
public class UnreconciledExpenseRecord
{
TransDate transactionDate;
TrvFreeText notes;
AmountCur transactionCurrencyAmount;
CurrencyCode transactionCurrencyCode;
}

Create the data members for the data contract
Add new methods in the class, and apply the DataMemberAttribute attribute to these methods.
X++
[DataMemberAttribute]
public TrvFreeText parmNotes(TrvFreeText _notes = notes)
{
notes = _notes;
return notes;
}

[DataMemberAttribute]
public AmountCur parmTransactionCurrencyAmount(
AmountCur _transactionCurrencyAmount = transactionCurrencyAmount)
{
transactionCurrencyAmount = _transactionCurrencyAmount;
return transactionCurrencyAmount;
}

[DataMemberAttribute]
public CurrencyCode parmTransactionCurrencyCode(
CurrencyCode _transactionCurrencyCode = transactionCurrencyCode)
{
transactionCurrencyCode = _transactionCurrencyCode;
return transactionCurrencyCode;
}


9

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
X++

[DataMemberAttribute]
public TransDate parmTransactionDate(TransDate _transactionDate = transactionDate)
{
transactionDate = _transactionDate;
return transactionDate;
}

Create the service class
Create a class in the AOT named UnreconciledExpenseService, and set the RunOn property to
Server.
The class declaration is as follows.
X++
/// <summary>
/// The <c>TrvUnreconciledExpenseService</c> is the unreconciled
/// expense transaction Web service class.
/// </summary>
public class UnreconciledExpenseService
{
// These macros are used to specify the SubCode on AifFaults.
// Their values will not be translated allowing the consumer
// of the service to identify the cause
// of the fault and take appropriate action.

#DEFINE.ParameterValidationError('ParameterValidationError')
#DEFINE.UnreconciledExpenseCreationFailed('UnreconciledExpenseCreationFailed')
}

Create the service operations
In the UnreconciledExpenseService class, create a public method named createRecord, which will
take a reference of an unreconciled expense transaction that the user submitted and insert the data
into the TrvUnreconciledExpenseTransaction table.
X++
[SysEntryPointAttribute(true)]
public recId createRecord(UnreconciledExpenseRecord _unreconciledExpenseRecord)
{
TrvUnreconciledExpenseTransaction unreconciledExpenseTrans;
recId createdRecId;
recId workerId;

if (!_unreconciledExpenseRecord) // An instance of data contract class is required
{
throw error(Error::wrongUseOfFunction(funcname()));
}



10

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
X++
workerId = DirPersonUser::findUserWorkerReference(curUserId());

//Validates if user is related to a worker in AX
if (workerId == 0)
{
throw AifFault::faultList("@SYS335749", #ParameterValidationError);
}

ttsbegin;

unreconciledExpenseTrans.TransDate = _unreconciledExpenseRecord.parmTransactionDate();
unreconciledExpenseTrans.Worker = workerId;
unreconciledExpenseTrans.Notes = _unreconciledExpenseRecord.parmNotes();
unreconciledExpenseTrans.TransactionCurrencyAmount =
_unreconciledExpenseRecord.parmTransactionCurrencyAmount();
unreconciledExpenseTrans.TransactionCurrencyCode =
_unreconciledExpenseRecord.parmTransactionCurrencyCode();

if (unreconciledExpenseTrans.validateWrite())
{
unreconciledExpenseTrans.insert();
}
ttscommit;
createdRecId = unreconciledExpenseTrans.RecId;

if (!createdRecId)
{
//Creation of record failed
throw AifFault::faultList("@SYS335750, #UnreconciledExpenseCreationFailed);
}
return createdRecId;
}

As you can see in the preceding code, we are fetching the worker who is associated with the expense
based on a current user ID. As you will see in the Create the middle-tier WCF service section, the call
to the service operation is made under the context of the mobile Microsoft Dynamics AX user
submitting the request by setting the CallContext property. Therefore, the curUserId value will be
the Microsoft Dynamics AX user ID of the original user submitting the request.
Create the service contract
To create the service contract that is made available to clients consuming the service, create a new
service in the Services node of the AOT that implements the service class we created
(UnreconciledExpenseService). You must also add the operation exposed by the class
(createRecord). For guidance, see Walkthrough: Exposing an X++ Class as a Data Contract [AX
2012].



11

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Create a privilege to secure the service operation
At this point, we want to create a special privilege to help provide secure access when the
createRecord method is called. We require that this privilege be added to the Employee role (AOT
name: HCMEmployee), so that only those users who have this privilege call the createRecord
service method.
Create a privilege and add the operation to the Entry Points object of the Privilege.
1. In the Development workspace go to AOT > Security > Privileges > Right click and New Privilege.
2. Add a privilege and name it UnreconciledExpenseServiceCreate.
3. Go to the Entry Point node and right click and add a New Entry point and set:
Property Value
Name UnreconciledExpenseServiceCreate
ObjectType ServiceOperation
ObjectName UnreconciledExpenseService
ObjectChildName createRecord
AccessLevel Invoke


4. You can now add this Privilege to the Duty TrvTravelAndExpenseServiceOperations. (AOT>
Security>Duties>New Privilege)
Note: This duty is already incorporated in the HCMEmployee roles list of duties.
Note: If you have Dynamics AX 2012 R2 installed, you will also need to add two more privileges
(LogisticsAddressCountryRegionView and LogisticsPostalAddressView) to the
TrvTravelAndExpenseServiceOperations duty for the above implemented createRecord
operation to work correctly.
Create a basic inbound integration port
The following instructions pertain to the middle-tier WCF service only. When using the AIF Windows Azure Service Bus
Adapter, do not create a basic inbound integration port. Instead, go to Deploy the AIF service using the AIF Windows
Azure Service Bus Adapter.

In order to deploy the service we must create a basic inbound integration port.
First, we need to register the service in the AOT:
Go to the Service that we created in the step above: \Services\UnreconciledExpenseService.


12

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Right-click > Add-Ins > Register service. The AIF services window will open. Verify if the service
that you created is in the list of AIF services. Close the form.
Next, we need to activate the port in order to make it available to external clients:
Click System Administration > Setup > Services and Application Integration Framework > Inbound
ports.
Click New to create a new inbound port for this service. Specify a Port name for example:
UnreconciledExpense
Click on Service operations to add a required service operation. In our example, add operation
UnreconciledExpenseService.createRecord from the list of remaining service operations and
then close.
Click Activate to activate the port.
Verify that the service has been correctly deployed
1. In the Inbound ports form, copy the WSDL URI.

2. Open the WSDL URI in a browser to view the WSDL file. To consume the service, clients need to
add the WSDL URI address as the service reference to generate the service proxy.

Establish a listener to the Windows Azure Service Bus
Both the AIF service that is published using the Service Bus adapter and a middle-tier WCF service will
establish a listener to the Windows Azure Service Bus. This listener is an out-bound connection to the
Service Bus on which incoming messages from clients are relayed. A message relayed in this manner
is then routed to Microsoft Dynamics AX by a routing service hosted in IIS 7.5 (if using the Service
Bus adapter) or by the routing service in the middle-tier WCF service.


13

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
A middle-tier WCF service
Creating a WCF service that deploys its listening endpoint on a Windows Azure Service Bus namespace
involves the following tasks:
Define a service contract that is in line with the requirements of the AIF service contract (that is,
clients pass data that is required by the AIF service per the business scenario).
Define a URI that is used to listen on the Service Busfor example,
https://<AzureNamespace>.servicebus.windows.net/Expense/.
Set up a secure channel (HTTP relay binding) with the Service Bus.
Extract information from the incoming message sent by the client. (The client application creates
its request by using the service proxy generated from the WCF service, and sends the request to
this endpoint URI. The Service Bus will relay the message to the middle-tier WCF service). The
WCF service then calls the AIF service and passes all the data the AIF service needs.
It is very important that only authorized users be allowed to send and receive messages through the
Service Bus. In addition, we require that only authorized users be able to make calls to the WCF
service. These users exist in an enterprises Active Directory Domain Services and can be
authenticated by a deployed Active Directory Federation Service (AD FS).
Furthermore, we need to call the AIF service in the context of the authorized user, and therefore need
information about the user in the data that is passed from the client to the WCF service.


14

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
AIF Windows Azure Service Bus Adapter
The AIF Windows Azure Service Bus Adapter extends the existing AIF functionality and uses IIS 7.5 to
provide a method to deploy services by using cloud computing. The following infrastructure helps
accomplish this:
IIS 7.5
The Service Bus adapter leverages IIS to host Microsoft Dynamics AX services published with
an HTTP adapter, or by using the new Service Bus adapter. IIS hosts the Service Bus listener
and a routing service (both of which are WCF services) that work in tandem to pass messages
from the Service Bus to Microsoft Dynamics AX.
Authentication Classes
Each call to Microsoft Dynamics AX services through the Service Bus must be authenticated.
With the Service Bus adapter hotfix, the AIF now allows registering authentication classes to
authenticate inbound Service Bus messages and extract the users Microsoft Dynamics AX
credentials. Registering authentication classes is a one-time configuration step, and the
authentication classes can be used across multiple Service Bus namespaces and published
services after they are registered.
AIF Service Bus Namespace Registration
Registering a Service Bus namespace is a one-time step for each namespace you wish to use.
Registration includes supplying the namespace name, access key credentials, authentication
classes, and X.506 signing certificate that is used to sign the ADFS SAML token. The AIF uses
all of these in order to establish trust with the Service Bus before opening a connection.
AIF Windows Azure Service Bus Adapter
After you have registered a Service Bus namespace with AIF, you can begin publishing
Microsoft Dynamics AX services by using the AIF Windows Azure Service Bus Adapter. The
process of publishing Microsoft Dynamics AX AIF services has not changed. Create a new port
(using the form AifInboundPorts form), select the AIF Windows Azure Service Bus Adapter,
and then select the service operations to expose on the port. After you activate the port, your
service will be accessible from the cloud. For more information about adapters, see
http://msdn.microsoft.com/EN-US/library/gg751348.aspx.
All of these items are described in detail in Deploy the AIF service to the Azure Service Bus.
Comparing the Middle-tier WCF Service and the AIF Windows Service
Bus Adapter
Use the following table to compare the capabilities and requirements of the Middle-tier WCF service
and the AIF Windows Azure Service Bus Adapter. Both options provide solutions for mobile application
development, but they differ in implementation, infrastructure, and technical capabilities. The
following table highlights the differences.
Middle-tier WCF Service AIF Windows Azure Service Bus Adapter
Configuration
and Setup
Requires developing the Middle-tier WCF
service.
Can be configured by an administrator.
Configuring custom authentication may
require a developer.
IIS Does not require IIS Requires IIS 7.5 to host the Service Bus
listener.
Failover
Support
Failover is handled by installing multiple
middle-tier WCF services on separate
machines.
Failover is handled through available IIS
failover strategies.


15

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Multiplicity Can listen to multiple Service Bus
namespaces simultaneously from one
middle-tier WCF service instance.
Each Service Bus namespace must be
registered with exactly one IIS website.
Routing to
multiple AX
instances
Each middle-tier WCF service can serve
multiple AX instances. The WCF service
developer creates this routing behavior.
An IIS instance can host multiple websites.
Each IIS website can serve a different
Microsoft Dynamics AX instance. Each website
is tied to exactly one Service Bus namespace
within a Microsoft Dynamics AX instance. We
recommend that you do not share a website
across Microsoft Dynamics AX instances.
REST support Can be configured to expose a RESTful
endpoint, or any other service contract
type and binding that is possible in WCF as
a faade for the backing AIF service.
Not currently supported. The SOAP service
contract exposed to the client on Service Bus
is always identical to the service contract as
defined in Microsoft Dynamics AX.
Protocol
support
Endpoints hosted on Service Bus can support
any transport (such as HTTP andNet.Tcp) or
messaging (such as SOAP and JSON)
protocols available for a WCF service,
including custom message encoders or other
service behaviors (enabling compression or
other message manipulation or inspection,
for example).
Supports only HTTPS for service calls.
Logging and
eventing
As part of configuring the Middle-tier WCF
service, a developer must write a logging
service.
Logs connection status in IIS event log.

Authentication Endpoints can be either authenticated or
unauthenticated (to allow client
bootstrapping traffic, for example).
Endpoints must always be authenticated, so it
is the clients responsibility to know which
identity provider to authenticate against.

Choosing between the two approaches is primarily a matter of balancing customizability with
development costs. The middle-tier WCF service has higher development costs because it requires you
to manually create and install a WCF service that listens to the Service Bus and routes service calls to
Microsoft Dynamics AX. However, with the middle-tier WCF service you can use the messaging
protocols of your choice, expose different contracts to your clients, provide custom message routing
behavior, and serve multiple installations of Microsoft Dynamics AX or other back-end systems.

The Service Bus adapter has a lower development cost because automatically creates a WCF service
and hosts it in IIS. By using the Service Bus adapter, your only development costs are in
configuration: providing Service Bus information (namespace, access key), AD FS information
(certificate thumbprint), and registering authentication classes. However using the Service Bus
adapter does not allow customization of the WCF service that is hosted in IIS. The WCF service hosted
in IIS can perform only the action of authenticating and routing service calls. The routing behavior
only supports routing relayed messages to the installation of Microsoft Dynamics AX that the service
was published from.
Next, we will walk through the steps that are necessary to build the middle-tier WCF service, followed
by the steps that are necessary to publish a service using the AIF Windows Azure Service Bus Adapter.
Create the middle-tier WCF service
Prerequisites
An X.509 token signing certificate is installed on the AD FS 2.0 server and on the machine running
the WCF service, in the Trusted Root Certification Authorities store. For guidance, see Microsoft
Dynamics AX Connector for Mobile Applications.
You have the thumbprint from that certificate.


16

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
A Windows Azure Service Bus namespace has been created, and the shared secret and issuer
name for the namespace are available. For guidance, see Microsoft Dynamics AX Connector for
Mobile Applications.
The machine that the middle-tier WCF service runs on should be in the same domain or on the
same network as the Microsoft Dynamics AX 2012 AOS machine (which can be the same machine
or a different one).
Overview
The following steps are required to create the WCF SOAP-based service that will receive service
requests from the mobile client, relayed by the Service Bus.
For the following example, we will create the WCF service as a Windows service.
Development requirements
Microsoft Visual Studio 2010 and the Microsoft .NET Framework version 4.
The Service Bus component (Microsoft.ServiceBus.dll), which is included with the Windows Azure
Libraries for .NET. To install it, visit the Windows Azure SDK download page.
The Windows Identity Foundation runtime, which can be downloaded from Windows Identity
Foundation (WIF) SDK. Download the 4.0 version for Visual Studio 2010 and the .NET Framework
version 4.0.
For more information about the WIF SDK, see Windows Identity Foundation SDK.
Create the service contract and operation contract
1. Open Visual Studio, and create a new Windows Service .NET Framework version 4 project
named ExpenseConnectorService.


17

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
2. Rename the Service1.cs class ConnectorService.cs. This class contains the OnStart and
OnStop methods for the Windows service, which we will use to open a listening endpoint.
C#
using System.ServiceModel;
using System.ServiceProcess;

namespace ExpenseConnectorService
{
public partial class ConnectorService : ServiceBase
{
private ServiceHost host;

public ConnectorService()
{
InitializeComponent();
}

protected override void OnStart(string[] args)
{
// Deploy the endpoint
}

protected override void OnStop()
{
// Close the endpoint connection
}
}
}

3. Add the System.ServiceModel reference to the project, and include the System.ServiceModel
namespace in all the following classes.
4. Add a new C# interface for the service contract, named IExpenseService, to the project, and
create the service contract and operation contract as shown here.
C#
[ServiceContract(Name = "ExpenseServiceContract",
Namespace = "http://samples.microsoft.com/DynamicsAx/")]
public interface IExpenseServiceContract
{
[OperationContract]
long CreateExpense(DateTime dateTime, decimal amount, string currency, string comments);
}



18

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
5. Create another C# class for the service operation implementation.
Per the contract we created, create a class named ExpenseService, which implements the
IExpenseServiceContract interface.
C#
[ServiceBehavior(Name = "ExpenseService")]
public class ExpenseService : IExpenseServiceContract
{
public long CreateExpense(DateTime dateTime, decimal amount, string currency, string
comments)
{
// Implementation
}
}

Any client consuming this service will make a call to the services CreateExpense operation and
will be required to pass information as stated in the method parameters.
Later, we will add code to this method that will process the incoming SOAP message in the
following way:
Extract the Security Assertion Markup Language (SAML) token from the header of the
message. The token is issued by the identity provider (the corporations Active Directory
Federation Service).
Perform token validation.
Extract the claim assertion that was requested (the windowsaccountname claim).
Use the expense data embedded in the SOAP message body, and make a call to the AIF
service operation.
All the processing, validating, and extracting of claims from the token is facilitated by the Windows
Identity Foundation libraries.
Add a service reference of the AIF service
We need to generate a client proxy of the AIF service to gather the service contract, bindings, and
address for the AIF endpoint. To add the service reference, we use the WSDL exposed by the inbound
port that was activated in the Design and create the AIF service in Microsoft Dynamics AX 2012
section.


19

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
1. Go to Solution Explorer, right-click References, and then select Add service reference. In the
Add Service Reference form, enter the WSDL address
http://AOSMachine:8101/DynamicsAx/Services/UnreconciledExpense.

You will see the createRecord operation exposed by the service. Edit the namespace, naming it
AXExpenseServiceReference, and then click OK to add the reference to the project.
The reference shows up in the Service References node in Solution Explorer. Also observe that
the client proxy file named Reference.cs is generated within the project in a folder (\Service
References).
2. Observe that several changes have automatically been made to the app.config file in the project
with regard to the bindings, security protocols, and so on, and also the URI of the endpoint
deployed to enable the middle-tier service to communicate with the AIF endpoint on Microsoft
Dynamics AX. Verify that the following configuration values are created in the app.config file.


20

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
NetTcpBinding specification for connecting to the AIF endpoint exposed on the AOS
server
APP.CONFIG
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_UnreconciledExpenseService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false"
transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288"
maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
<message clientCredentialType="Windows"/>
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>

Definition of the endpoint address, binding configuration, and contract of the AIF
service
APP.CONFIG
<client>
<!-- This address should be set to the URI of the endpoint deployed on AX.
It should be of the form:
"net.tcp://<AOS_MACHINE_NAME>:8201/DynamicsAx/Services/<INBOUND_PORT_NAME>" -->
<endpoint address="net.tcp://AOSMachine:8201/DynamicsAx/Services/UnreconciledExpense"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_UnreconciledExpenseService"
contract="AXExpenseServiceReference.UnreconciledExpenseService"
name="NetTcpBinding_UnreconciledExpenseService">
</endpoint>
</client>

As shown in the <client> element, the endpoint address can be configured to point to a machine
that hosts the AOS machine on which the AIF service is deployed and activated. In this way, the
middle-tier service can be run on any machine, provided that it is on the same network as the
AOS machine, to make the service call by using the NetTcp binding.
Call the AIF service operations
After you have added the service reference, the next step is to use its operation contract and make
the necessary method call.


21

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
1. Include the AIF service namespace ExpenseConnectorService.AXExpenseServiceReference in the
ExpenseService class.
C#
using ExpenseConnectorService.AXExpenseServiceReference;

2. Create a new private method named SubmitExpenseToAX, which will do the following:
1. Populate the values of the UnreconciledExpenseRecord data member of the
UnreconciledExpenseService AIF service
2. Call UnreconciledExpenseServices createRecord operation
3. Return the result (the RecID value returned by the AIF service operation)
Later, we will call this method in the exposed service operation (CreateExpense).
C#
private long SubmitExpenseToAX(DateTime dateTime, decimal amount, string currency,
string comments, string windowsAccountName)
{
UnreconciledExpenseRecord record = new UnreconciledExpenseRecord()
{
parmNotes = comments,
parmTransactionCurrencyAmount = amount,
parmTransactionDate = dateTime,
parmTransactionCurrencyCode = currency
};

using (UnreconciledExpenseServiceClient client = new
AXExpenseServiceReference.UnreconciledExpenseServiceClient())
{
UnreconciledExpenseRecord expenseRecord = record;
CallContext callContext = new CallContext() { LogonAsUser = windowsAccountName };
return client.createRecord(callContext, expenseRecord);
}
}

The preceding method creates an instance of the services client, sets the data member values,
and then makes the final call to the createRecord operation. Also notice the CallContext object
that is passed into the service call. In Microsoft Dynamics AX, values such as the user, company,
and so on can be used when the service call is executed and are sent in the message header from
the service client by using the CallContext object.
In our example, we want to pass the mobile users information when making the createRecord
call, so that the unreconciled expense is created in the context of the user.
LogonAsUser has been set to windowsAccountName. This is the value of the claim that was
requested from the AD FS (in the form domain\userAlias) and identifies the user who submitted
the request from the client. Remember that this user must exist in the Microsoft Dynamics AX
system, and because Microsoft Dynamics AX uses the same Active Directory service as the identity
provider, it will recognize and then be able to authorize this user.


22

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Set up the Service Bus relay and deploy the listening endpoint for the middle-tier
WCF service
To configure the middle-tier services endpoint to listen on the Service Bus, we need to update the
app.config file as follows:
Add a BasicHttpRelayBinding binding for communicating with the Service Bus.
Provide the service contract name and the service endpoint address.
Set up the required binding configuration by specifying Service Bus credentials.

1. Define the BasicHttpRelayBinding configuration by adding the following under the <bindings>
element in the <system.serviceModel> section.
APP.CONFIG
<basicHttpRelayBinding>
<binding name="BasicHttpRelayBinding_ServiceBus">
<security mode="Transport" relayClientAuthenticationType="RelayAccessToken"/>
</binding>
</basicHttpRelayBinding>

The preceding configuration sets the binding to have end-to-end transport security. We also set
the value of the relayClientAuthenticationType parameter to RelayAccessToken, which forces
clients of the service to authenticate to the Service Bus before sending across any messages.
As shown in Figure 1, to connect to the Service Bus, the client presents the Service Bus with the
security token (SWT) issued by the ACS.


23

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
2. Define configuration values for the endpoint behavior.
APP.CONFIG
<behaviors>
<endpointBehaviors>
<behavior name="sharedSecretClientCredentials">
<transportClientEndpointBehavior credentialType="SharedSecret">
<clientCredentials>

<!-- The issuerName & issuerSecret here should be set to the values
for the service account on Service Bus you wish to use to listen.
By default, the namespace will come with an admin user (issuerName) of
"owner" with a 256-bit secret key (issuerSecret) available in the
Windows Azure management portal.-->
<sharedSecret issuerName="owner"
issuerSecret="xxxxxxxxx/xxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxx="/>
</clientCredentials>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>

As shown in the preceding configuration, transportClientEndpointBehavior is used to specify
the Service Bus credentials for the endpoint that will be deployed on the Service Bus.
The shared secret values of issuerName and issuerSecret are values of Default Issuer and
Default Key of your namespace that was set up in Windows Azure Management Portal.
Note: If you want to collect the necessary information from the user at run time via a UI,
System.ServiceModel and Microsoft.ServiceBus provide APIs to set all these configuration values
programmatically.
3. Deploy the listening endpoint.
To specify the service contract for the middle-tier service, the binding, and the behavior
configuration (all of which were defined in the preceding points), add the following code snippet in
the app.config file, under the <services> element.
APP.CONFIG
<services>
<service name="ExpenseConnectorService.ExpenseService">
<endpoint address="" behaviorConfiguration="sharedSecretClientCredentials"
binding="basicHttpRelayBinding"
contract="ExpenseConnectorService.IExpenseServiceContract"/>
<host>
<baseAddresses>
<!-- This baseAddress should be set to the URI you intend to
listen to on the Service Bus. It should be of the form:
"https://<APPFABRIC_NAMESPACE>.servicebus.windows.net/Expense/" -->
<add baseAddress="https://contosomobile.servicebus.windows.net/Expense/"/>
</baseAddresses>
</host>
</service>
</services>



24

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
4. Deploy the metadata endpoint for the service.
To generate a client proxy for our mobile client, we will need to expose a metadata endpoint
address.
Under the <behaviors>/<serviceBehaviors> node, add the following. Make sure that you
enable the serviceMetadata node.
APP.CONFIG
<serviceBehaviors>
<behavior name="serviceMetadata">
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment to
avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False"/>
<!--Enable this element when publishing metadata-->
<serviceMetadata />
</behavior>
</serviceBehaviors>

We now need to update the <services> section that we used to specify the service contract,
binding, and behavior configurations. Set behaviorConfiguration to serviceMetadata, and then
add a local MEX endpoint.
APP.CONFIG
<services>
<service name="ExpenseConnectorService.ExpenseService"
behaviorConfiguration="serviceMetadata">
<endpoint address="" behaviorConfiguration="sharedSecretClientCredentials"
binding="basicHttpRelayBinding"
contract="ExpenseConnectorService.IExpenseServiceContract"/>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding"
address="http://localhost/mex" />

<host>
<baseAddresses>
<!-- This baseAddress should be set to the URI you intend to listen on the Service
Bus
It should be of the form:
"https://<APPFABRIC_NAMESPACE>.servicebus.windows.net/Expense/" -->
<add baseAddress="https://contosomobile.servicebus.windows.net/Expense/"/>
</baseAddresses>
</host>
</service>
</services>

The client proxy that consumes this service can then be generated by using the
http://<MiddleTierServiceMachineName>/mex metadata URI.


25

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
5. We also need to update the app.config file to register the preceding Service Bus behavior and
binding extensions.
APP.CONFIG
<extensions>
<behaviorExtensions>
<add name="transportClientEndpointBehavior"
type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement,
Microsoft.ServiceBus, Version=1.7.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>
<bindingExtensions>
<add name="basicHttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCollectionElement,
Microsoft.ServiceBus, Version=1.7.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
</bindingExtensions>
</extensions>

6. Finally, open the Service Bus connection, and start listening on the endpoint.
Note: The on-premises service connects to the relay service over ports 93509354; however, if
these are unavailable, the service will try to call back to port 80 (HTTP) or 443 (HTTPS).
Add the following code snippets to the OnStart method in the ConnectorService class.
C#
protected override void OnStart(string[] args)
{
// Note that all binding, endpoint, service, behavior configuration
// for this ServiceHost is located in the app.config
host = new ServiceHost(typeof(ExpenseConnectorService.ExpenseService));
WriteToEventViewer("Opening the Service endpoint connection " +
host.BaseAddresses[0].ToString());

try
{
host.Open();
WriteToEventViewer(string.Format("Listening on: {0}",
host.Description.Endpoints.Find(
typeof(ExpenseConnectorService.IExpenseService)).Address));
}
catch (Exception e)
{
WriteToEventViewer(e.Message);
}
}



26

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
C#
private void WriteToEventViewer(string eventMessage)
{
string source = "Expense WCF Service";

if (!EventLog.SourceExists(source))
EventLog.CreateEventSource(source, "Application");

EventLog.WriteEntry(source, eventMessage, EventLogEntryType.Information);
}

C#
protected override void OnStop()
{
host.Close();
}

You can also close the connection in the OnStop method. There are several events you may want
to hook into and log, so that you can monitor the status of the relay binding and other such
events. You can log events in the event viewer by using System.Diagnostics.


27

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Validate and extract contents from incoming messages
The next step is to inspect the message coming from the client. The incoming SAML message contains
a header that holds the windowsaccountname claim in the security token. This claim is issued by
the AD FS 2.0. For more information about requesting claims, see the Implement active federation
and claims-based authorization for the mobile client section. Windows Identity Foundation is used to
validate the security token and the issuer, after which we extract the claim that we need to make the
AIF service call.



28

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
1. Update the app.config file, adding configuration values for handling the SAML security token
issued by the AD FS.
APP.CONFIG
<microsoft.identityModel>
<service>
<securityTokenHandlers>
<securityTokenHandlerConfiguration>
<audienceUris mode="Never"/>
<issuerNameRegistry
type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry,
Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35">
<trustedIssuers>
<!-- The STS that issues the SAML token exchanged
at ACS must be added as a trusted issuer here.
The thumbprint & name values should be obtainable from the
public signing certificate exposed on the STS' federation metadata -->
<add thumbprint="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
name=""/>
</trustedIssuers>
</issuerNameRegistry>
</securityTokenHandlerConfiguration>
</securityTokenHandlers>
</service>
</microsoft.identityModel>

APP.CONFIG
<configSections>
<section name="microsoft.identityModel"
type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection,
Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
</configSections>

The issuer (also known as the identity providerin our case, the corporate AD FS) uses a token
signing certificate to digitally sign the SAML token. Therefore, the thumbprint of the token signing
certificate must be specified in the services configuration as shown in the first code snippet, in the
<trustedIssuers> section. This will be used to validate the digital signature when the token is
validated.
2. Add Microsoft.IdentityModel and System.IdentityModel references to the project, and add
the following namespaces to the ExpenseService.cs file.
C#
using System.IdentityModel.Tokens;
using Microsoft.IdentityModel.Claims;
using Microsoft.IdentityModel.Configuration;

3. Add an implementation to the CreateExpense service operation to do the following:
1. Extract the security token from the custom SOAP header PassthroughBinarySecurityToken.
This header information is passed by the mobile client calling the service.


29

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
2. Inspect the SAML token.
3. Use WIF to validate the token by using the thumbprint and other configuration values from the
service configuration.
4. Extract the required claim (windowsaccountname) from the token.
5. Make the call to the SubmitExpenseToAX method, which will make the AIF service call.
C#
public long CreateExpense(DateTime dateTime, decimal amount, string currency, string
comments)
{
string samlTokenHeader =
(string)OperationContext.Current.IncomingMessageHeaders[OperationContext.Current.Incoming
MessageHeaders.FindHeader("PassthroughBinarySecurityToken", "")].ToString();

string encodedSamlToken = samlTokenHeader.Split('<', '>')[2];
byte[] binToken = Convert.FromBase64String(encodedSamlToken);
string samlToken = new string(Encoding.UTF8.GetChars(binToken));

// Load the app.config settings where we specify the audience & issuer that we'll
// accept in a token
var config = new ServiceConfiguration();
var handler =
config.SecurityTokenHandlers[
Microsoft.IdentityModel.Tokens.SecurityTokenTypes.Saml11TokenProfile11];

ClaimsIdentityCollection claimsIdentity = null;


// Convert the raw token into something that can be inspected
using (XmlReader reader = XmlReader.Create(new StringReader(samlTokenString)))
{
SecurityToken token = handler.ReadToken(reader);

// This is the primary WIF call that
// 1) Performs all the token validation
// a. Format, token type, key type, version, etc.
// b. Expiration
// c. Audience/AppliesTo/Relying party
// d. Issuer
// e. Signature
// 2) generates a ClaimsIdentityCollection that contains what the app actually //
cares about

claimsIdentity = handler.ValidateToken(token);
}

IPrincipal principal = new ClaimsPrincipal(claimsIdentity);
IClaimsIdentity identity = (IClaimsIdentity)principal.Identity;

windowsAccountName = identity.Claims.Single(claim => claim.ClaimType ==
"http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname").Value;



30

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
C#
return SubmitExpenseToAX(expenseData, windowsAccountName);
}

Build and deploy the middle-tier WCF Windows service
1. Build the entire project.
2. Add the ProjectInstaller.cs file, and create an installer (Setup project) for the Windows service by
following the guidance at Walkthrough: Creating a Windows Service Application in the Component
Designer.
3. Make sure that you add the primary output from the ExpenseConnectorService project to the
installer and all its dependencies (Microsoft.ServiceBus.dll, Microsoft.IdentityModel.dll, and the
.NET Framework dependencies).
The user account that the service is deployed and run should be the .NET Business Connector
proxy account. By using a proxy, you guarantee that .NET Business Connector can connect on
behalf of Microsoft Dynamics AX users when it authenticates with an AOS instance. For more
information about how to create and set up the .NET Business Connector proxy account, see
Specify the .NET Business Connector proxy account [AX 2012].
Also, note the following requirements for the .NET Business Connector proxy account:
It must be a Windows domain account.
It must be a dedicated account (used only by .NET Business Connector).
It must have a password that does not expire.
It must not have interactive logon rights.
It must not be a Microsoft Dynamics AX user.
In addition, it is important that the .NET Business Connector proxy user account be added as an
Administrator on the machine running the service (so that it has access to the ports required to
deploy listening endpoints on the Service Bus).
4. Run the installer, and provide the .NET Business Connector proxy users user name and password,
which will run the WCF Windows service.
Deploy the AIF service using the AIF Windows Azure Service Bus
Adapter
Prerequisites
The Service Bus component (Microsoft.ServiceBus.dll v1.8), which is included with the Windows
Azure Libraries for .NET. To install it, visit the Windows Azure SDK download page. (The
Microsoft.ServiceBus.dll must be placed in the Bin folder of the website that the service is
deployed to)
You have installed the AIF Windows Azure Service Bus Adapter Hotfix:
http://support.microsoft.com/kb/2845539
You have installed the AX Web Services on IIS 7.5.
An X.509 token signing certificate is installed on the AD FS 2.0 server and on the machine that is
running the WCF service, in the Trusted Root Certification Authorities store. For more information,
see Microsoft Dynamics AX Connector for Mobile Applications.
You have the thumbprint from that certificate.


31

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
A Windows Azure Service Bus namespace has been created, and the shared secret and issuer
name for the namespace are available. For more information, see Microsoft Dynamics AX
Connector for Mobile Applications.
Overview
The following steps enable publishing an AIF service that listens to messages incoming from the Azure
Service Bus, without a middle-tier WCF service.
You must register your Windows Azure Service Bus namespace with the AIF before you can publish
services to the Service Bus. Registration requires that you supply the X++ and WCF authentication
classes that will authenticate incoming Service Bus messages. Go to Create the authentication classes,
and then go to Register your Service Bus namespace with the AIF. Next, see Publish your AIF service.
Authentication overview
The Service Bus requires each on-premises service to be authenticated and authorized to listen on a
particular address before establishing a new relay connection. Clients must also be authenticated and
authorized before the Service Bus will relay messages on their behalf. The Service Bus relies on ACS
for authenticating services and clients.
Service authentication
Microsoft Dynamics AX services use a shared secret token provider to authenticate with the Service
Bus. The shared secret is provided to the AIF when you Register your Service Bus Namespace.
Client authentication
The following two types of client authentication are required:
Service Bus authentication
Clients are required to provide a send claim in order to be able to send messages to a
service on the Service Bus. The ACS must trust the identity provider used by the client. This
must be set up as described in Microsoft Dynamics AX Connector for Mobile Applications.
Microsoft Dynamics AX authentication
When the Service Bus relays a message to the on-premises service, the caller identity is used
to log on to Microsoft Dynamics AX. This caller identity is determined by calling a custom
authentication component to parse the incoming message token and to provide a valid claims
identity. The user specified by the claims identity must be a valid Microsoft Dynamics AX user.
Sample authentication component
A sample ADFS authentication component is provided here:
http://blogs.msdn.com/b/aif/archive/2013/04/29/aif-windows-azure-service-bus-adapter.aspx.
You can use it as it is or modify it to suit your needs. This component searches for an ADFS token in a
custom message header titled PassthroughBinarySecurityToken. If this token is found, the token is
validated by using the trusted issuer thumbprint of the ADFS STS and the claims that are extracted. A
Windows Account Name claim type identifies the user account. For more information, see
http://blogs.msdn.com/b/willpe/archive/2010/10/25/windows-authentication-adfs-and-the-access-
control-service.aspx.
Create custom authentication classes
A custom authentication component has two parts:
An X++ class that implements the AifAuthenticationManager interface and provides
configuration information.
A .NET class that implements the System.ServiceModel.ServiceAuthenticationManager
interface to provide runtime authentication.



32

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
AifAuthenticationManager interface
This X++ interface must be implemented by an X++ authentication manager class. This interface
is used by the services framework to get information that is used to configure and deploy the
custom authentication runtime component.

X++
interface AifAuthenticationManager
{
AifAuthenticationManagerName getName();
str getAuthenticationManagerType();
str getAuthorizationPolicyType();
AifAssemblyName getAuthenticationManagerAssemblyName();
Map getAppSettings();
MenuItemNameDisplay getConfigurationDisplayMenuItem;
}



Interface methods:
AifAuthenticationManagerName getName()
Returns the friendly name of the component. This is displayed for selection in the ServiceBus
configuration form.

str getAuthenticationManagerType()
Returns the .NET type of the WCF custom authentication class in the runtime assembly.

str getAuthorizationPolicyType()
Returns the .NET type of the WCF authorization policy class in the runtime assembly.

AifAssemblyName getAuthenticationManagerAssemblyName()
Returns the name of the authentication assembly that contains the WCF custom authentication
class.

Map getAppSettings()
Returns custom settings that are required by the .net authentication component at
authentication time. These settings are available in the AppSettings section of the web.config
file, which is located in the IIS website directory. Returns null if app settings are not required.

MenuItemNameDisplay getConfigurationDisplayMenuItem
Returns the name of the display menu item for the configuration form of this component.
Returns the empty string if no configuration form is available.


33

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Custom authentication component
A class that implements the following interfaces can perform custom authentication:
System.ServiceModel.ServiceAuthenticationManager
System.IdentityModel.Policy.IAuthorizationPolicy

The System.ServiceModel.ServiceAuthenticationManager interface contains the ReadOnlyCollection
method.

C#
ReadOnlyCollection<IAuthorizationPolicy> Authenticate(
ReadOnlyCollection<IAuthorizationPolicy> authPolicy,
Uri listenUri,
ref Message message)


The implementation of this method can inspect the request message and headers, perform the custom
authentication, and set the authenticated principal on the message as a property.

The System.IdentityModel.Policy.IAuthorizationPolicy interface has a the properties and the Evaluate
method shown in the following example:

C#
bool Evaluate(
EvaluationContext evaluationContext,
ref Object state
)

The implementation of the Evaluate method sets the authenticated principal and identity on the
security context of the message.
Registering the authentication component
Before an authentication component can be used, it must be registered with the Services framework.
The registerAuthenticationManager and unregisterAuthenticationManager methods on the
AifAuthenticationHelper class must be used to register and unregister the authentication component.
Create an X++ job that calls these X++ methods to register/unregister the authentication
components. When a component is registered, the .NET assembly is uploaded to the database so that
it is accessible to all AOS instances. The file path that you use must grant read permissions to the AOS
service account. For more information about the AOS service account, see
http://technet.microsoft.com/en-us/library/ee355089.aspx and http://technet.microsoft.com/en-
us/library/ee355089.aspx and http://technet.microsoft.com/en-us/library/jj585430.aspx.
The following code shows the methods and describes the parameters:

X++
static public void registerAuthenticationManager(
AifAuthenticationManagerClass authenticationManagerClass,
FilePath assemblyFolder,
boolean updateExisting = false)



34

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012

AuthenticationManagerClass is class ID of the X++ authentication manager class
AssemblyFolder is the path of the folder that contains the .net authentication manager
assembly.
UpdateExisting is the flag indicating that any existing assembly in the database should
updated with the assembly in the folder.

X++
static public void unregisterAuthenticationManager(
AifAuthenticationManagerClass authenticationManagerClass)

authenticationManagerClass is the class ID of the X++ authentication manager class

Encryption key containers

Encryption is used to protect confidential data in the web.config file. This requires a machine-level
key container to be created and configured on all the involved machines. We have provided scripts
for this process. Download the scripts here: http://blogs.msdn.com/b/aif/archive/2013/04/29/aif-
windows-azure-service-bus-adapter.aspx.
These scripts use the IIS configuration utility aspnet_regiis.exe to manage the key containers.

1. Create an exportable machine-level key container on the IIS computer. Go to the directory
where you want to export the container before running this script. In this example we use
the root of the C drive.
Windows Command Prompt
C:\> CreateKeyContainer MyKey

2. Export the key container to an XML file. The following script will export the key container
to MyKey.xml.
Windows Command Prompt
C:\> ExportKeyContainer MyKey


3. Import the key container into each machine (machine running IIS and machine running
the AOS).
Windows Command Prompt
C:\> ImportKeyContainer MyKey MyKey.xml

4. On each machine, grant the appropriate users access to the key containers.
For the IIS Machine, this user is the AppPool identity (which is the same as the BC proxy
account). For the AOS machine, this is the AOS account (Network Service or domain
account).

For a Domain account:
Windows Command Prompt
C:\> GrantAccessToKeyContainer MyKey domain\user



35

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
For a Network account:
Windows Command Prompt
C:\> GrantAccessToKeyContainer MyKey

5. Delete the exported MyKey.xml files. In this example, we exported the MyKey file to the
root of the C drive. This is important to prevent unauthorized access to the key container.
Publish AIF Service using the Service Bus Adapter
We are now going to publish the UnreconciledExpense service operation that we created in
Create the service operation.
Register your Service Bus namespace
1. Open the Microsoft Dynamics AX Client.
Click System administration > Setup > Services and Application Integration
Framework > Azure Service Bus Configuration .

2. Provide Service Bus details in the Azure Service Bus Configuration form:
a. Supply your Azure Service Bus namespace, which was created when you registered
the namespace by following instructions in Microsoft Dynamics AX Connector for
Mobile Applications.
b. Supply your Azure Service Bus issuer name and issuer secret.
c. For Deployment website, select the IIS website to deploy the service on.
d. For Class name, specify the authentication class that you registered.
e. Click Configure. The Mobile Authentication Configuration form is shown.
i. Enter the certificate thumbprint (from your ADFS).
ii. Click Close.
f. For the RSA key container name, type the name of the key container that you created
previously in the Encryption key containers section.
g. For a description, provide a description for the Service Bus namespace, as shown in
the following illustration:


36

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012

h. Click Close.
Deploy your AIF service to the Azure Service Bus
To create a new port to publish your service on:
1. Click System Administration > Services and Application Integration Framework >
Inbound Ports.
2. Click New to create a new port.
3. Type the name of the port. It is a best practice to incorporate the name that you used
for the Azure Service Bus namespace on the Azure Service Bus Configuration form (2-
a).
4. Type a description of the port to provide a description of the services that this port
hosts.
5. Select Azure Service Bus for Adapter.
6. Click the button beside the URI field to open the Select Azure Service Bus
Namespace form, and select the namespace that you created.
7. Click OK.




37

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
8. Click the Service Operations button, which is located below Service Contract
customizations.
9. Find the UnreconciledExpense service from Create the expense service operations in
the right-hand pane.
i. Select all of the operations on your service that you want to publish by
highlighting each one, and then clicking the < button.
ii. Click Close.
10. In the Inbound Ports form, highlight your port in the left-hand pane.
11. Click Activate.
12. The UnreconciledExpense Service is now published to IIS 7.5. The URL to access the
Microsoft Dynamics AX service through the Service Bus is displayed in the URI: field,
as shown in the previous illustration. For the example in this document, the URI field
should be:
https://ContosoMobile.servicebus.windows.net/UnreconciledExpense/xppservice.svc

You may now refer to the remainder of this document to develop the client that will
communicate with Microsoft Dynamics AX using the AX service that you have published to the
Windows Azure Service Bus.


38

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Develop the client to communicate data to the middle-tier
WCF service
In this example and the sample code provided, we have made use of a Windows Phone application
to represent a client for the backend service, but you are by no means limited to that. Clients could be
anything ranging from Windows 8 apps in C# or JavaScript to .NET services to websites.
Development requirements
Visual Studio 2010 with Windows Phone SDK 7.1 with the 7.8 update installed, or Visual Studio
2012 with Windows Phone SDK 8.0 installed.
The Service Bus component (Microsoft.ServiceBus.dll), which is included with the Windows Azure
Libraries for .NET. To install it, visit the Windows Azure SDK download page.
Overview
This section will guide you through creating a Windows Phone client application that will consume the
hosted Expense service on the Service Bus.
First, you will create a Windows Phone application project and generate a client proxy to consume the
middle-tier service. Then you will lay out the controls on the UI for accepting the required input from
the user and handling all the control and page events.
Create a Windows Phone application
Open Visual Studio, and create a Windows Phone app projectfor example, ContosoMobileApp.
For more information about Windows Phone development, see Getting started with developing for
Windows Phone. A recommended way for developing Windows Phone apps is to use the MVVM pattern
for Windows Phone apps. See Developing a Windows Phone Application using the MVVM Pattern.
Add the middle-tier WCF service reference
1. Right-click References, and add a service reference. You will need to enter the MEX URL that was
specified in the Create the middle-tier WCF service section.
Note: The middle-tier service must be running at this point, and its metadata endpoint must be
enabled, so that the client can fetch the metadata of the service and generate the client proxy file
(Reference.cs).


39

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012

2. Notice that a ServiceReferences.Clientconfig file is created. Make sure that the following binding
information for the client exists.
APP.CONFIG
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpRelayBinding_ExpenseServiceContract"
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://contosomobile.servicebus.windows.net/https/ExpenseService/"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpRelayBinding_ExpenseServiceContract"
contract="ExpenseServiceReference.ExpenseServiceContract"
name="BasicHttpRelayBinding_ExpenseServiceContract" />
</client>
</system.serviceModel>
</configuration>



40

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
If you want to access your MEX endpoint outside your domain during development, you could also
consider hosting the WCF services MEX endpoint on the Service Bus itself.
Lay out and set up the UI controls for required user input
After adding the service reference, look at the Reference.cs client proxy file that is generated. You will
see a method such as CreateExpenseAsync. This is the service operation that the app will call to
send across expense data. As you can see in the generated proxy, the values that need to be passed
in are the date, amount, currency string, and comments.
C#
public void CreateExpenseAsync(
System.DateTime dateTime, decimal amount, string currency, string comments)
{
this.CreateExpenseAsync(dateTime, amount, currency, comments, null);
}

Also remember that, in addition to sending the expense data, the app is required to do the following:
Authenticate to the Service Bus when making the service call.
Send the claims that identify the user sending the expense data, in the form of a SAML assertion
token.
We will walk you through the authentication implementation in the Implement active federation and
claims-based authorization for the mobile client section.
Based on these requirements, the app gathers the following data from the user:
Data for the service operation
Data for the authentication


41

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Data for the service operation
In the app project, create a new page, MainPage.xaml. We will design this page (together with its
MainPage.xaml.cs file) to store the expense data.

The user enters the expense data and then clicks the Upload button. We will see later how the
data is sent across to the service in the UploadClick event handler.


42

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Data for the authentication
In the app project, create a new page, Settings.xaml. We will design and implement this page
(together with its Settings.xaml.cs file) to store the data required for authentication. This data is
taken as input from the user.

The user name, password, service connection name (Windows Azure namespace), and
authentication server URL (the AD FS endpoint) are then used to authenticate the user for the
service operations.
The next step is to implement active federation for claims-based authentication to the Windows Azure
Service Bus by using ACS and AD FS.
Implement active federation and claims-based
authorization for the mobile client
Prerequisites (configuring the trusts)
1. Create the Windows Azure namespace and configure the Service Bus, as explained in Microsoft
Dynamics AX Connector for Mobile Applications.
2. Add the Service Bus as the relying party in the ACS. In this way, the ACS is responsible for
providing security to the Service Bus. For more information, see the Configuring the Access
Control Service; Configure the relying party applications section in Microsoft Dynamics AX
Connector for Mobile Applications.


43

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
3. Set up trust between AD FS 2.0 and the ACS.
The Active Directory server acts as the identity provider. It contains information about the
corporate users and authenticates a users identity. Configure AD FS on the Active Directory
server. The AD FS is also a security token service (STS) that provides security tokens to
requestors.
Configure AD FS to trust only requests coming from the ACS of the Service Bus for the
namespace that you created. For example, add the endpoint https://contosomobile-
sb.accesscontrol.windows.net as a relying party in the AD FS by providing the federation
metadata URL exposed by the ACS. For more information, see the Configuring an Active
Directory Federation Service for authentication section in Microsoft Dynamics AX Connector
for Mobile Applications.
Configure the ACS to trust claims coming from the AD FS. To do this, go to your namespaces
Management Portal for the ACS, and add the AD FS as an identity provider in the Identity
Provider configuration section. You will need to add the federation metadata URL exposed
by the AD FS server. For more information, see the Configuring the Access Control Service;
Add and configure the identity provider section in Microsoft Dynamics AX Connector for
Mobile Applications.
4. Map incoming claims to outgoing claims in the ACS. These claims will be inspected by Service Bus.
An incoming claim of the windowsaccountname type should be mapped to an outgoing claim of
the net.windows.servicebus.action type with a value of Send. (For more information, see the
Configuring the Access Control Service; Configure rule groups section in Microsoft Dynamics AX
Connector for Mobile Applications.) This will ensure that any authenticated user having the
windowsaccountname claim sent by the AD FS is authorized to send a message through the
Service Bus.
5. Set up trust between the middle-tier WCF service and the corporate AD FS.
The AD FS uses an X.509 token signing certificate issued by a CA to digitally sign the SAML token
containing the claims about the user. For more information, see the Configuring an Active
Directory Federation Service for authentication; Add/Configure the token signing certificate
section in Microsoft Dynamics AX Connector for Mobile Applications.
When setting up the trust, observe the following guidelines:
The X.509 token signing certificate needs to be installed in the Trusted Root Certification store
on the machine that hosts the middle-tier WCF service.
The thumbprint of the certificate should be made available to this service. By using this
thumbprint, the service can verify that the claims are from an authorized and trusted issuer.
Overview
After collecting the information from the user on the mobile device, we now need to submit the data
to Microsoft Dynamics AX. Only those users who are authenticated are authorized to send this data
through the Service Bus to Microsoft Dynamics AX. The ACS and AD FS (which acts as an identity
provider and a security token service) cooperate to authenticate and authorize Service Bus operations.
The claims obtained from the identity provider are also used to extract information about the user in
the middle-tier service. Authorization of Microsoft Dynamics AX users according to their Microsoft
Dynamics AX roles and privileges will be handled by the Microsoft Dynamics AX instance itself.
We use active federation and the WS-Trust security protocol to request a security token (containing
the required claim) from the identity provider (corporate AD FS).
After the security token is presented to the ACS, it recognizes the identity of the user. As was
mentioned in the prerequisites, the incoming claims are mapped to the Send outgoing claims that are
recognized by the Service Bus for which the ACS is providing security. A claim is then issued to the
client by the ACS in the form of a simple web token (SWT).


44

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
When the client is ready to send its message through the Service Bus endpoint, it presents the SWT,
thus granting it permission to send the message. For our solution, the client is also required to send
across to the middle-tier service, the SAML assertions token that it received from the AD FS. The
service then extracts the assertion claims, as we saw in the walkthrough for the middle-tier WCF
service.
The following steps will show how we implement the required authentication described earlier.
Development requirements
You can implement the authentication described in the next section in the same Windows Phone app
project or in a compatible Windows Phone class library, which you can then reference in the app (if
you plan to reuse the authentication code).
If you are implementing a client (Windows Phone 8 or Windows 8 Store app) in Visual Studio 2012,
consider creating a Portable Class Library for the authentication and including the library in your client
application.
Implementation
We will walk you through implementing the authentication by using sample code to show you how the
Expense Capture mobile application uses the SAML and SWT tokens to securely pass data through the
Service Bus to Microsoft Dynamics AX.
Setup
1. In the phone app (ContosoMobileApp) that we created earlier, create a new class named
AuthenticationProvider, and include the System.Net reference in it.
C#
using System.Net

2. Create an event for notification about completion of authentication. This event should provide
notification about errors and also success in authentication.
C#
/// <summary>
/// Delegate type for handling authentication completed events
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void AuthenticationCompletedEventHandler(object sender,
AuthenticationMessageArgs e);



45

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Here, AuthenticationMessageArgs is a class that defines custom EventArgs for storing custom
exception messages and a Boolean value for success.
C#
public class AuthenticationMessageArgs: EventArgs
{
public AuthenticationMessageArgs(AuthenticationMessage authenticationMessage)
{
this.AuthenticationMessage = authenticationMessage;
}

public AuthenticationMessage AuthenticationMessage { get; private set; }
}

public class AuthenticationMessage
{
public AuthenticationMessage(string message, bool isSuccess)
{
this.Message = message;
this.IsSuccess = isSuccess;
}

public string Message { get; set; }

public bool IsSuccess { get; set; }
}

C#
/// <summary>
/// Subscribe to this event to be notified of authentication completion messages,
/// both succeeded & failed.
/// </summary>
public event AuthenticationCompletedEventHandler AuthenticationCompleted;

/// <summary>
/// The On Completed method to be called
/// </summary>
/// <param name="args"></param>
private void OnAuthenticationCompleted(AuthenticationMessageArgs args)
{
AuthenticationCompletedEventHandler handler = AuthenticationCompleted;

if (handler != null)
{
handler(this, args);
}
}



46

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
3. Define member variables, such as those for storing the user credentials, and response SAML and
SWT tokens.
C#
UserCredentials credentials;
string azureNamespace = String.Empty;
string stsEndpoint = String.Empty;
string requestSecurityTokenPayload = String.Empty;
string requestSecurityTokenResponse = String.Empty;
DateTime stsAuthStartTime;
string acsPayload = String.Empty;
string samlAssertionToken = String.Empty;
string swtAcsToken = String.Empty;

Get user input
The next thing we need to do is accept the user inputthat is, the user name (in the form
domain\user alias), password, Federation Server (AD FS) endpoint URI, and Windows Azure
namespace.
C#
public AuthenticationProvider(
string userName, string password, string windowsazureNamespace, string stsEndpointUrl)
{
credentials = new UserCredentials(userName, password);
azureNamespace = windowsazureNamespace;
stsEndpoint = stsEndpointUrl;
}

After the Windows Azure namespace is provided, we can define the following endpoints, which are
required for the authentication process.
C#
/// <summary>
/// This read-only property is the relying party that is configured in ADFS. This value tells the
STS how
/// to respond (which token format, whether it's encrypted, which claims to include, token
lifetime, etc.)
/// </summary>
public string AppliesTo
{
get
{
return "https://" + azureNamespace + "-sb.accesscontrol.windows.net";
}
}

/// <summary>
/// This read-only property is the actual ACS endpoint we post the SAML token to, to acquire the
SWT
/// </summary>
public string AcsEndPoint
{


47

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
C#
get
{
return "https://" + azureNamespace + "-sb.accesscontrol.windows.net/WRAPv0.9/";
}
}

/// <summary>
/// This read-only property is the relying party that's configured in SB's ACS.
/// The value is a hint to the STS as to which rules to perform. By default, it's
/// http://[namespace].servicebus.windows.net/, but more specific endpoint configurations are
/// possible if needed.
/// </summary>
public string RelyingParty
{
get
{
return "http://" + azureNamespace + ".servicebus.windows.net/";
}
}

/// <summary>
/// This read-only property is the actual endpoint exposed on ServiceBus that the final service
/// call & security tokens will be sent to.
/// </summary>
public string ServiceEndpoint
{
get
{
return "https://" + azureNamespace + ".servicebus.windows.net/Expense/";
}
}



48

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Create and send the request for security token
Now we can create the request for security token (RST) and actively send the request to the identity
provider (AD FS).

1. Create the RST payload.
Create a string named StsUrlPayload with the following SOAP message format for the payload.
C#
/// <summary>
/// This is the actual payload of the SOAP message that will be sent to the STS
/// </summary>
private string StsUrlPayload = @"<s:Envelope xmlns:s=""http://www.w3.org/2003/05/soap-
envelope""
xmlns:a=""http://www.w3.org/2005/08/addressing""
xmlns:u=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-
1.0.xsd"">
<!--Header-->
<s:Header>
<a:Action s:mustUnderstand=""1"">http://docs.oasis-open.org/ws-sx/ws-
trust/200512/RST/Issue</a:Action>
<a:To s:mustUnderstand=""1"">{0}</a:To>
<o:Security s:mustUnderstand=""1"" xmlns:o=""http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"">
<u:Timestamp u:Id=""_0"">
<u:Created>{1}Z</u:Created>
<u:Expires>{2}Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id=""uuid-ea4cdc24-712d-4af7-9128-acb3db03b55f-1"">
<o:Username>{3}</o:Username>
<o:Password o:Type=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-
username-token-profile-1.0#PasswordText"">{4}</o:Password>
</o:UsernameToken>
</o:Security>


49

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
C#

</s:Header>

<s:Body>
<trust:RequestSecurityToken xmlns:trust=""http://docs.oasis-open.org/ws-sx/ws-
trust/200512"">
<wsp:AppliesTo xmlns:wsp=""http://schemas.xmlsoap.org/ws/2004/09/policy"">
<a:EndpointReference>
<a:Address>{5}</a:Address>
</a:EndpointReference>
</wsp:AppliesTo>
<trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-
trust/200512/Bearer</trust:KeyType>
<trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-
trust/200512/Issue</trust:RequestType>
<trust:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</trust:TokenType>
</trust:RequestSecurityToken>
</s:Body>
</s:Envelope>";

2. Insert the values for the highlighted parts in the StsUrlPayload string, and assign it to
requestSecurityTokenPayload.
C#
this.stsAuthStartTime = DateTime.UtcNow;

//Setting Expires time to request time + 5 minutes
requestSecurityTokenPayload =
String.Format(this.StsUrlPayload, this._stsEndpoint, this.stsAuthStartTime.ToString("s")
+ ".000",
this.stsAuthStartTime.AddMinutes(5).ToString("s") + ".000", credentials.Username,
credentials.Password, this.AppliesTo);



50

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
3. The SendRequestSecurityToken method is used to send the request across to the AD FS. These
are asynchronous SOAP message requests, and callback methods are used to write to the request
stream and receive the response.
C#
/// <summary>
/// Create the RST payload containing the user's credentials
/// Send the RST to the STS in a SOAP message using HttpWebRequest
/// </summary>
private void SendRequestSecurityToken()
{
this.stsAuthStartTime = DateTime.UtcNow;
requestSecurityTokenPayload = String.Format(this.StsUrlPayload, this._stsEndpoint,
this.stsAuthStartTime.ToString("s") + ".000",
this.stsAuthStartTime.AddMinutes(5).ToString("s") + ".000", credentials.Username,
credentials.Password, this.AppliesTo);

try
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(stsEndpoint);
httpWebRequest.ContentType = "application/soap+xml; charset=utf-8";
httpWebRequest.Method = "POST";
httpWebRequest.BeginGetRequestStream(
new AsyncCallback(RequestSecurityTokenStreamCallback), httpWebRequest);
}
catch (Exception e)
{
//Fire the event to be handled by the App in case there was an error during
authentication
OnAuthenticationCompleted(new AuthenticationMessageArgs(
new AuthenticationMessage(e.Message,false)));
}
}



51

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
C#
private void RequestSecurityTokenStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest httpWebRequest = (HttpWebRequest)asynchronousResult.AsyncState;
Stream requestStream = null;

try
{
using (requestStream = httpWebRequest.EndGetRequestStream(asynchronousResult))
{
if (requestStream != null)
{
byte[] bytes = Encoding.UTF8.GetBytes(requestSecurityTokenPayload);
requestStream.Write(bytes, 0, bytes.Length);
}
}


httpWebRequest.BeginGetResponse(
new AsyncCallback(RequestSecurityTokenResponseStreamCallback), httpWebRequest);
}

catch (Exception e)
{
OnAuthenticationCompleted(new AuthenticationMessageArgs(new
AuthenticationMessage(e.Message, false)));
}
}

4. The requestSecurityTokenResponse message contains the SAML token containing the
windowsaccountname claim for the user. After extracting the request for security token
response (RSTR) (by using the GetResponseStringFromResponse method), we call the
SendTokenToAcs method.
C#
/// <summary>
/// Helper method to extract the response string from an HttpWebResponse object.
/// </summary>
/// <param name="response">The HttpWebResponse object</param>
/// <returns>the response string contained in the http response.</returns>
public static string GetResponseStringFromResponse(HttpWebResponse response)
{
string responseString = string.Empty;

if (response != null)
{
Stream streamResponse = null;
try
{
streamResponse = response.GetResponseStream();
using (StreamReader streamRead = new StreamReader(streamResponse))
{


52

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
C#
streamResponse = null;
responseString = streamRead.ReadToEnd();
}
}
finally
{
if (streamResponse != null)
{
streamResponse.Dispose();
}
}
}

return responseString;
}

Create the ACS payload
1. The next step is to extract the SAML claims from the RSTR and construct the ACS payload.

GetSamlTokenFromResponseString is a utility method that looks for the <saml:Assertion>
element in the response string and returns the elements contents as the SAML token.
C#
public static string GetSamlTokenFromResponseString(string responseString)
{
string samlToken = string.Empty;



53

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
C#
// Parse the xml to find the <saml:Assertion> tag as per SAML11 standard.
// This is the ADFS token
StringReader reader = null;
try
{
reader = new StringReader(responseString);
using (XmlReader xmlparser = XmlReader.Create(reader))
{
reader = null;
while (xmlparser.Read())
{
switch (xmlparser.NodeType)
{
case XmlNodeType.Element:
string name = xmlparser.Name;
if (String.Equals(xmlparser.Name, "saml:Assertion"))
{
samlToken = xmlparser.ReadOuterXml();
}
break;
}
}
}
}
finally
{
if (reader != null)
{
reader.Dispose();
}
}
return samlToken;
}

C#
/// <summary>
/// Extracts the SAML assertions from the RSTR and sends a request to the ACS for a SWT token
/// </summary>
private void SendTokenToAcs()
{
const string acsPayloadFormat =
@"wrap_scope={0}&wrap_assertion={1}&wrap_assertion_format=SAML";

samlAssertionToken =
Utilities.GetSamlTokenFromResponseString(requestSecurityTokenResponse);

if (!String.IsNullOrEmpty(samlAssertionToken))
{
acsPayload = String.Format(acsPayloadFormat, Uri.EscapeDataString(RelyingParty),
Uri.EscapeDataString(samlAssertionToken));


54

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
C#

try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(AcsEndPoint);
request.ContentType = @"application/x-www-form-urlencoded";
request.Method = "POST";
request.BeginGetRequestStream(
new AsyncCallback(RequestAcsTokenStreamCallback), request);
}
catch (WebException e)
{
OnAuthenticationCompleted(new AuthenticationMessageArgs(
new AuthenticationMessage(e.Message, false)));
}
}

else
{
OnAuthenticationCompleted(new AuthenticationMessageArgs(
new AuthenticationMessage("SAML Token from STS is empty", false)));
}
}

2. The ACS payload containing the SAML token is written to the request stream and sent to the ACS
endpoint.
C#
private void RequestAcsTokenStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream requestStream = null;
try
{
using (requestStream = request.EndGetRequestStream(asynchronousResult))
{
if (requestStream != null)
{
byte[] bytes = Encoding.UTF8.GetBytes(acsPayload);
requestStream.Write(bytes, 0, bytes.Length);
}
}
request.BeginGetResponse(new AsyncCallback(RequestAcsTokenResponseCallback),
request);
}
catch (WebException e)
{
OnAuthenticationCompleted(new AuthenticationMessageArgs(new
AuthenticationMessage(e.Message, false)));
}
}



55

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
3. The ACS sends back a response containing the SWT security token that is required to authenticate
to the Service Bus.
C#
private void RequestAcsTokenResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

try
{
HttpWebResponse response =
(HttpWebResponse)request.EndGetResponse(asynchronousResult);
string rawAcsResponse = Utilities.GetResponseStringFromResponse(response);
SwtAcsToken = Uri.UnescapeDataString(rawAcsResponse.Split('&').Single(value =>
value.StartsWith("wrap_access_token=",
StringComparison.OrdinalIgnoreCase)).Split('=')[1]);

if (!String.IsNullOrEmpty(this.SwtAcsToken))
{
OnAuthenticationCompleted(new AuthenticationMessageArgs(new
AuthenticationMessage("Security Token from ACS issued successfully", true)));
}
}
catch (WebException e)
{
// The ACS server has likely sent back an error response
string responseString =
Utilities.GetResponseStringFromResponse((HttpWebResponse)e.Response);
OnAuthenticationCompleted(new AuthenticationMessageArgs(
new AuthenticationMessage(responseString, false)));
}
catch (System.FormatException)
{
// Error parsing ACS token; it is in an invalid format
OnAuthenticationCompleted(new AuthenticationMessageArgs(
new AuthenticationMessage("Invalid ACS Token Format", false)));
}
catch (System.ArgumentOutOfRangeException)
{
// Error parsing ACS token; it is in an invalid format
OnAuthenticationCompleted(new AuthenticationMessageArgs(
new AuthenticationMessage("Invalid ACS Token Format", false)));
}
catch (Exception e)
{
OnAuthenticationCompleted(new AuthenticationMessageArgs(
new AuthenticationMessage(e.Message, false)));
}
}

The SwtAcsToken value is extracted from the raw response string sent by the ACS, as shown in
the preceding code.


56

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
At this point a non-empty SWT with no other errors or exceptions implies that the authentication was
successful.
Additional notes and guidelines
To keep this exercise as simple and focused as possible, this code has been boiled down to its essence
and only contains the key principles required to understand the solution. In a production-level
application, you would want to take into account additional considerations, including your platform and
functional requirements. For example, your app does not have to request fresh tokens from both IdPs
every time it needs to make a service call. Because of this, it would be useful to implement some local
storage or caching of the security tokens until their expiration time. That expiration time is adjustable
on both AD FS and the ACS. Choose a token lifetime that makes sense for your scenario and security
requirements; for example, more business-sensitive applications should have shorter token lifetimes,
whereas low business-impact applications could have longer token lifetimes.
Regarding platform support, if you have access to the WIF libraries (for example, if you are writing a
.NET client), feel free to use them, because they will offer you slightly more robust RST and RSTR
processing. If you are working on any other platform, you may either search for library support on
that platform or follow the same pattern that you have implemented earlier.
Finally, when storing data in durable storage, always be sure to encrypt secret information, such as
the users credentials; this includes the security tokens and even the Service Bus secrets in the
app.config file.
Authenticate the user and send the data to the service
After authenticating the user by using active federation as described in the Implement active
federation and claims-based authorization for the mobile client section, the client can send its request
to the service endpoint. We now need to use the AuthenticationProvider object within the Windows
Phone app.
1. As is shown in the ContosoMobileApp application, when the user clicks the Submit/Save button,
we will handle the UploadClick event in the following way.
C#
private void UploadClick(object sender, EventArgs e)
{
Submit();
}

2. In the Submit method, we initialize the AuthenticationProvider object, subscribe to its
AuthenticationCompleted event, and then call the IssueToken method.
We pass in the user data that we collect from the Settings.xaml page to initialize the
AuthenticationProvider object; the following code shows an example of the user input that can
be passed in.


57

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
The IssueToken method is the starting point for the multiple asynchronous calls.
C#
public void Submit()
{
// parameters are domain\\userAlias, user's password, Azure Namespace & ADFS endpoint URL
authenticator = new AuthenticationProvider("contoso\\userAlias", "password",
"contosmobile",
"https://contosoadfs.com/adfs/services/trust/13/usernamemixed");

authenticator.AuthenticationCompleted += authenticator_AuthenticationCompleted;
authenticator.IssueToken();
}

C#
/// <summary>
/// Handle the Authentication completed event and then submit the expense using the tokens
/// if the authentication was successful
/// </summary>
private void authenticator_AuthenticationCompleted(object sender, AuthenticationMessageArgs
e)
{
if (e.AuthenticationMessage.IsSuccess)
{
// Authentication was successful. Now submit the expense through service bus,
// using the SWT and SAML token values exposed by the AuthenticationProvider
CreateExpense();
}
else
{
RaiseSubmitCompleted(new Exception(e.AuthenticationMessage.Message));
}
}



58

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
3. After the IssueToken asynchronous method is completed, the AuthenticationCompleted event
is fired. We then check whether the authentication was successful.
If the authentication was successful, the app is now in possession of the SWT (the token to
authenticate to the Service Bus) and the SAML token (the token containing the
windowsaccountname claim that is used to set the call context of the AIF service call). We then
insert the two tokens into a custom SOAP header of the message. The body of the message will
contain the expense data we want to send to the middle-tier WCF service.

4. Add a method named CreateExpense that creates the message as described in the previous step
and sends it to the actual service endpoint on the Service Busthat is, https://<AzureNamespace
>servicebus.windows.net/Expense/.
A call is then made to the CreateExpenseAsync service operation by using the middle-tier
services ExpenseServiceContractClient client proxy.
C#
private void CreateExpense()
{
ExpenseServiceReference.ExpenseServiceContractClient expenseService =
new ExpenseServiceReference.ExpenseServiceContractClient();

expenseService.Endpoint.Address = new System.ServiceModel.EndpointAddress(
new Uri(SettingsViewModel.ServiceEndpoint));

expenseService.CreateExpenseCompleted +=
new EventHandler<CreateExpenseCompletedEventArgs>(OnCreateExpenseCompleted);

// Get the channel context scope so we can add message headers to it
using (new OperationContextScope(expenseService.InnerChannel))


59

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
C#
{
// Grab the raw SAML token and stuff it in a byte array
byte[] binToken = Encoding.UTF8.GetBytes(authenticator.SamlAssertionToken);

// Add the SAML token to a custom SOAP header
var customSecurityHeader =
MessageHeader.CreateHeader("PassthroughBinarySecurityToken", "",
Convert.ToBase64String(binToken));

OperationContext.Current.OutgoingMessageHeaders.Add(customSecurityHeader);

// Add the SWT token to a SOAP header as SB is expecting
OperationContext.Current.OutgoingMessageHeaders.Add(
new AcsHeader(authenticator.SwtAcsToken));

// Finally, call the actual service to create our expense.
expenseService.CreateExpenseAsync(
ExpenseDate, Amount, Amount == 0? null : Currency, Comment);
}
}

C#
/// <summary>
/// This is the Custom (SOAP header) format that Service Bus requires a token
/// from ACS to exist in the message. This header will be stripped out by SB
/// and thus will not exist when the message gets to the service.
/// </summary>
/// <remarks>
/// Leave all these hard-coded values alone, SB is expecting
/// a very particular format for this header.
/// </remarks>
private class AcsHeader : MessageHeader
{
private string token;

public AcsHeader(string token)
{
this.token = token;
}

public override string Name
{
get { return "RelayAccessToken"; }
}

public override string Namespace
{
get { return "http://schemas.microsoft.com/netservices/2009/05/servicebus/connect"; }
}



60

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
C#
protected override void OnWriteHeaderContents(
XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteStartElement("BinarySecurityToken", "http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
writer.WriteAttributeString("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-wssecurity-utility-1.0.xsd",
string.Format("uuid:{0}", Guid.NewGuid().ToString("D")));
writer.WriteAttributeString("ValueType", "http://schemas.xmlsoap.org/ws/2009/11/swt-
token-profile-1.0");
writer.WriteAttributeString("EncodingType", "http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");

byte[] binToken = Encoding.UTF8.GetBytes(token);
writer.WriteBase64(binToken, 0, binToken.Length);

writer.WriteEndElement();
}
}

The request is then sent to the endpoint on the Service Bus. The Service Bus authorizes the
incoming message to be relayed through it to the middle-tier WCF service, by examining the SWT.
The expense data and the SAML token are then passed to the middle-tier service.
The Service Bus also relays back the response from the WCF service after the operation is
completed. An event is raised to notify about completion.
In this example, you can also create a custom completed notification event to handle the response
(success or error messages) within the application and send a message that can be viewed by the
user. In the preceding code sample, we subscribe to a custom event, CreateExpenseCompleted,
to accomplish this.
Developing RESTful JavaScript mobile apps for Microsoft
Dynamics AX 2012
Creating secure mobile apps for Microsoft Dynamics AX 2012 is not restricted to clients that are built
on the .NET runtime, such as Windows Phone and Windows Store apps. As we indicated earlier, you
can also create mobile apps by using cross-platform technologies such as HTML5 and JavaScript.
The solution architecture for creating such apps remains the same, as described in the Technical
overview section. This means that you can still create secure apps for mobile clients by using active
federation and claims-based identity for authentication, given the users corporate credentials and
using the Windows Azure Service Bus relay to transport the messages from the client to the middle-
tier WCF service, which in turn would send the data across to Microsoft Dynamics AX by using AIF
services.


61

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
The following table demonstrates a mapping between apps that use the .NET Framework and apps
that use HTML5 and JavaScript with respect to the various components in the architecture.
.NET Framework HTML5/JavaScript
Microsoft Dynamics AX AIF
service
Creating AIF services is described in
the Design and create the AIF
service in Microsoft Dynamics AX
2012 section.
No change
Middle-tier WCF service A SOAP-based service with a
BasicHttpRelayBinding binding. The
SAML token is in the SOAP header.
A RESTful service with a
WebHttpRelayBinding binding. The
SAML token is in the request body.
Configuration (AD FS, Windows
Azure Service Bus, ACS)
The configuration required for
setting up AD FS, token signing
certificates, and the Windows Azure
Service Bus and ACS is described in
Microsoft Dynamics AX Connector
for Mobile Applications.
No change
Active federation for
authentication
Implemented by using .NET
technologies (WCF and System.NET
APIs). For more information, see
the Implement active federation
and claims-based authorization for
the mobile client section.
No change in request payloads to
AD FS.
Implemented by using JavaScript
and JQuery for asynchronous
communication.
Fetching tokens, claims, and
communication to the WCF
service
Implemented by using .NET
technologies (WCF and System.NET
APIs).
The SAML token with claims is sent
in a custom SOAP header, together
with the SWT for the Service Bus.
For more information, see the
Authenticate the user and send the
data to the service section.
No change in the request for a SWT
sent to the ACS.
However, the SAML token is sent in
the request body of the JSON
payload. The SWT is sent in the
HTTP Authorization header.
Mobile client UI Accepts user input.
Implemented by using .NET
technologies (for example, for
Windows Phone and Windows Store
apps).
Accepts user input.
Can be implemented by using
HTML5, for example.

The following walkthrough provides guidance in creating RESTful JavaScript mobile apps and uses the
same expense capture example that was used in earlier sections.
Design and create the AIF service in Microsoft Dynamics AX 2012
The steps to create the AIF service for our expense example remain the same as described in the
Design and create the AIF service in Microsoft Dynamics AX 2012 section.
Create the middle-tier RESTful service
This section will now walk you through creating a RESTful service by using WCF. You can create this
service in a way that is very similar to the WCF SOAP service that we created in the Create the
middle-tier WCF service section, except that we now create and configure the service to deploy
RESTful service endpoints on the Service Bus.
Before you complete this walkthrough, you could also see the Create the middle-tier WCF service
section to help you understand the following:
Setting up the Service Bus relay and deploying the listening endpoint


62

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Using Windows Identity Foundation to validate incoming messages and extract the users claims
Adding the AIF service reference
Building and creating an installer, and deploying the Windows service
Prerequisites
An X.509 token signing certificate is installed on the AD FS server and on the machine running the
WCF service, in the Trusted Root Certification Authorities store. For guidance, see Microsoft
Dynamics AX Connector for Mobile Applications.
You have the thumbprint from that certificate.
A Windows Azure Service Bus namespace has been created, and the shared secret and issuer
name for the namespace are available. For guidance, see Microsoft Dynamics AX Connector for
Mobile Applications.
The machine that the middle-tier WCF service runs on should be in the same domain or on the
same network as the Microsoft Dynamics AX 2012 AOS machine (which can be the same machine
or a different one).
Development requirements
Visual Studio 2010 and the .NET Framework version 4
The Service Bus component (Microsoft.ServiceBus.dll), which is included with the Windows Azure
Libraries for .NET. To install it, visit the Windows Azure SDK download page.
The Windows Identity foundation runtime, which can be downloaded from Windows Identity
Foundation SDK. Download the 4.0 version for Visual Studio 2010 and the .NET Framework
version 4.0.
For more information about the WIF SDK, see Windows Identity Foundation SDK.
Create the data contract, service contract, and operation contract
1. Open Visual Studio, and create a new Windows Service .NET Framework version 4 project
named ExpenseConnectorService.
2. Add the System.ServiceModel.Web reference to the project.
3. Rename the Service1.cs class ConnectorService.cs. This class contains the OnStart and
OnStop methods for the Windows service, which we will use to open a listening endpoint.


63

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
4. Include the System.ServiceModel.Web namespace in this class.
C#
using System;
using System.ServiceModel.Web;
using System.ServiceProcess;

namespace ExpenseConnectorService
{
public partial class ConnectorService : ServiceBase
{
private WebServiceHost host;

public ConnectorService()
{
InitializeComponent();
}

protected override void OnStart(string[] args)
{
// Deploy the endpoint
}

protected override void OnStop()
{
// Close the endpoint connection
}
}
}

5. Add the System.Runtime.Serialization reference to the project.
6. Add a new C# class for the data contract, named ExpenseData, to the project, and include the
System.Runtime.Serialization namespace. Add the data members to this serializable object, as
shown here.
C#
[DataContract]
public class ExpenseData
{
[DataMember]
public decimal Amount { get; set; }

[DataMember]
public string Comments { get; set; }

[DataMember]
public string CurrencyCode { get; set; }

[DataMember]
public string Date { get; set; }
}



64

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
7. Add the System.ServiceModel reference to the project.
8. Add a new C# interface for the service contract, named IExpenseRestService, to the project,
and create the service contract and operation contract as shown here. Include the
System.ServiceModel namespace.
C#
[ServiceContract(Name="ExpenseRestServiceContract", Namespace =
"http://samples.microsoft.com/DynamicsAx/")]
public interface IExpenseRestServiceContract
{
[OperationContract]
long CreateExpense(string adfsToken, ExpenseData expenseData);
}

9. Create another C# class for the service operation implementation, which implements
IExpenseRestServiceContract. Include the System.ServiceModel.Web namespace in this class.
C#
using System;
using System.IO;
using System.Linq;
using System.ServiceModel.Web;
using System.Xml;

namespace ExpenseConnectorService
{
public class ExpenseRestService: IExpenseRestServiceContract
{
[WebInvoke(
UriTemplate = "Expense?Action=Create", //
URI:"https://<azurenamespace>.servicebus.windows.net/ExpenseRestService/Expense?Ac
tion=Create"
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public long CreateExpense(string adfsToken, ExpenseData expenseData)
{
// Implementation
}
}

10. The CreateExpense service operation needs to be handled by the WCF REST programming
model. To do this, we need to specify the following:
WebInvoke attribute for the service operation: This lets us map the service operation to the
HTTP verb POST and place the SAML token in the body of the HTTP request.
UriTemplate: This is the URI that is mapped to the operation that the client will send its
request to.
The endpoint that we deploy on the Service Bus will be in the form
https://<azurenamespace>.servicebus.windows.net/ExpenseRestService, and therefore the
CreateExpense service operation will be mapped to
https://<azurenamespace>.servicebus.windows.net/ExpenseRestService/Expense?Action=Cre
ate, as shown in the preceding code.


65

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
RequestFormat and ResponseFormat: These indicate that we will be sending messages to
and from the client in the form of JSON payloads.
Observe the two parameters in the service operation. The first is adfsToken, which is the SAML
token that is acquired from the corporate AD FS by the client. This token contains the
windowsaccountname claim that identifies the user making the request and will be used to set
the CallContext property when the AIF service call is made. For more information about the
CallContext property, see the Call the AIF service operations section.
The second parameter is data that comes from the client. This contains the expense data we
defined in the serializable data contract.
Both these parameters exist in the incoming JSON body of the payload.
Add a service reference of the AIF service
See the Add a service reference of the AIF service section.
Call the AIF service operations
Create a new private method named SubmitExpenseToAX. For this example, pass in the
windowsAccountName string and the ExpenseData object. For more information, see the Call the
AIF service operations section.
C#
private long SubmitExpenseToAX(ExpenseData expenseData, string windowsAccountName)
{
UnreconciledExpenseRecord record = new UnreconciledExpenseRecord()
{
parmNotes = expenseData.Comments,
parmTransactionCurrencyAmount = expenseData.Amount,
parmTransactionDate = DateTime.Parse(expenseData.Date),
parmTransactionCurrencyCode = expenseData.CurrencyCode
};

using (UnreconciledExpenseServiceClient client = new
AXExpenseServiceReference.UnreconciledExpenseServiceClient())
{
UnreconciledExpenseRecord expenseRecord = record;
CallContext callContext = new CallContext() { LogonAsUser = windowsAccountName };
return client.createRecord(callContext, expenseRecord);
}
}

Configure the RESTful service bindings and deploy the listening endpoint on
Service Bus
The Set up the Service Bus relay and deploying the listening endpoint for the middle-tier WCF service
section describes in detail the bindings required for a SOAP service to communicate with the Service
Bus. In a very similar way, we need to set up a WebHttpRelayBinding binding to deploy the RESTful
services listening endpoint on the Service Bus. You will need to update the app.config file to add the
binding and specify the Service Bus credentials.


66

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
1. Define the WebHttpRelayBinding configuration by adding the following under the <bindings>
element in the <system.serviceModel> section. Set the relayClientAuthenticationType
parameter to RelayAccessToken, which forces clients of the service to authenticate to the
Service Bus before sending across any messages.
APP.CONFIG
<bindings>
<webHttpRelayBinding>
<binding name="WebHttpRelayBinding_ServiceBus">
<security mode="Transport" relayClientAuthenticationType="RelayAccessToken"/>
</binding>
</webHttpRelayBinding>
</bindings>

2. Define configuration values for the endpoint behavior.
APP.CONFIG
<behaviors>
<endpointBehaviors>
<behavior name="sharedSecretClientCredentials">
<transportClientEndpointBehavior credentialType="SharedSecret">
<clientCredentials>

<!-- The issuerName & issuerSecret here should be set to the values
for the service account on Service Bus you wish to use to listen.
By default, the namespace will come with an admin user (issuerName) of
"owner" with a 256-bit secret key (issuerSecret) available in the
Windows Azure management portal. -->
<sharedSecret issuerName="owner"
issuerSecret="xxxxxxxxx/xxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxx="/>
</clientCredentials>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>



67

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
3. Deploy the listening endpoint. Add the following code snippet in the app.config file, under the
<services> element.
APP.CONFIG
<services>
<service name="ExpenseConnectorService.ExpenseRestService">
<endpoint address="" behaviorConfiguration="sharedSecretClientCredentials"
binding="webHttpRelayBinding"
contract="ExpenseConnectorService.IExpenseRestServiceContract"/>

<host>
<baseAddresses>
<!-- This baseAddress should be set to the URI you intend to
listen to on the Service Bus. It should be of the form:
"https://<APPFABRIC_NAMESPACE>.servicebus.windows.net/Expense/" -->
<add baseAddress="https://contosomobile.servicebus.windows.net/ExpenseRest/"/>
</baseAddresses>
</host>
</service>
</services>

4. We also need to update the app.config file to register the preceding Service Bus behavior and
binding extensions.
APP.CONFIG
<extensions>
<behaviorExtensions>
<add name="transportClientEndpointBehavior"
type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement,
Microsoft.ServiceBus, Version=1.7.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>

<bindingExtensions>
<add name="webHttpRelayBinding"
type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement,
Microsoft.ServiceBus, Version=1.7.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
</bindingExtensions>
</extensions>



68

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
5. Finally, open the Service Bus connection, and start listening on the endpoint.
Add the following code snippets to the OnStart method in the ConnectorService class.
C#
protected override void OnStart(string[] args)
{
// Note that all binding, endpoint, service, behavior configuration
// for this WebServiceHost is located in the app.config
host = new WebServiceHost(typeof(ExpenseConnectorService.ExpenseRestService));
WriteToEventViewer("Opening the Service endpoint connection " +
host.BaseAddresses[0].ToString());

try
{
host.Open();
WriteToEventViewer(string.Format("Listening on: {0}",
host.Description.Endpoints.Find(
typeof(ExpenseConnectorService.IExpenseRestServiceContract)).Address));
}
catch (Exception e)
{
WriteToEventViewer(e.Message);
}
}

C#
private void WriteToEventViewer(string eventMessage)
{
string source = "Expense WCF Service";

if (!EventLog.SourceExists(source))
{ EventLog.CreateEventSource(source, "Application"); }
EventLog.WriteEntry(source, eventMessage, EventLogEntryType.Information);
}

C#
protected override void OnStop()
{
host.Close();
}

Validate and extract contents from incoming JSON messages
The Validate and extract contents from incoming messages section explains, in detail, more about the
SAML token and the claims extracted, and also the use of WIF to validate the token from the trusted
issuer.
You will need to process the incoming JSON message to extract the claims and the expense data. The
client sends a POST request containing the parameter values for adfsToken and expenseData in the
request body itself;, therefore, you can easily extract the claims from the adfsToken parameter and
the ExpenseData object from the expenseData parameter.


69

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
You will also need to add the configuration required by Windows Identity Foundation to handle the
incoming SAML tokens (that is, the thumbprint for the X.509 token signing certificate, as described in
the Validate and extract contents from incoming messages section).
1. Update the app.config file under the <configuration> node, adding configuration values for
handling the SAML security token issued by the AD FS.
The issuer (also known as the identity providerin our case, the corporate AD FS) uses a token
signing certificate to digitally sign the SAML token.
APP.CONFIG
<microsoft.identityModel>
<service>
<securityTokenHandlers>
<securityTokenHandlerConfiguration>
<audienceUris mode="Never"/>
<issuerNameRegistry
type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry,
Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35">

<trustedIssuers>
<!-- The STS that issues the SAML token exchanged
at ACS must be added as a trusted issuer here.
The thumbprint & name values should be obtainable from the
public signing certificate exposed on the STS' federation metadata -->
<add
thumbprint="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
name=""/>
</trustedIssuers>
</issuerNameRegistry>
</securityTokenHandlerConfiguration>
</securityTokenHandlers>
</service>
</microsoft.identityModel>

APP.CONFIG
<configSections>
<section name="microsoft.identityModel"
type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection,
Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
</configSections>

2. Add Microsoft.IdentityModel and System.IdentityModel references to the project, and add the
following namespaces to the ExpenseRestService.cs file.
C#
using System.IdentityModel.Tokens;
using System.Security.Principal;
using Microsoft.IdentityModel.Claims;
using Microsoft.IdentityModel.Configuration;



70

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
3. Add an implementation to the CreateExpense service operation to do the following:
1. Extract the security token containing the SAML assertions from the adfsToken parameter
value. This information is passed by the mobile client calling the service.
2. Use WIF to validate the token by using the thumbprint and other configuration values from the
service configuration.
3. Extract the required claim (windowsaccountname) from the token.
4. Make the call to the SubmitExpenseToAX method, which will make the AIF service call. Pass
the expenseData value in the call that will be sent to the AIF service.
C#
[WebInvoke(
UriTemplate = "Expense?Action=Create", //
URI:"https://<azurenamespace>.servicebus.windows.net/ExpenseRestService/Expense?Action
=Create"
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public long CreateExpense(string adfsToken, ExpenseData expenseData)
{
string windowsAccountName = string.Empty;

// Extract the 'adfsToken' from the message body
string samlTokenString = Uri.UnescapeDataString(adfsToken);

// Load the app.config settings where we specify the audience & issuer that we'll
// accept in a token
var config = new ServiceConfiguration();
var handler =
config.SecurityTokenHandlers[
Microsoft.IdentityModel.Tokens.SecurityTokenTypes.Saml11TokenProfile11];

ClaimsIdentityCollection claimsIdentity = null;

// Convert the raw token into something that can be inspected
using (XmlReader reader = XmlReader.Create(new StringReader(samlTokenString)))
{
SecurityToken token = handler.ReadToken(reader);

// This is the primary WIF call that
// 1) Performs all the token validation
// a. Format, token type, key type, version, etc.
// b. Expiration
// c. Audience/AppliesTo/Relying party
// d. Issuer
// e. Signature
// 2) generates a ClaimsIdentityCollection that contains what the app actually //
cares about

claimsIdentity = handler.ValidateToken(token);
}



71

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
C#
IPrincipal principal = new ClaimsPrincipal(claimsIdentity);
IClaimsIdentity identity = (IClaimsIdentity)principal.Identity;

windowsAccountName = identity.Claims.Single(claim => claim.ClaimType ==
"http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname").Value;

return SubmitExpenseToAX(expenseData, windowsAccountName);
}

Create an HTML5/JavaScript app to communicate data to the WCF
middle-tier RESTful service
Mobile apps can be created by using commonly known web technologies, such as HTML5, CSS3, and
JavaScript. HTML5 and style sheets can be combined to produce impressive user interfaces, which you
can use to obtain user input. In our expense capture example, the client could be designed to capture
the following user input:
Expense data, such as the amount, currency, date, and comments
Authentication data, such as the following:
The users alias and password
The Windows Azure Service Bus namespace hosting the back-end services endpoint
The endpoint URL of the AD FS server that is required for active federation
This document will not cover the creation of the user interface itself, but will instead focus on the
client-side authentication and service calls.
Implement active federation and claims-based authorization for the
mobile client by using JavaScript
We now move on to implementing the authentication required for communicating to the back-end
middle-tier RESTful service through the Service Bus. To help understand more about the
authentication process, the prerequisites, and the configuration of trusts between AD FS and the ACS,
the ACS and the Service Bus, and AD FS and the middle-tier WCF service, see the Implement active
federation and claims-based authorization for the mobile client section.
The code samples below will demonstrate how you can achieve the following in JavaScript (using AJAX
for asynchronous communication):
Send AD FS a request for security token (RST) containing the users credentials
Extract the claim (SAML token) from the request for security token response (RSTR) returned from
the AD FS
Send a request containing the claim token in exchange for a simple web token (SWT) from the
Service Buss ACS.
Extract the SWT from the response received from the ACS.


72

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
In the following sample, we define a JavaScript AuthenticationProvider object that contains
methods for fetching the SAML token from AD FS and the SWT from the ACS.
JAVASCRIPT
function AuthenticationProvider() {
// ADFS token variables
var _ADFSEndpoint = 'https://contosoadfs.com/adfs/services/trust/13/usernamemixed';
var _ADFSEncodedToken = '';
var _ACSEncodedToken = '';

// user credentials (to be obtained from the user interface)
var _userName = 'contoso\\userAlias';
var _password = 'password';

// Azure namespace
var _serviceNamespace = 'contosomobile';

// Gets encoded SAML Token from ADFS in response to the Request for Security Token (RST)
this.getADFSToken = function getADFSToken(success, error) {

// prepare parameters for the web-service call
var ADFSUrlPayload = ["<s:Envelope xmlns:a='http://www.w3.org/2005/08/addressing\'
xmlns:s='http://www.w3.org/2003/05/soap-envelope'>",
"<s:Header>",
"<a:Action s:mustUnderstand='1'>http://docs.oasis-
open.org/ws-sx/ws-trust/200512/RST/Issue</a:Action>",
"<Security s:mustUnderstand='1'
xmlns:u='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'",
" xmlns='http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-wssecurity-secext-1.0.xsd'>",
"<UsernameToken u:Id='45dcb005-1a5b-4c9d-b26e-
cb9ab35f7b26'>",
"<Username>", _userName, "</Username>",
"<Password Type='http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText'>", _password,
"</Password>",
"</UsernameToken>",
"</Security>",
"<a:To s:mustUnderstand='1'>", _ADFSEndpoint, "</a:To>",
"</s:Header>",
"<s:Body>",
"<trust:RequestSecurityToken
xmlns:trust='http://docs.oasis-open.org/ws-sx/ws-trust/200512'>",
"<wsp:AppliesTo
xmlns:wsp='http://schemas.xmlsoap.org/ws/2004/09/policy'>",
"<a:EndpointReference>",
"<a:Address>https://", _serviceNamespace, "-
sb.accesscontrol.windows.net/</a:Address>",
"</a:EndpointReference>",
"</wsp:AppliesTo>",
"<trust:RequestType>http://docs.oasis-open.org/ws-
sx/ws-trust/200512/Issue</trust:RequestType>",
"<trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-
trust/200512/Bearer</trust:KeyType>",
"</trust:RequestSecurityToken>",


73

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
JAVASCRIPT
"</s:Body>",
"</s:Envelope>"].join("");

// Ajax call to send the request to AD FS
$.ajax({
url: _ADFSEndpoint + "/",
type: "POST",
contentType: "application/soap+xml",
dataType: "xml",
data: ADFSUrlPayload,

success: function (data, textStatus, jqXHR) {
var response = jqXHR.responseText;

// Get the SAML assertion token from the response
var startIndex = response.indexOf("<saml:Assertion");
if (startIndex != -1) {
var endIndex = response.indexOf("/saml:Assertion");
var _ADFSRawToken = response.substring(parseInt(startIndex),
(parseInt(endIndex) + parseInt(16)));
_ADFSEncodedToken = encodeURIComponent(_ADFSRawToken);

// Fire the successful event
if (success && $.isFunction(success)) {
success(_ADFSEncodedToken);
}
}
},
error: function (jqXHR, textStatus, errorThrown) {
// Fire the failure event
if (error && $.isFunction(error)) {
error(textStatus, errorThrown);
}
}
});
}

// Get the ACS SWT token by sending the ACS the ADFSEncodedToken containing the identity
// claims about the user (windowsaccountname) in a specific format
this.getACSToken = function getACSToken(success, error) {
$.ajax({
type: "POST",
url: "https://" + _serviceNamespace + "-sb.accesscontrol.windows.net/WRAPv0.9/",
contentType: "application/x-www-form-urlencoded",
data: 'wrap_scope=http%3a%2f%2f' + _serviceNamespace +
'.servicebus.windows.net%2f&wrap_assertion=' + _ADFSEncodedToken + '&wrap_assertion_format=SAML',
dataType: "text",

success: function (data, textStatus, jqXHR) {
var response = decodeURIComponent(jqXHR.responseText);



74

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
JAVASCRIPT
// Get the SWT token from the response
var endIndexToken = response.indexOf('&wrap_access_token_expires_in');
_ACSEncodedToken = response.substring(18, endIndexToken);

// Fire the successful event
if (success && $.isFunction(success)) {
success(_ACSEncodedToken);
}
},
error: function (jqXHR, textStatus, errorThrown) {
// Fire the failure event
if (error && $.isFunction(error)) {
error(textStatus, errorThrown);
}
}
});
}
}

Send the request payload to the REST service
After the expense data is captured from the user, the data, together with the authentication tokens,
needs to be sent in the request to the back-end service operation CreateExpense.
In the following code sample, we create a ServiceRequest object whose send method does the
following:
Create a request message containing the SWT in the header, and the SAML token together with
the user data (expense data in our example), in the request body
Send the message to the endpoint URI of the RESTful service operation through the Service Bus
relay.
JAVASCRIPT
function ServiceRequest() {
this.send = function send(adfsEncodedToken, acsEncodedToken, success, error) {

// Create the payload for the RESTful service at the backend containing the expenseData
// and the adfstoken
var expenseObj = {
"Amount": "100",
"Comments": "Expense of 100 EUR",
"CurrencyCode": "EUR",
"Date": "02/02/2013"
};

var payload = {
"adfsToken": adfsEncodedToken,
"expenseData": expenseObj
};

// The token sent to Service Bus relay needs to be in a particular format


75

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
JAVASCRIPT
var relayToken = 'WRAP access_token="' + acsEncodedToken + '"';
var payloadJSON = JSON.stringify(payload);

// Make the AJAX call to invoke the service operation mapped to a specific URL
// The relay token goes into the header of the request going through Service Bus
$.ajax({
type: "POST",
url:
'https://contosomobile.servicebus.windows.net/ExpenseRestService/Expense?Action=Create',
beforeSend: function (jqXHR) {
jqXHR.setRequestHeader('Authorization', relayToken);
},
contentType: 'application/json; charset=utf-8',
data: payloadJSON,
processData: false,
datatype: "json",
success: function (data, textStatus, jqXHR) {
// Fire the success event
if (success && $.isFunction(success)) {
success(data);
}
},
error: function (jqXHR, textStatus, errorThrown) {
// Fire the failure event
if (error && $.isFunction(error)) {
error(textStatus, errorThrown);
}
}
});
}
}

Finally, use the AuthenticationProvider object implemented earlier to begin the series of
asynchronous calls to the getADFSToken and getACSToken methods, and then send across the
request to invoke the service operation in the middle-tier service.
JAVASCRIPT
<script type="text/javascript">
var adfsToken = '';
var acsToken = '';
var authProvider = new AuthenticationProvider();

//Fire off the asynchronous calls on clicking a submit button for example
$('#submit').click(function (evt) {
//Support cross domain requests
$.support.cors = true;
authProvider.getADFSToken(adfsSuccess, adfsError);
});

var adfsError = function (textStatus, errorThrown) {
console.log(textStatus + ": " + errorThrown);


76

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
JAVASCRIPT
}

var adfsSuccess = function (_ADFSEncodedToken) {
adfsToken = _ADFSEncodedToken;
authProvider.getACSToken(acsSuccess, acsError);
}

var serviceRequest = new ServiceRequest();

var acsError = function (textStatus, errorThrown) {
console.log(textStatus + ": " + errorThrown);
}
var acsSuccess = function (_ACSEncodedToken) {
acsToken = _ACSEncodedToken;
serviceRequest.send(adfsToken, acsToken, submitSuccess, submitError);
}

var submitSuccess = function (result) {
console.log("Success!");
}

var submitError = function (textStatus, errorThrown) {
console.log(textStatus + ": " + errorThrown);
}
</script>



77

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Additional resources
Microsoft Dynamics AX Connector for Mobile Applications
Walkthrough: Exposing an X++ Class as a Data Contract [AX 2012]
Walkthrough: Creating a Windows Service Application in the Component Designer
Specify the .NET Business Connector proxy account [AX 2012]
Getting started with developing for Windows Phone
Developing a Windows Phone Application using the MVVM Pattern
Download Windows Azure
Download Windows Identity Foundation SDK
Windows Identity Foundation SDK


78

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
The computer code, including developer tools and sample code (software) included with this document is made available to you
under the software license agreement that appear below.

Microsoft Dynamics AX Sample License

This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the
license, do not use the software.

1. Definitions
The terms reproduce, reproduction, derivative works, and distribution have the same meaning here as under U.S. copyright
law.
A contribution is the original software or any additions or changes to the software.
A contributor is any person that distributes its contribution under this license.
Licensed patents are a contributors patent claims that read directly on its contribution.

2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each
contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative
works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor
grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale,
import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.

3. Conditions and Limitations
(A) No Trademark License - This license does not grant you rights to use any contributors name, logo, or trademarks.
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent
license from such contributor to the software ends automatically.
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are
present in the software.
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete
copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may
only do so under a license that complies with this license.
(E) The software is licensed as-is. You bear the risk of using it. The contributors give no express warranties, guarantees or
conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose
and non-infringement.
(F) Platform Limitation- The licenses granted in sections 2(A) & 2(B) extend only to the software or derivative works that operates
with Microsoft Dynamics AX.



79

DEVELOPING SECURE MOBILE APPS FOR MICROSOFT DYNAMICS AX 2012
Microsoft Dynamics is a line of integrated, adaptable business management solutions that enables you and your
people to make business decisions with greater confidence. Microsoft Dynamics works like and with familiar
Microsoft software, automating and streamlining financial, customer relationship, and supply chain processes in a
way that helps you drive business success.

U.S. and Canada Toll-Free 1-888-477-7989
Worldwide +1-701-281-6500
www.microsoft.com/dynamics

This document supports a demonstration of how to create a mobile app for use with Microsoft Dynamics 2012. This document is
provided for informational purposes only and Microsoft makes no warranties, either express or implied, in this document.
Information in this document, including URL and other Internet Web site references, is subject to change without notice. The entire
risk of the use or the results from the use of this document remains with the user. Unless otherwise noted, the companies,
organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted in examples herein are
fictitious. No association with any real company, organization, product, domain name, e-mail address, logo, person, place, or event
is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the
rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted
in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the
express written permission of Microsoft Corporation.

This is a preliminary document and may be changed substantially prior to final commercial release of the software described herein.

The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the
date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a
commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of
publication.

This white paper is for informational purposes only. Microsoft makes no warranties, express or implied, in this document.

Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of
this document may be reproduced, stored in, or introduced into a retrieval system, or transmitted in any form or by any means
(electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of
Microsoft Corporation.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject
matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this
document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

2013 Microsoft Corporation. All rights reserved.

The example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted
herein are fictitious. No association with any real company, organization, product, domain name, e-mail address, logo, person,
place, or event is intended or should be inferred.

Microsoft, Microsoft Dynamics, the Microsoft Dynamics logo, .NET Framework, Visual Studio, and Windows Azure are either
registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.

The names of actual companies and products mentioned herein may be the trademarks of their respective owners.

Вам также может понравиться