Export (0) Print
Expand All
Information
The topic you requested is included in another documentation set. For convenience, it's displayed below. Choose Switch to see the topic in its original location.

Control Which Browsers Your Organization Supports

Applies To: Microsoft Dynamics CRM 2011, Microsoft Dynamics CRM Online

Jim Daly
Microsoft Corporation

December, 2012

Summary

This article describes a Microsoft Dynamics CRM 2011 managed solution that enables a Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online organization with Microsoft Dynamics CRM 2011 Update Rollup 12 or the Microsoft Dynamics CRM December 2012 Service Update to control which browsers are supported for their organization.

The ControlBrowserSupportforOrganization_1_0_0_1_managed.zip file contains the Control Browser Support for Organization managed solution.

Applies To

Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online

Update Rollup 12 and the December 2012 Service Update

Introduction

Update Rollup 12 or the December 2012 Service Update adds the long awaited capability to use Microsoft Dynamics CRM with browsers other than Internet Explorer. However, with this change there is potential for customizations using JavaScript to stop working if they were not written for the new set of browsers that Microsoft Dynamics CRM supports. The Control Browser Support for Organization managed solution provides a way for an organization to enforce a policy to restrict which browsers the organization chooses to support and reduce the risk that unexpected errors will occur. Details about the browsers that are supported is available at Microsoft Dynamics CRM 2011 web application and mobile device requirements.

Some organizations may already have policies about which browsers they choose to support, to reduce costs or for other reasons. A website that is available to the public has to support the browsers that the public will ordinarily use to access the site. But most public websites do not try to support every browser. Developing and testing scripts for multiple browsers is expensive and time consuming. And, if the scripts were written for other browsers, because Microsoft Dynamics CRM has required using Internet Explorer, there has been no way to test customizations using other browsers. Also, even for organizations that do not have separate development and production environments, applying the Update Rollup 12 or the December 2012 Service Update on the production environment could cause errors when someone uses a browser other than Internet Explorer. The Control Browser Support for Organization managed solution allows an organization to specify which browsers they want to support for people using Microsoft Dynamics CRM. A JavaScript developer can modify this solution to enforce a policy to restrict the browser use to any of the browsers supported by Microsoft Dynamics CRM.

This topic includes the following sections:

What Does the Solution Do?

When the Control Browser Support for Organization managed solution is installed and someone accesses Microsoft Dynamics CRM using a browser that is supported by Microsoft Dynamics CRM but is not supported by the organization, the user briefly sees the Microsoft Dynamics CRM application as the page loads. However, as soon as the browser support rules are applied, the user will be directed to a page that explains what browsers the organization supports.

A system administrator can add a security role called Any Browser Allowed that is included in the solution to any user who should be exempt from this behavior. This allows for developers who are writing and testing scripts to use other browsers supported by Microsoft Dynamics CRM. Also, users who have the system administrator security role cannot be prevented from using Internet Explorer.

This solution can only restrict access for pages that display the ribbon. This solution is not intended to protect data. This solution enables an organization to take steps to enforce policies about browsers they support. It is possible for a user to defeat this solution and access the application by using an unapproved browser. Many browsers include capabilities to spoof other browsers by changing the navigation.userAgent property to represent a different browser.

Using the Solution

The Control Browser Support for Organization solution is easy to install and configure.

