How to: Create an ASP.NET web app to access SAP data by using SAP Gateway for Microsoft

 

Topic Last Modified: 2014-10-08

Summary: Learn how you can build an ASP.NET web app that can access SAP data via SAP Gateway for Microsoft.

You can create an ASP.Net app that reads and writes SAP data by using the SAP Gateway for Microsoft. This article describes how you can do so by using the Model-View-Controller (MVC) architecture to get authorized access to SAP.

Sample download: Creating an ASP.NET Web app to access SAP Gateway for Microsoft

Before you begin

Before you create your application, ensure that you have the prerequisite software and information that you need to be successful.

Prerequisites

Before you can create an ASP.NET app, be sure that you have the following are in place:

Understand how to access SAP data with OAuth 2.0 in Azure AD

Azure AD uses OAuth 2.0 to grant you authorized access to web applications, such as SAP Gateway for Microsoft, and web APIs in your Azure AD subscription. Access to SAP Gateway for Microsoft from an ASP.NET application is implemented by using the OAuth 2.0 Authorization Code Grant flow. In this flow, the user’s work account delegates access to the ASP.NET application. This transaction is protected and mediated by exchanging an authorization code from Azure AD with an access token that provides access to the resource. In this exchange, the client application never "detects" the user’s credentials, and the user agent or browser environment never "detects" the access token.

The process is as follows:

  1. The ASP.NET web application starts the flow by redirecting the user agent to the Azure AD authorization endpoint, login.windows.net, and the user signs in.

  2. The Azure AD authorization endpoint redirects the user agent back to the ASP.NET web application with an authorization code.

  3. The ASP.NET web application requests access from the Azure AD token issuance endpoint.

  4. The Azure AD token issuance endpoint returns an access token and a refresh token. The refresh token can be used to request a new access token when the current access token expires.

  5. The ASP.NET web application uses the access token to authenticate to SAP Gateway for Microsoft. After the access token is validated by SAP Gateway for Microsoft, the requested SAP data is returned to the ASP.NET web application.

Microsoft has built a library for developers with the OAuth 2.0 in Azure AD authentication process that’s known as the Active Directory Authentication Library, also referred to as the ADAL. The ADAL can help developers easily authenticate users and obtain tokens.

Create an ASP.NET MVC app with ADAL to access SAP Gateway for Microsoft

This example project uses the ADAL to do the Azure OAuth 2.0 authentication.

Create the ASP.NET application

Create an ASP.NET MVC project in Visual Studio with the following steps.

Tip

The continuing example in this article assumes that you are using C#; but you can start an ASP.NET web application project in the Visual Basic section of the new project templates also.

To create an ASP.NET MVC project

  1. Create an ASP.NET MVC project in Visual Studio.

    1. In the New Project wizard, in the left menu, click Templates > Visual C# > Web, and then select the ASP.NET web Application project template.

    2. Name the project, and then click OK.

      For the continuing example, we assume the project is named “SAP2ASPNET.”

  2. Choose the MVC template.

  3. The example project doesn’t need a user account. So click Change Authentication.

  4. In the Change Authentication dialog box, select No Authentication, and then click OK.

  5. Click OK to close the New ASP.Net Project dialog box.

  6. Add the Active Directory Authentication Library (ADAL) package to the ASP.NET project with these steps:

    1. On the Your ASP.NET application page, in Solution Explorer, right-click your ASP.NET application, and then click Manage NuGet Packages.

    2. In the dialog box that opens, select Online on the left menu, and type ADAL in the search box.

    3. When the Active Directory Authentication Library (ADAL) appears in the search results, click the Install button next to it, and accept the license agreement to continue.

  7. Add the Json.net package to the ASP.NET project with these steps:

    1. Type Json.net in the search box. If this produces too many hits, try searching on Newtonsoft.json.

    2. When Json.net appears in the search results, click the Install button next to it.

  8. After it’s installed, click Close.

Optionally enable SSL

We recommend that you use SSL for this ASP.NET web application to protect your OAuth access token in the HTTP request.

