Limiting Access to Office 365 Services Based on the Location of the Client

Updated: October 6, 2014

Applies To: Active Directory Federation Services (AD FS) 2.0

Some organizations may want to create policies that limit access to Microsoft ® Office 365 services, depending on where the client resides. For example, you might want to:

  • Block all extranet client access to Office 365

  • Block all extranet client access to Office 365, except for devices accessing Exchange Online for Exchange Active Sync

Active Directory Federation Services (AD FS) 2.0 provides a way for organizations to configure these types of policies. Office 365 customers using Single Sign-On (SSO) who require these policies can now use client access policy rules to restrict access based on the location of the computer or device that is making the request. Customers using Microsoft Online Services cloud User IDs cannot implement these restrictions at this time.

For more information about how to deploy AD FS 2.0 for SSO to Office 365, see Plan for and deploy AD FS 2.0 for use with single sign-on to Office 365 on the Office 365 content portal.

An AD FS 2.0 federation server proxy or a third-party proxy is required to forward requests from clients residing outside the corporate network to the internal Federation Service.

Note

If you are using a third-party proxy, it must be configured to do the following:

  1. Send an HTTP header named x-ms-proxy. The value of this header should be the DNS name of the proxy host.

  2. Send an HTTP header named x-ms-endpoint-absolute-path. The value of this header should be set to the name of the proxy endpoint that received the request.

Otherwise, an AD FS 2.0 federation server proxy must be deployed behind the third-party proxy.

Note

Scenario 3: Block all external access to Office 365 except browser-based applications is not supported with a third-part proxy because of limitations on client access policy headers with passive (Web-based) requests.

For more information about the use of third-party proxies with AD FS 2.0, see Using a Third-Party Proxy as a Replacement to an AD FS 2.0 Federation Server Proxy.

Client Access Policy Claim Types

Client access policy works by identifying which authentication requests should be permitted based upon attributes of the request itself. To provide this additional request context information, client access policy introduces a set of new claim types that AD FS populates from header information sent by the requesting client. For a detailed description of the new claim types and values, see New Claim Types.

Client Access Policy Scenarios

The following table describes the scenarios supported by the client access policy feature.

Scenario Description

Block all external access to Office 365

Office 365 access is allowed from all clients on the internal corporate network, but requests from external clients are denied based on the IP address of the external client.

Block all external access to Office 365, except Exchange ActiveSync

Office 365 access is allowed from all clients on the internal corporate network, as well as from any external client devices, such as smart phones, that make use of Exchange ActiveSync. All other external clients, such as those using Outlook, are blocked.

Block all external access to Office 365, except for browser-based applications such as Outlook Web Access or SharePoint Online

Blocks external access to Office 365, except for passive (browser-based) applications such as Outlook Web Access or SharePoint Online.

Block all external access to Office 365 for members of designated Active Directory groups

This scenario is used for testing and validating client access policy deployment. It blocks external access to Office 365 only for members of one or more Active Directory group. It can also be used to provide external access only to members of a group.

Note

The following client access policy scenarios have the effect of blocking external access to Microsoft Lync Online and Office Subscription Services:

  • Scenario 1: Block all external access to Office 365

  • Scenario 2: Block all external access to Office 365 except Exchange ActiveSync

  • Scenario 3: Block all external access to Office 365 except browser-based applications

Enabling Client Access Policy

To enable client access policy, you must complete the following steps:

Step 1: Install the Update Rollup 2 for AD FS 2.0 package on your AD FS servers

Download the Update Rollup 2 for Active Directory Federation Services (AD FS) 2.0 package and install it on all federation server and federation server proxies.

For more information about the fixes, new capabilities, download location and installation instructions associated with this package, see Description of Update Rollup 2 for Active Directory Federation Services (AD FS) 2.0 on the Microsoft Support site.

Step 2: Add five claim rules to the Active Directory Claims Provider trust

After the Update Rollup 2 for Active Directory Federation Services (AD FS) 2.0 package has been installed on all federation servers and federation server proxies, and the AD FS Windows service has been restarted, use the following procedure to add a set of claim rules that make the new claim types available to the policy engine.

In this step, you will have to add five acceptance transform rules for each of the new request context claim types using the following procedure.

On the Active Directory claims provider trust, create a new acceptance transform rule to pass through each of the new request context claim types.