To Install and Configure the Solution

  1. Download the ControlBrowserSupportforOrganization_1_0_0_0_managed.zip solution.

  2. Install the solution by using the steps described in How to Import or Export a Solution.

  3. In the Solutions list, open the solution and view the Configuration page. The configuration page includes instructions about how to locate and edit the Organization Browser Support Message (sample_OrganizationBrowserSupportMessage.htm) HTML web resource. You must open this web resource from the default solution. You cannot access a web resource through a managed solution page.

  4. Edit the Organization Browser Support Message (sample_OrganizationBrowserSupportMessage.htm) HTML web resource using the Text Editor. Use the Source tab in the Text Editor when you set recommended links. The default HTML for this web resource is:

    <HTML><HEAD><TITLE>Browser Support Page</TITLE>
    <META charset=utf-8></HEAD>
    <BODY style="FONT-FAMILY: Tahoma, Verdana, Arial" contentEditable=true>
    <SCRIPT type=text/javascript>
      document.onselectstart = function () { return false };
     </SCRIPT>
     
    <P>At [Organization Name] we only support using Internet Explorer version 7 or higher when accessing Microsoft Dynamics CRM. </P>
    <P>For more information or to request support for additional browsers contact <A href="mailto:someone@example.com?subject=browser support for Microsoft CRM">[Administrator Name]</A>. </P></BODY></HTML>
    

    At a minimum, you should change the following parts: [Organization Name] and <A href="mailto:someone@example.com?subject=browser support for Microsoft CRM">[Administrator Name]</A>, adding an actual email address for an administrator in your organization.

  5. (Optional) If you want to specify that certain users are exempt from the browser policy, you can add the Any Browser Allowed security role to their user record.

If the solution does not meet your needs, or you want to remove browser restrictions, use the instructions in Delete a solution to uninstall it.

How Does the Solution Work?

The solution contains the solution components that are shown in the following table.

 

Name Type Description

Any Browser Allowed

Security Role

A security role that provides no additional privileges.

Application Ribbons

Application Ribbons

Ribbon definitions that add custom actions to include a disabled button in a custom group to all ribbons that represent access points to the application.

sample/icons/CheckedIcon16x16.png

PNG format web resource

A small icon used by the disabled button included in the application ribbon definition.

sample/icons/CheckedIcon32x32.png

PNG format web resource

A large icon used by the disabled button included in the application ribbon definition.

sample_ControlBrowserSupportforOrganization.js

Script (Jscript) web resource

A library that provides functions and objects that are used to enforce browser policies for an organization.

sample_ControlBrowserSupportforOrganization.json2.js

Script (Jscript) web resource

The json2.js library from Douglas Crockford https://github.com/douglascrockford/JSON-js that provides a JSON object when a browser does not provide a native JSON object.

sample_ControlBrowserSupportforOrganizationConfig.htm

Web Page (HTML) web resource

The configuration page for the solution that provides instructions about how to configure the solution.

Organization Browser Support Message (sample_OrganizationBrowserSupportMessage.htm)

Web Page (HTML) web resource

The page that people using unsupported browsers are redirected to. This web resource is intended to be edited by the organization.

The design uses the ribbon to display a custom button in a custom group. The command for the custom button contains an enable rule that executes a function that always returns false so the button is never enabled. The button must be displayed for the enable rule to be evaluated. The enable rule contains the code to detect the browser and enforce the policy.

noteNote
This solution uses an enable rule to execute code that is not related to enabling a ribbon control. Generally, this approach is not recommended. Enable rules can be called repeatedly and a function that requires time to process can damage performance. Evaluate other approaches before resorting to this technique. If you do use this approach, take great care to ensure that the functions called by the enable rule can complete very quickly.

Each time the ribbon is evaluated, the enable rule for the button executes the SDK.ControlBrowserSupportForOrganization.enforceAllowedBrowsers function in the sample_ControlBrowserSupportforOrganization.js library. A description of the operations performed by library function follows the following code.


//If the SDK namespace object is not defined, create it.
if (typeof (SDK) == "undefined")
{ SDK = {}; }
// Create Namespace container for functions in this library;