To enable SSL

  1. Select the SAP2APSNET project, and open the Properties window of the ASP.NET web application project.

    Tip

    In the Visual Studio menu, click View > Properties Window, or use the keyboard shortcut Ctrl+W+P to display it.

  2. Under SAP2ASPNET Project Properties, set the SSL Enabled property to True.

    A new SSL URL is generated by Visual Studio in the form of https://localhost:<portnumber>/.

    Project Properties dialog box of the SAP2ASPNET project

  3. Copy the SSL URL, and right-click the SAP2ASPNET project. In the Web tab of the SAP2ASPNET project settings page, set it to Project Url, and then save the changes.

Register the application in Azure AD

  1. Log on to the Azure Management portal with your Azure service administrator or co-administrator account.

    Note

    Registering the application requires an Azure service administrator or co-administrator account. But, for security purposes, we recommend against using an administrator account when you’re running or debugging applications.

  2. Select Active Directory.

  3. Select the directory associated with SAP Gateway for Microsoft. In the continuing example, we assume that the Azure AD directory associated with SAP Gateway for Microsoft is named "Contoso."

  4. Choose APPLICATIONS (on the top navigation bar).

  5. Choose Add on the command bar at the bottom of the screen.

  6. In the dialog box that opens, choose Add an application my organization is developing.

  7. On the ADD APPLICATION dialog box, name the application. For the continuing example, we use the name ContosoAutomobileCollection.

  8. Choose Web Application And/Or Web API as the application type, and then click the right arrow.

  9. On the second page of the dialog box, use the SSL debugging URL from the ASP.NET project in the Visual Studio solution as the SIGN-ON URL. You can find the URL using the following steps.

    Note

    You have to register the application for the first time with the debugging URL so that you can run the Visual Studio debugger (F5). When your application is ready for staging, you should re-register it with its staging Azure website URL. Change the application, and stage it to Azure.

    1. Highlight the ASP.NET project in Solution Explorer.

    2. In the Properties window, copy the value of the SSL URL property, for example, https://localhost:44300/.

    3. In the ADD APPLICATION dialog box, paste it into the SIGN-ON URL box.

  10. For the APP ID URI, give the application a unique URI, such as the application name that’s appended to the SSL URL, for example, https://localhost:44300/ContosoAutomobileCollection.

  11. Click the check mark. The Azure dashboard for the application opens with a success message.

  12. Click CONFIGURE on the top of the page.

  13. Scroll to the CLIENT ID, and copy it. You need it for a later procedure.

  14. In the keys section, create a key. It won't appear at first. Click SAVE, and the key will be visible. Copy it. You will need it for a later procedure.

  15. Scroll to permissions to other applications, and select your SAP Gateway for Microsoft service application.

  16. Click the Delegated Permissions drop-down list, and enable the boxes for the permissions to the SAP Gateway for Microsoft service that your ASP.NET application needs.

  17. Click SAVE.

Configure the application to communicate with Azure AD

  1. In Visual Studio, open the web.config file in the ASP.NET project.

  2. Add the following two elements to the <appSettings> section. The application uses these elements to authenticate to Azure AD.

    <add key="ida:ClientID" value="" />
    
    <add key="ida:ClientKey" value="" />
    
  3. Insert the Client ID value that you saved from your Azure AD directory in the earlier procedure as the value of the ida:ClientID key. Leave the casing and punctuation exactly as you copied it, and be careful not to include any spaces at the beginning or end of the value. For the ida:ClientKey key, use the key that you saved from the directory. Again, be careful not to introduce any extra spaces or change the value in any way. The <appSettings> section should now resemble the following, and the ClientId value might have a GUID or an empty string.

    <appSettings>
    
      <add key="ida:ClientID" value="3db17232-7765-4176-ba5e-4bb3cfc4dc3b" />
    
      <add key="ida:ClientKey" value="T3tIHYVVtbDo3tPi4473V+n+2k2ZyiDUdvUiGPzWXdI=" />
    
    </appSettings>
    

    Note

    Your application is known to Azure AD by the "localhost" URL you used to register it. The client ID and client key are associated with that identity. When you are ready to stage your application to an Azure website, you should re-register it with a new URL.

  4. Still in the appSettings section, add an Authority key, and set its value to the Azure domain (some_domain.onmicrosoft.com) of your organization account. In the continuing example, the organizational account is bob@contoso.onmicrosoft.com. So, the authority is contoso.onmicrosoft.com.

    <add key="Authority" value="contoso.onmicrosoft.com" />
    
  5. Still in the appSettings section, add an AppRedirectUrl key, and set its value to the page that the user's browser should be redirected to after the ASP.NET application has obtained an authorization code from Azure AD. Usually, this is the same page that the user was on when the call to Azure AD was made. In the continuing example, use the SSL URL value with "/SAP" appended to it, as shown below. This is another value that you should change for staging.

    <add key="AppRedirectUrl" value="https://localhost:44300/SAP" />
    
  6. Still in the appSettings section, add a ResourceUrl key, and set its value to the APP ID URI of SAP Gateway for Microsoft, not the APP ID URI of your ASP.NET application. Obtain this value from the SAP Gateway for Microsoft administrator. The following is an example.

    <add key="ResourceUrl" value="http://contoso.cloudapp.net/" />
    

    The <appSettings> section should now resemble the following:

    <appSettings>
    
      <add key="ida:ClientID" value="3db17232-7765-4176-ba5e-4bb3cfc4dc3b" />
    
      <add key="ida:ClientKey" value="T3tIHYVVtbDo3tPi4473V+n+2k2ZyiDUdvUiGPzWXdI=" />
    
      <add key="Authority" value="contoso.onmicrosoft.com" />
    
      <add key="AppRedirectUrl" value="https://localhost:44300/SAP" />
    
      <add key="ResourceUrl" value="http://contoso.cloudapp.net/" />
    
    </appSettings>
    
  7. Save and close the web.config file.