To add a claim rule to the Active Directory claims provider trust for each of the five context claim types

  1. Click Start, point to Programs, point to Administrative Tools, and then click AD FS 2.0 Management.

  2. In the console tree, under AD FS 2.0\Trust Relationships, click Claims Provider Trusts, right-click Active Directory, and then click Edit Claim Rules.

  3. In the Edit Claim Rules dialog box, select the Acceptance Transform Rules tab, and then click Add Rule to start the Rule wizard.

  4. On the Select Rule Template page, under Claim rule template, select Pass Through or Filter an Incoming Claim from the list, and then click Next.

  5. On the Configure Rule page, under Claim rule name, type the display name for this rule; in Incoming claim type, type the following claim type URL, and then select Pass through all claim values.

    https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip
    
  6. To verify the rule, select it in the list and click Edit Rule, then click View Rule Language. The claim rule language should appear as follows:

    c:[Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip"] => issue(claim = c);

  7. Click Finish.

  8. In the Edit Claim Rules dialog box, click OK to save the rules.

  9. Repeat steps 2 through 6 to create an additional claim rule for each of the remaining four claim types shown below until all five rules have been created.

    • https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application
      
    • https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-user-agent
      
    • https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy
      
    • https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path
      

Step 3: Update the Microsoft Office 365 Identity Platform relying party trust

Choose one of the example scenarios below to configure the claim rules on the Microsoft Office 365 Identity Platform relying party trust that best meets the needs of your organization.

Note

To ensure that the client access policy scenario works, verify that you have completed the instructions under To add a claim rule to the Active Directory claims provider trust for each of the five context claim types.

Scenario 1: Block all external access to Office 365

The client access policy scenario allows access from all internal clients and blocks all external clients based on the IP address of the external client. The rule set builds on the default Issuance Authorization rule Permit Access to All Users. You can use the following procedure to add an Issuance Authorization rule to the Office 365 relying party trust.

To create a rule to block all external access to Office 365

  1. Click Start, point to Programs, point to Administrative Tools, and then click AD FS 2.0 Management.

  2. In the console tree, under AD FS 2.0\Trust Relationships, click Relying Party Trusts, right-click the Microsoft Office 365 Identity Platform trust, and then click Edit Claim Rules.

  3. In the Edit Claim Rules dialog box, select the Issuance Authorization Rules tab, and then click Add Rule to start the Claim Rule Wizard.

  4. On the Select Rule Template page, under Claim rule template, select Send Claims Using a Custom Rule, and then click Next.

  5. On the Configure Rule page, under Claim rule name, type the display name for this rule. Under Custom rule, type or paste the following claim rule language syntax:

    exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy"]) &&
    NOT exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip",
    Value=~"customer-provided public ip address regex"])
    => issue(Type = "https://schemas.microsoft.com/authorization/claims/deny", Value = "true"); 
    

    You will have to replace the value above for “public ip address regex” with a valid IP expression; see Building the IP address range expression for more information.

  6. Click Finish. Verify that the new rule appears immediately below the Permit Access to All Users rule in the Issuance Authorization Rules list.

  7. To save the rule, in the Edit Claim Rules dialog box, click OK.

Scenario 2: Block all external access to Office 365 except Exchange ActiveSync

The following example allows access to all Office 365 applications, including Exchange Online, from internal clients including Outlook. It blocks access from clients residing outside the corporate network, as indicated by the client IP address, except for Exchange ActiveSync clients such as smart phones. The rule set builds on the default Issuance Authorization rule titled Permit Access to All Users. Use the following steps to add an Issuance Authorization rule to the Office 365 relying party trust using the Claim Rule Wizard:

To create a rule to block all external access to Office 365 except Exchange ActiveSync

  1. Click Start, point to Programs, point to Administrative Tools, and then click AD FS 2.0 Management.

  2. In the console tree, under AD FS 2.0\Trust Relationships, click Relying Party Trusts, right-click the Microsoft Office 365 Identity Platform trust, and then click Edit Claim Rules.

  3. In the Edit Claim Rules dialog box, select the Issuance Authorization Rules tab, and then click Add Rule to start the Claim Rule Wizard.

  4. On the Select Rule Template page, under Claim rule template, select Send Claims Using a Custom Rule, and then click Next.

  5. On the Configure Rule page, under Claim rule name, type the display name for this rule. Under Custom rule, type or paste the following claim rule language syntax:

    exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy"]) &&
    NOT exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application",
    Value=="Microsoft.Exchange.Autodiscover"]) &&
    NOT exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application",
    Value=="Microsoft.Exchange.ActiveSync"]) &&
    NOT exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip",
    Value=~"customer-provided public ip address regex"])
    => issue(Type = "https://schemas.microsoft.com/authorization/claims/deny", Value = "true");
    

    You will have to replace the value above for “public ip address regex” with a valid IP expression; see Building the IP address range expression for more information.

  6. Click Finish. Verify that the new rule appears immediately below the Permit Access to All Users rule in the Issuance Authorization Rules list.

  7. To save the rule, in the Edit Claim Rules dialog box, click OK.