if (typeof (SDK.ControlBrowserSupportForOrganization) == "undefined") {
 SDK.ControlBrowserSupportForOrganization = {
  status: "unknown",
  AdminAndCustomizerRoleIdValues: [],
  AnyBrowserAllowedRoleIdValues: [],
  getAllowedSecurityRoleIds: function () {
   SDK.ControlBrowserSupportForOrganization.querySecurityRoles("?$select=RoleId,Name&$filter=Name eq 'System Administrator' or Name eq 'System Customizer' or Name eq 'Any Browser Allowed'")
  },
  enforceAllowedBrowsers: function () {
   switch (SDK.ControlBrowserSupportForOrganization.status) {
    //If the user has already been approved to use any browser                                                     
    // simply return false.                                                    
    case "approved":
     return false;
     break;
    default:
     var userRoles = Xrm.Page.context.getUserRoles();
     // Begin enforcement of allowed browsers.
     // This example shows allowing only Internet Explorer versions that are not earlier than version 7.
     var isAllowed = false;
     //Control rules for your organization by changing the function that sets isAllowed.
     isAllowed = SDK.ControlBrowserSupportForOrganization.isIE();
     if (!isAllowed) {
      // For Microsoft Dynamics CRM Update Rollup 12 or the December 2012 Update, System Administrators or System customizers must not be blocked 
      // from accessing the application using Internet Explorer.
      if (SDK.ControlBrowserSupportForOrganization.AdminAndCustomizerRoleIdValues.length == 0) {
       SDK.ControlBrowserSupportForOrganization.getAllowedSecurityRoleIds();
       return false;
      }
      else {
       for (var i = 0; i < userRoles.length; i++) {
        var userRole = userRoles[i];
        for (var n = 0; n < SDK.ControlBrowserSupportForOrganization.AdminAndCustomizerRoleIdValues.length; n++) {
         var adminOrCustomizerRole = SDK.ControlBrowserSupportForOrganization.AdminAndCustomizerRoleIdValues[n];
         if ((userRole.toLowerCase() == adminOrCustomizerRole.toLowerCase()) && SDK.ControlBrowserSupportForOrganization.isIE()) {
          SDK.ControlBrowserSupportForOrganization.status = "approved";
          return false;
         }
        }
       }
      }
      // Check whether the user has the 'Any Browser Allowed' security role.
      if (SDK.ControlBrowserSupportForOrganization.AnyBrowserAllowedRoleIdValues.length == 0) {
       SDK.ControlBrowserSupportForOrganization.getAllowedSecurityRoleIds();
       return false;
      }
      else {
       for (var i = 0; i < userRoles.length; i++) {
        var userRole = userRoles[i];
        for (var n = 0; n < SDK.ControlBrowserSupportForOrganization.AnyBrowserAllowedRoleIdValues.length; n++) {
         var AnyBrowserAllowedRole = SDK.ControlBrowserSupportForOrganization.AnyBrowserAllowedRoleIdValues[n];
         if (userRole.toLowerCase() == AnyBrowserAllowedRole.toLowerCase()) {
          SDK.ControlBrowserSupportForOrganization.status = "approved";
          return false;
         }
        }
       }
      }
      //Redirect page to web resource explaining the organization policy.
      window.top.location.replace(Xrm.Page.context.getClientUrl() + "/WebResources/sample_OrganizationBrowserSupportMessage.htm");
     }
     else {
      //Set the flag so the code above doesn't need to run again.
      SDK.ControlBrowserSupportForOrganization.status = "approved";
      return false;
     }
     break;
   }
  },
  isIE: function () {
   return (
     (SDK.ControlBrowserSupportForOrganization.isIE7() ||
     SDK.ControlBrowserSupportForOrganization.isIE8() ||
     SDK.ControlBrowserSupportForOrganization.isIE9() ||
     SDK.ControlBrowserSupportForOrganization.isIE10())
     );
  },
  isIE7: function () { return SDK.ControlBrowserSupportForOrganization.testUserAgent("msie 7.0"); },
  isIE8: function () { return SDK.ControlBrowserSupportForOrganization.testUserAgent("msie 8.0"); },
  isIE9: function () { return SDK.ControlBrowserSupportForOrganization.testUserAgent("msie 9.0"); },
  isIE10: function () { return SDK.ControlBrowserSupportForOrganization.testUserAgent("msie 10.0"); },
  //Simple Examples to detect Chrome, Firefox, & Safari
  isChrome: function () { return SDK.ControlBrowserSupportForOrganization.testUserAgent("chrome"); },
  isFirefox: function () { return SDK.ControlBrowserSupportForOrganization.testUserAgent("firefox"); },
  //Chrome userAgent includes 'Safari' so to test for Safari the string must not include 'chrome'
  isSafari: function () {
   return (SDK.ControlBrowserSupportForOrganization.testUserAgent("safari") &&
 (!SDK.ControlBrowserSupportForOrganization.testUserAgent("chrome")));
  },
  testUserAgent: function (string) {
   // Function to test whether a specific string is included within the navigator.userAgent.
   return new RegExp(string.toLowerCase()).test(navigator.userAgent.toLowerCase());
  },
  querySecurityRoles: function (queryString) {

   var req = new XMLHttpRequest();
   var clientUrl = Xrm.Page.context.getClientUrl();
   req.open("GET", clientUrl + "/XRMServices/2011/OrganizationData.svc/RoleSet" + queryString, true);
   req.setRequestHeader("Accept", "application/json");
   req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
   req.onreadystatechange = function () {
    if (this.readyState == 4 /* complete */) {
     req.onreadystatechange = null; //Addresses memory leak issue with IE.
     if (this.status == 200) {
      var returned = window.JSON.parse(this.responseText).d;
      for (var i = 0; i < returned.results.length; i++) {
       if ((returned.results[i].Name == "System Administrator") || (returned.results[i].Name == "System Customizer")) {
        SDK.ControlBrowserSupportForOrganization.AdminAndCustomizerRoleIdValues.push(returned.results[i].RoleId);
       }
       else {
        SDK.ControlBrowserSupportForOrganization.AnyBrowserAllowedRoleIdValues.push(returned.results[i].RoleId);
       }
      }

      if (returned.__next != null) {
       //In case more than 50 results are returned.
       // This occurs if an organization has more than 16 business units.
       var queryOptions = returned.__next.substring((clientUrl + "/XRMServices/2011/OrganizationData.svc/RoleSet").length);
       SDK.ControlBrowserSupportForOrganization.querySecurityRoles(queryOptions);
      }
      else {
       //Now that the roles have been retrieved, try again.
       SDK.ControlBrowserSupportForOrganization.enforceAllowedBrowsers();
      }
     }
     else {
      var errorText;
      if (this.status == 12029)
      { errorText = "The attempt to connect to the server failed."; }
      if (this.status == 12007)
      { errorText = "The server name could not be resolved."; }
      try {
       errorText = window.JSON.parse(this.responseText).error.message.value;
      }
      catch (e)
        { errorText = this.responseText }
     }
    }
   };
   req.send();

  },
  __namespace: true
 };

}