Add a helper class to authenticate to Azure AD

  1. Right-click the ASP.NET project, and use the Visual Studio item adding process to add a new class file to the project named AADAuthHelper.cs.

  2. Add the following using statements to the file.

    using Microsoft.IdentityModel.Clients.ActiveDirectory;
    
    using System.Configuration; 
    
    using System.Web.UI;
    
  3. Change the access keyword from public to internal, and add the static keyword to the class declaration.

    internal static class AADAuthHelper
    
  4. Add the following fields to the class. These fields store information that your ASP.NET application uses to obtain access tokens from Azure AD.

    private static readonly string _authority = ConfigurationManager.AppSettings["Authority"];
    private static readonly string _appRedirectUrl = ConfigurationManager.AppSettings["AppRedirectUrl"];
    private static readonly string _resourceUrl = ConfigurationManager.AppSettings["ResourceUrl"];     
    private static readonly string _clientId = ConfigurationManager.AppSettings["ida:ClientID"];
    private static readonly ClientCredential _clientCredential = new ClientCredential(
                               ConfigurationManager.AppSettings["ida:ClientID"],
                               ConfigurationManager.AppSettings["ida:ClientKey"]);
    private static readonly AuthenticationContext _authenticationContext = 
                new AuthenticationContext("https://login.windows.net/common/" + 
                                          ConfigurationManager.AppSettings["Authority"]);
    
  5. Add the following property to the class. This property holds the URL to the Azure AD logon screen.

    private static string AuthorizeUrl
    {
        get
        {
            return string.Format("https://login.windows.net/{0}/oauth2/authorize?response_type=code&redirect_uri={1}&client_id={2}&state={3}",
                _authority,
                _appRedirectUrl,
                _clientID,
                Guid.NewGuid().ToString());
        }
    }
    
  6. Add the following properties to the class. These properties are used to cache the access and refresh tokens and to check their validity.

    public static Tuple<string, DateTimeOffset> AccessToken
    {
        get {
    return HttpContext.Current.Session["AccessTokenWithExpireTime-" + _resourceUrl] 
           as Tuple<string, DateTimeOffset>;
        }
        set { HttpContext.Current.Session["AccessTokenWithExpireTime-" + _resourceUrl] = value; }
    }
    private static bool IsAccessTokenValid
    {
       get 
       { 
           return AccessToken != null &&
           !string.IsNullOrEmpty(AccessToken.Item1) &&
           AccessToken.Item2 > DateTimeOffset.UtcNow;
       }
    }
    private static string RefreshToken
    {
        get { return HttpContext.Current.Session["RefreshToken" + _resourceUrl] as string; }
        set { HttpContext.Current.Session["RefreshToken-" + _resourceUrl] = value; }
    }
    private static bool IsRefreshTokenValid
    {
        get { return !string.IsNullOrEmpty(RefreshToken); }
    }
    
  7. Add the following methods to the class. These are used to check the validity of the authorization code and to obtain an access token from Azure AD by using either an authentication code or a refresh token.

    private static bool IsAuthorizationCodeNotNull(string authCode)
    {
        return !string.IsNullOrEmpty(authCode);
    }
    private static Tuple<Tuple<string,DateTimeOffset>,string> AcquireTokensUsingAuthCode(string authCode)
    {
        var authResult = _authenticationContext.AcquireTokenByAuthorizationCode(
                    authCode,
                    new Uri(_appRedirectUrl),
                    _clientCredential,
                    _resourceUrl);
        return new Tuple<Tuple<string, DateTimeOffset>, string>(
                    new Tuple<string, DateTimeOffset>(authResult.AccessToken, authResult.ExpiresOn), 
                    authResult.RefreshToken);
    }
    private static Tuple<string, DateTimeOffset> RenewAccessTokenUsingRefreshToken()
    {
        var authResult = _authenticationContext.AcquireTokenByRefreshToken(
                             RefreshToken,
                             _clientId,
                             _clientCredential,
                             _resourceUrl);
        return new Tuple<string, DateTimeOffset>(authResult.AccessToken, authResult.ExpiresOn);
    }
    
  8. Add the following method to the class. It is called from the ASP.NET code behind to obtain a valid access token before a call is made to request SAP data via SAP Gateway for Microsoft.

    internal static string EnsureValidAccessToken(HttpContextBase httpContext)
    {
        if (IsAccessTokenValid) 
        {
            return AccessToken.Item1;
        }
        else if (IsRefreshTokenValid) 
        {
            AccessToken = RenewAccessTokenUsingRefreshToken();
            return AccessToken.Item1;
        }
        else if (IsAuthorizationCodeNotNull(httpContext.Request.QueryString["code"]))
        {
            Tuple<Tuple<string, DateTimeOffset>, string> tokens = null;
            try
            {
                tokens = AcquireTokensUsingAuthCode(httpContext.Request.QueryString["code"]);
            }
            catch 
            {
                httpContext.Response.Redirect(AuthorizeUrl);
            }
            AccessToken = tokens.Item1;
            RefreshToken = tokens.Item2;
            return AccessToken.Item1;
        }
        else
        {
            httpContext.Response.Redirect(AuthorizeUrl);
        }
        return string.Empty;
    }
    