Scenario 3: Block all external access to Office 365 except browser-based applications

The rule set builds on the default Issuance Authorization rule titled Permit Access to All Users. Use the following steps to add an Issuance Authorization rule to the Microsoft Office 365 Identity Platform relying party trust using the Claim Rule Wizard:

Note

This scenario is not supported with a third-party proxy because of limitations on client access policy headers with passive (Web-based) requests.

To create a rule to block all external access to Office 365 except browser-based applications

  1. Click Start, point to Programs, point to Administrative Tools, and then click AD FS 2.0 Management.

  2. In the console tree, under AD FS 2.0\Trust Relationships, click Relying Party Trusts, right-click the Microsoft Office 365 Identity Platform trust, and then click Edit Claim Rules.

  3. In the Edit Claim Rules dialog box, select the Issuance Authorization Rules tab, and then click Add Rule to start the Claim Rule Wizard.

  4. On the Select Rule Template page, under Claim rule template, select Send Claims Using a Custom Rule, and then click Next.

  5. On the Configure Rule page, under Claim rule name, type the display name for this rule. Under Custom rule, type or paste the following claim rule language syntax:

    exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy"]) &&
    NOT exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip",
    Value=~"customer-provided public ip address regex"]) &&
    NOT exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path", Value == "/adfs/ls/"])
    => issue(Type = "https://schemas.microsoft.com/authorization/claims/deny", Value = "true"); 
    

    You will have to replace the value above for “public ip address regex” with a valid IP expression; see Building the IP address range expression for more information.

  6. Click Finish. Verify that the new rule appears immediately below the Permit Access to All Users rule in the Issuance Authorization Rules list.

  7. To save the rule, in the Edit Claim Rules dialog box, click OK.

Scenario 4: Block all external access to Office 365 for designated Active Directory groups

The following example enables access from internal clients based on IP address. It blocks access from clients residing outside the corporate network that have an external client IP address, except for those individuals in a specified Active Directory Group.The rule set builds on the default Issuance Authorization rule titled Permit Access to All Users. Use the following steps to add an Issuance Authorization rule to the Microsoft Office 365 Identity Platform relying party trust using the Claim Rule Wizard:

To create a rule to block all external access to Office 365 for designated Active Directory groups

  1. Click Start, point to Programs, point to Administrative Tools, and then click AD FS 2.0 Management.

  2. In the console tree, under AD FS 2.0\Trust Relationships, click Relying Party Trusts, right-click the Microsoft Office 365 Identity Platform trust, and then click Edit Claim Rules.

  3. In the Edit Claim Rules dialog box, select the Issuance Authorization Rules tab, and then click Add Rule to start the Claim Rule Wizard.

  4. On the Select Rule Template page, under Claim rule template, select Send Claims Using a Custom Rule, and then click Next.

  5. On the Configure Rule page, under Claim rule name, type the display name for this rule. Under Custom rule, type or paste the following claim rule language syntax:

    exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy"]) &&
    exists([Type == "https://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "Group SID value of allowed AD group"]) &&
    NOT exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip",
    Value=~"customer-provided public ip address regex"])
    => issue(Type = "https://schemas.microsoft.com/authorization/claims/deny", Value = "true");
    

    You will have to replace the value above for “public ip address regex” with a valid IP expression; see Building the IP address range expression for more information.

  6. Click Finish. Verify that the new rule appears immediately below the Permit Access to All Users rule in the Issuance Authorization Rules list.

  7. To save the rule, in the Edit Claim Rules dialog box, click OK.

Descriptions of the claim rule language syntax used in the above scenarios

Description

Claim Rule language syntax

Default AD FS rule to Permit Access to All Users. This rule should already exist in the Microsoft Office 365 Identity Platform relying party trust Issuance Authorization Rules list.

=> issue(Type = "https://schemas.microsoft.com/authorization/claims/permit", Value = "true");

Adding this clause to a new, custom rule specifies that the request has come from the federation server proxy (i.e., it has the x-ms-proxy header)

It is recommended that all rules include this.

exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy"])

Used to establish that the request is from a client with an IP in the defined acceptable range.

NOT exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip",

Value=~"customer-provided public ip address regex"])

This clause is used to specify that if the application being accessed is not Microsoft.Exchange.ActiveSync the request should be denied.

NOT exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application",