All functions and objects in this library use the SDK.ControlBrowserSupportForOrganization namespace. For brevity, the following description doesn’t include the namespace when it refers to specific objects or functions in this library.

The key consideration in the design of this solution is that the enforceAllowedBrowsers function must not take a long time processing because this decreases performance. Actions that require data access are performed asynchronously and the function calls itself during the callback to complete processing. After the result is determined, it is cached in a global variable so that processing does not have to be performed again. The enforceAllowedBrowsers function follows this pattern:

  1. Check the value of status. The default value for this variable is "unknown". If the value is "approved", the function returns false and is completed. The ribbon may be evaluated several times while the page is opened. The goal of this design is to quickly determine whether the browser is approved and exit as quickly as possible. The status value persists as long as the page is open.

  2. When the value is not "approved", the enforceAllowedBrowsers function continues to verify whether the browser is allowed. The default behavior is to require Internet Explorer. Therefore, the isIE function is used to call several other functions that test the navigator.userAgent object to determine the browser.

    The isIE function actually calls several separate functions to test for different versions of Internet Explorer. If any one of them return true, the value returned is true.

    If the browser is allowed, the value of status is set to "approved" and the function returns false.

  3. If the browser is not allowed, the script checks whether two arrays contain data: AdminAndCustomizerRoleIdValues and AnyBrowserAllowedRoleIdValues. If these arrays contain data, their security role ID values are compared to the security roles for the user, which are available using Xrm.Page.context.getUserRoles. If a matching security role ID is found the status is set to "approved" and the function returns false.

    If the arrays do not contain data, which is expected the first time the enforceAllowedBrowsers function runs, the function initiates a process of retrieving the necessary security role ID values by using the getAllowedSecurityRoleIds function. This function contains the following code:



    SDK.ControlBrowserSupportForOrganization.querySecurityRoles("?$select=RoleId,Name&$filter=Name eq 'System Administrator' or Name eq 'System Customizer' or Name eq 'Any Browser Allowed'")
    
    The querySecurityRoles function uses the REST endpoint for web resources to asynchronously request a list of security role ID values for specific security roles. Each time a business unit is created, any existing security roles are created and will have unique ID values. If an organization has more than 16 business units, the results may be more than the 50 records that are returned by default using the REST endpoint. Therefore, this function will look for the continuation token (__next) and it will call itself until all the results are returned. With each request, the values are added to the respective array. When all the results are returned, the enforceAllowedBrowsers function is called again. This time the AdminAndCustomizerRoleIdValues and AnyBrowserAllowedRoleIdValues arrays will have values and can determine whether the user is a member of the security roles that are excluded from the rules.

  4. If the user’s security role memberships do not exclude them from the rules, they are redirected to the sample_OrganizationBrowserSupportMessage.htm page.