Tip

The AADAuthHelper class has only minimal error handling. For a robust, production quality application for SharePoint, add more error handling, as described in Error Handling in OAuth 2.0 and its child articles.

Create data model classes

  1. Create one or more classes to model the data that your application obtains from SAP. In the continuing example, there is just one data model class. Right-click the ASP.NET project, and use the Visual Studio process of adding items to add a new class file to the project named Automobile.cs.

  2. Add the following code to the body of the class:

    public string Price;
    public string Brand;
    public string Model;
    public int Year;
    public string Engine;
    public int MaxPower;
    public string BodyStyle;
    public string Transmission;
    

Add a view to display SAP data

  1. Right-click the Views folder of the SAP2ASPNET project.

  2. Add a new folder, for example, a folder named SAP.

  3. Right-click this newly added folder, and add a View. From the Template drop-down list, select Empty, and select the data model for your project from the Model class list. In this continuing example, we assume that you selected the Automobile data model that you created earlier.

    Add View dialog box in Visual Studio

  4. Click Add.

  5. Edit the Index.cshtml file as follows:

    @model IEnumerable<SAP2ASPNET.Automobile>
    @{
        ViewBag.Title = "SAP";
    }
    <h2>Automobile</h2>
    <table class="table table-bordered table-striped">
        <tr>
            <th>
                Brand
            </th>
            <th>
                Model
            </th>
            <th>
                Year
            </th>
            <th>
                Engine
            </th>
            <th>
                MaxPower
            </th>
            <th>
                Price
            </th>
            <th>
                BodyStyle
            </th>
            <th>
                Transmission
            </th>
        </tr>
        @foreach (var item in Model)
        {
            <tr>
                <th>
                    @Html.DisplayFor(modelItem => item.Brand)
                </th>
                <th>
                    @Html.DisplayFor(modelItem => item.Model)
                </th>
                <th>
                    @Html.DisplayFor(modelItem => item.Year)
                </th>
                <th>
                    @Html.DisplayFor(modelItem => item.Engine)
                </th>
                <th>
                    @Html.DisplayFor(modelItem => item.MaxPower)
                </th>
                <th>
                    @Html.DisplayFor(modelItem => item.Price)
                </th>
                <th>
                    @Html.DisplayFor(modelItem => item.BodyStyle)
                </th>
                <th>
                    @Html.DisplayFor(modelItem => item.Transmission)
                </th>
            </tr>
        }
    </table>
    