Value=="Microsoft.Exchange.ActiveSync"])

This rule allows you to determine whether the call was through a Web browser, and will not be denied.

NOT exists([Type == "https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path", Value == "/adfs/ls/"])

This rule states that the only users in a particular Active Directory group (based on SID value) should be denied. Adding NOT to this statement means a group of users will be allowed, regardless of location.

exists([Type == "https://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "{Group SID value of allowed AD group}"])

This is a required clause to issue a deny when all preceding conditions are met.

=> issue(Type = "https://schemas.microsoft.com/authorization/claims/deny", Value = "true");

Building the IP address range expression

The x-ms-forwarded-client-ip claim is populated from an HTTP header that is currently set only by Exchange Online, which populates the header when passing the authentication request to AD FS. The value of the claim may be one of the following:

Note

Exchange Online currently supports only IPV4 and not IPV6 addresses.

  • A single IP address: The IP address of the client that is directly connected to Exchange Online

Note

  • The IP address of a client on the corporate network will appear as the external interface IP address of the organization’s outbound proxy or gateway.

  • Clients that are connected to the corporate network by a VPN or by Microsoft DirectAccess (DA) may appear as internal corporate clients or as external clients depending upon the configuration of VPN or DA.

    • One or more IP addresses: When Exchange Online cannot determine the IP address of the connecting client, it will set the value based on the value of the x-forwarded-for header, a non-standard header that can be included in HTTP-based requests and is supported by many clients, load balancers, and proxies on the market.

    Note

  • Multiple IP addresses, indicating the client IP address and the address of each proxy that passed the request, will be separated by a comma.

  • IP addresses related to Exchange Online infrastructure will not appear on the list.

  • Regular Expressions

    When you have to match a range of IP addresses, it becomes necessary to construct a regular expression to perform the comparison. In the next series of steps, we will provide examples for how to construct such an expression to match the following address ranges (note that you will have to change these examples to match your public IP range):

    • 192.168.1.1 – 192.168.1.25

    • 10.0.0.1 – 10.0.0.14

    First, the basic pattern that will match a single IP address is as follows: \b###\.###\.###\.###\b

    Extending this, we can match two different IP addresses with an OR expression as follows: \b###\.###\.###\.###\b|\b###\.###\.###\.###\b

    So, an example to match just two addresses (such as 192.168.1.1 or 10.0.0.1) would be: \b192\.168\.1\.1\b|\b10\.0\.0\.1\b

    This gives you the technique by which you can enter any number of addresses. Where a range of address need to allowed, for example 192.168.1.1 – 192.168.1.25, the matching must be done character by character: \b192\.168\.1\.([1-9]|1[0-9]|2[0-5])\b

    Note

    The IP address is treated as string and not a number.

    The rule is broken down as follows: \b192\.168\.1\.

    This matches any value beginning with 192.168.1.

    The following matches the ranges required for the portion of the address after the final decimal point:

    • ([1-9] Matches addresses ending in 1-9

    • |1[0-9] Matches addresses ending in 10-19

    • |2[0-5]) Matches addresses ending in 20-25

    Note

    Note that the parentheses must be correctly positioned, so that you don’t start matching other portions of IP addresses.

    With the 192 block matched, we can write a similar expression for the 10 block: \b10\.0\.0\.([1-9]|1[0-4])\b

    And putting them together, the following expression should match all the addresses for “192.168.1.1~25” and “10.0.0.1~14”: \b192\.168\.1\.([1-9]|1[0-9]|2[0-5])\b|\b10\.0\.0\.([1-9]|1[0-4])\b

    Testing the Expression

    Regex expressions can become quite tricky, so we highly recommend using a regex verification tool. If you do an internet search for “online regex expression builder”, you will find several good online utilities that will allow you to try out your expressions against sample data.

    When testing the expression, it’s important that you understand what to expect to have to match. The Exchange online system may send many IP addresses, separated by commas. The expressions provided above will work for this. However, it’s important to think about this when testing your regex expressions. For example, one might use the following sample input to verify the examples above:

    192.168.1.1, 192.168.1.2, 192.169.1.1. 192.168.12.1, 192.168.1.10, 192.168.1.25, 192.168.1.26, 192.168.1.30, 1192.168.1.20

    10.0.0.1, 10.0.0.5, 10.0.0.10, 10.0.1.0, 10.0.1.1, 110.0.0.1, 10.0.0.14, 10.0.0.15, 10.0.0.10, 10,0.0.1

    Validating the Deployment

    Security Audit Logs

    To verify that the new request context claims are being sent and are available to the AD FS claims processing pipeline, enable audit logging on the AD FS server. Then send some authentication requests and check for the claim values in the standard security audit log entries.

    To enable the logging of audit events to the security log on an AD FS server, follow the steps at Configure auditing for AD FS 2.0

    Event Logging

    By default, failed requests are logged to the application event log located under Applications and Services Logs \ AD FS 2.0 \ Admin.For more information on event logging for AD FS, see Set up AD FS 2.0 event logging

    Configuring Verbose AD FS Tracing Logs

    AD FS tracing events are logged to the AD FS 2.0 debug log. To enable tracing, see Configure debug tracing for AD FS 2.0

    After you have enabled tracing, use the following command line syntax to enable the verbose logging level:

    wevtutil.exe sl “AD FS 2.0 Tracing/Debug” /l:5

    New Claim Types

    To provide additional request context information, Client Access Policy introduces the following new claim types, which AD FS generates from request header information for processing by the policy engine:

    X-MS-Forwarded-Client-IP

    Claim type: https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip

    This AD FS claim represents a “best attempt” at ascertaining the IP address of the user (for example, the Outlook client) making the request. This claim can contain multiple IP addresses, including the address of every proxy that forwarded the request.  This claim is populated from an HTTP header that is currently only set by Exchange Online, which populates the header when passing the authentication request to AD FS. The value of the claim can be one of the following:

    • A single IP address - The IP address of the client that is directly connected to Exchange Online

    Note

    The IP address of a client on the corporate network will appear as the external interface IP address of the organization’s outbound proxy or gateway.

    • One or more IP addresses

      • If Exchange Online cannot determine the IP address of the connecting client, it will set the value based on the value of the x-forwarded-for header, a non-standard header that can be included in HTTP based requests and is supported by many clients, load balancers, and proxies on the market.

      • Multiple IP addresses indicating the client IP address and the address of each proxy that passed the request will be separated by a comma.

    Note

    IP addresses related to Exchange Online infrastructure will not be present in the list.

    Warning

    Exchange Online currently supports only IPV4 addresses; it does not support IPV6 addresses.

    X-MS-Client-Application

    Claim type: https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application

    This AD FS claim represents the protocol used by the end client, which corresponds loosely to the application being used.  This claim is populated from an HTTP header that is currently only set by Exchange Online, which populates the header when passing the authentication request to AD FS. Depending on the application, the value of this claim will be one of the following:

    • In the case of devices that use Exchange Active Sync, the value is Microsoft.Exchange.ActiveSync.

    • Use of the Microsoft Outlook client may result in any of the following values:

      • Microsoft.Exchange.Autodiscover

      • Microsoft.Exchange.OfflineAddressBook

      • Microsoft.Exchange.RPC

      • Microsoft.Exchange.WebServices

      • Microsoft.Exchange.Mapi

    • Other possible values for this header include the following:

      • Microsoft.Exchange.Powershell

      • Microsoft.Exchange.SMTP

      • Microsoft.Exchange.PopImap

    X-MS-Client-User-Agent

    Claim type: https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-user-agent

    This AD FS claim provides a string to represent the device type that the client is using to access the service. This can be used when customers would like to prevent access for certain devices (such as particular types of smart phones).  This claim is populated from an HTTP header that is currently only set by Exchange Online, which populates the header when passing the authentication request to AD FS. Example values for this claim include (but are not limited to) the values below.

    Note

    The below are examples of what the x-ms-user-agent value might contain for a client whose x-ms-client-application is “Microsoft.Exchange.ActiveSync”

    • Vortex/1.0

    • Apple-iPad1C1/812.1

    • Apple-iPhone3C1/811.2

    • Apple-iPhone/704.11

    • Moto-DROID2/4.5.1

    • SAMSUNGSPHD700/100.202

    • Android/0.3

    Note

    It is also possible that this value is empty.

    X-MS-Proxy

    Claim type: https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy

    This AD FS claim indicates that the request has passed through the federation server proxy.  This claim is populated by the federation server proxy, which populates the header when passing the authentication request to the back end Federation Service. AD FS then converts it to a claim.

    The value of the claim is the DNS name of the federation server proxy that passed the request.

    X-MS-Endpoint-Absolute-Path (Active vs Passive)

    Claim type: https://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path

    This claim type can be used for determining requests originating from “active” (rich) clients versus “passive” (web-browser-based) clients. This enables external requests from browser-based applications such as the Outlook Web Access, SharePoint Online, or the Office 365 portal to be allowed while requests originating from rich clients such as Microsoft Outlook are blocked.

    The value of the claim is the name of the AD FS service that received the request.