Configure the Solution to Enforce Other Browser Support Policies

Changing the policy enforced by the solution requires a JavaScript developer to change some lines in the sample_ControlBrowserSupportforOrganization.js web resource. The first step is to access this web resource so that you can edit it.

Because the Control Browser Support for Organization solution is managed, you cannot simply open the managed solution and then open the web resource for editing. You have to use an indirect approach of locating the sample_ControlBrowserSupportforOrganization.js JScript web resource in the default solution. From there you can open the web resource and edit it using the text editor in the application.

noteNote
Editing JavaScript code by using the text editor in the application is generally not recommended. At a minimum, copy the text out of the text editor and paste it into a code editor of your choice. After you finish editing you can paste it back into the text editor to save and publish. A better solution is to use the Developer Toolkit for Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online or a third-party tool such as the WebResources Manager for Microsoft Dynamics CRM 2011 or the CRM Solution Manager. Any of these options will provide a support for editing JavaScript and help prevent syntax errors.

After you have the sample_ControlBrowserSupportforOrganization.js Jscript web resource open for editing, locate the following line:

isAllowed = SDK.ControlBrowserSupportForOrganization.isIE();

If your requirements are for a policy that only supports the Google Chrome browser, you can use one of the existing example functions in the library. Just change the assignment of isAllowed using this code:

isAllowed = SDK.ControlBrowserSupportForOrganization.isChrome();

There are also example functions to check for Mozilla Firefox or Apple Safari. If these examples do not meet your requirements, you can apply your own logic to use a different method to test the value of the navigator.userAgent value provided by the browser. The default logic is a simple string match defined by the SDK.ControlBrowserSupportForOrganization.testUserAgent function in the following code:

  testUserAgent: function (string) {
   // Function to test whether a specific string is included within the navigator.userAgent.
   return new RegExp(string.toLowerCase()).test(navigator.userAgent.toLowerCase());
  },

As mentioned in the Microsoft Dynamics CRM SDK Use JavaScript with Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online topic JavaScript Programming Best Practices section, browser detection is generally not recommended for use in scripts. You should generally use feature detection. For more information, see How to Detect Features Instead of Browsers. However, because this solution is actually about detecting browsers, using a browser detection approach is appropriate.

Conclusion

 

If your organization doesn’t want to support all the browsers that Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online support with Update Rollup 12 or the December 2012 Service Update, you may want to apply some way to prevent people from using certain browsers when they use Microsoft Dynamics CRM.

This article described the Control Browser Support for Organization managed solution showing what it does, how to use it, and how it works. It also described how it can be configured to enforce policies other than the default policy, which is to only let users use Internet Explorer.

Send comments about this article to Microsoft.

Community Additions

Show:
© 2015 Microsoft