Add a controller for retrieving SAP data

  1. In the SAP2ASPNET project, right-click Controller, and then select MVC 5 Controller – Empty. Name the project SAPController. We use this name in the continuing example.

  2. Edit SAPController.cs, and add the following using statements to the file:

    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Threading.Tasks;
    using Newtonsoft.Json.Linq;
    
  3. While still editing SAPController.cs, add the following SAPController public class:

        public class SAPController : Controller
        {
            // Replace the value with your SAP OData endpoint stem. The last character in the value has to be a single forward slash.
            private const string SAP_ODATA_URL = @"https://stem_of_SAP_OData_endpoint/";
            // Replace parameter with an OData object and optional query parameters.
            private const string SAP_ODATA_QUERY = "some_data_collection?$top=10";
    
            public async Task<ActionResult> Index()
            {
                string accessToken = AADAuthHelper.EnsureValidAccessToken(this.HttpContext);
                using (HttpClient client = new HttpClient())
                {
                    string requestUrl = SAP_ODATA_URL + SAP_ODATA_QUERY;
    
                    using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl))
                    {
                        request.Headers.Add("Accept", "application/json");
                        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    
                        HttpResponseMessage response = await client.SendAsync(request);
                        string dataString = await response.Content.ReadAsStringAsync();
    
                        var sapData = JObject.Parse(dataString)["d"]["results"].ToObject<Automobile[]>();
                        return View(sapData);
                    }
                }
            }
        } 
    

Add the SAP view entry point to the web application

  1. Edit Views\Shared\_Layout.csthml.

  2. In the <body> section, find <ul class="nav navbar-nav">, and add the following code:

    <li>@Html.ActionLink("SAP", "Index", "SAP")</li>
    

Test the application with F5 in Visual Studio

Follow these steps to test the application using F5 in Visual Studio.

  1. Open Visual Studio, and press F5.

  2. Click the SAP link at the top of the page.

  3. On the login.microsoft.online.com page, log on with the organizational account that you use for running applications.

    Note

    This user must be granted access to SAP Gateway for Microsoft.

  4. After a brief delay while the access token is being obtained, the SAP view page opens. Verify that the SAP data appears.

Change the application and stage it to Azure

When you finish debugging the application using F5 in Visual Studio, you have to deploy the ASP.NET application to an actual Azure website.

To create the Azure website

  1. In the Azure portal, open WEB SITES on the left navigation bar.

  2. Click NEW on the command bar at the bottom of the page, and on the NEW dialog box, select WEB SITE > QUICK CREATE.

  3. Enter a domain name, and then click CREATE WEB SITE. Make a copy of the new site's URL. It has the form my_domain.azurewebsites.net.

To change the code and markup in the application

  • In Visual Studio, open the web.config file of the ASP.NET project, and change the domain part of the value of the AppRedirectUrl key in the appSettings section to the domain of the Azure website.

    For example, change <add key="AppRedirectUrl" value=" https://localhost:44300/SAP" /> to <add key="AppRedirectUrl" value="https://my_domain.azurewebsites.net/SAP" />.

To change the Azure AD registration and register the application

  1. Log on the Azure Management portal with your Azure administrator account.

  2. In the left navigation pane, select Active Directory.

  3. Click the Azure AD directory that’s associated with SAP Gateway for Microsoft.

  4. Choose APPLICATIONS on the top navigation bar.

  5. Open the applications that you created. In the continuing example, it is named ContosoAutomobileCollection.

  6. For each of the following values, change the "localhost:port" part of the value to the domain of your new Azure website:

    • SIGN-ON URL

    • APP ID URI

    • REPLY URL

    For example, if the APP ID URI is https://localhost:44304/ContosoAutomobileCollection, change it to https://<my_domain>.azurewebsites.net/ContosoAutomobileCollection.

  7. Click SAVE.

To publish the ASP.NET application to Azure