Securing and restricting access to Office 365 with custom AD FS claimrules

We’ve been working hard with one of our clients to secure access to Office 365 workloads such as Exchange Online. In this specific article we will share our experience how to restrict access to Exchange Online to specific networks and for specific protocols.

This client was using MobileIron for securing mobile devices and wanted to integrate this MDM solution with Office 365.

The tricky part of securing access to Exchange Online with MobileIron is the fact that MobileIron Sentry servers require dedicated IP adresses to Exchange. As you can imagine, the always changing Office 365 Cloud – with all it’s IP Addresses – will make it hard to follow this requirement. Thus we had to use a different technology, outside of MobileIron for restricting access to Office 365.

We chose to implement custom claimrules in AD FS, the enviroment we built this solution for on was an AD FS 2016 farm. In this new version of AD FS there are several changes on how to create custom claim rule, by default AD FS 2016 uses Access Control Policies and with these policies it was not possible to create such custom claim rules. So before we begin, we will start with explaining how torevert back to making use of the old school way of creating claim rules

  1. Log on the one of your AD FS servers
  2. Fire up PowerShell and run these commands
    1. $ADFSRpt = Get-AdfsRelyingPartyTrust -Name “Microsoft Office 365 Identity Platform”
    2. Set-AdfsRelyingPartyTrust -TargetRelyingParty $ADFSRpt -AccessControlPolicyName $null
    3. Set-AdfsRelyingPartyTrust -TargetRelyingParty $ADFSRpt -IssuanceAuthorizationRules $null
    4. Set-AdfsRelyingPartyTrust -TargetRelyingParty $ADFSRpt -IssuanceAuthorizationRules ‘@RuleName = “TEMP RULE” exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy”%5D) => issue(Type = “http://schemas.microsoft.com/authorization/claims/deny”,Value = “true”);’
  3. Open the AD FS Management Console
  4. Navigate to “Relying Party Trusts” and select the Office 365 relying party trust.
  5. Click on “Edit Access Control Policy” in the right menu to find the old menu for configuring “Issuance Authorization Rules”
  6. Remove the “TEMP RULE’ but DO NOT close the window
    Issuance AuthorizationRules

Now here the cool part comes, which is actually restricting specific traffic and protocols to specific networks, for instance SMTP or EWS traffic.

Restricting ActiveSync Protocol

  1. Add new rule
  2. Insert the following custom claim
  3. This claim contains the dedicated IP Adress from the MobileIron Sentry server from which we do accept ActiveSync traffic to Office 365. All other IP adressess are denied.

exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy”%5D)
&& exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application”, Value == “Microsoft.Exchange.ActiveSync”])
&& NOT exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip”, Value =~ “\b82\.125\.45\.23\b”])
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/deny”, Value = “true”);

Restricting IMAP Protocol

  1. Add new rule
  2. Insert the following custom claim
  3. This claim contains the dedicated IP Adress from the MobileIron Sentry server from which we do accept IMAP traffic to Office 365. All other IP adressess are denied.

exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy”%5D)
&& exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application”, Value == “Microsoft.Exchange.Imap”])
&& NOT exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip”, Value =~ “\b82\.125\.45\.23\b”])
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/deny”, Value = “true”);

Restricting SMTP Protocol

  1. Add new rule
  2. Insert the following custom claim
  3. This claim contains the dedicated IP Adress from the MobileIron Sentry server from which we do accept SMTP traffic to Office 365. All other IP adressess are denied.

exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy”%5D)
&& exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application”, Value == “Microsoft.Exchange.SMTP”])
&& NOT exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip”, Value =~ “\b82\.125\.45\.23\b”])
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/deny”, Value = “true”);

Restricting POP Protocol

  1. Add new rule
  2. Insert the following custom claim
  3. This claim contains the dedicated IP Adress from the MobileIron Sentry server from which we do accept POP traffic to Office 365. All other IP adressess are denied.

exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy”%5D)
&& exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application”, Value == “Microsoft.Exchange.Pop”])
&& NOT exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip”, Value =~ “\b82\.125\.45\.23\b”])
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/deny”, Value = “true”);

Restricting EWS Protocol

  1. Add new rule
  2. Insert the following custom claim
  3. This claim contains the public IP Adress range from the on-premises network from which we do accept EWS traffic to Office 365. All other IP adressess are denied. For this claimrule we also require the hybrid Exchange servers to send EWS traffic to Office 365 for delivering rich-coexistence functionality to all users. This example allows traffic from the range of 82.125.45.1 – 82.125.45.14.

exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy”%5D
&& exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application”, Value == “Microsoft.Exchange.SMTP”])
&& NOT exists([Type == “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip”, Value =~ “\b82\.125\.45\.([1-9]|1[0-4])\b”])
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/deny”, Value = “true”);

Now the current rule configuration should look like this:

Issuance AuthorizationRules2

The last rule to be added is a standard rule “Permit Access to All Users” and be sure this rule is at the bottom of the list with the “Permit” action.

Now all desired Exchange protocols are restricted to anywhere besides the MobileIron Sentry server or either the on-premises network range for some EWS traffic to support free/busy and other hybrid traffic to Exchange on-premises. However the new Outlook for iOS and Android app doesn’t use these traditional Exchange protocols. This new nifty app uses the Graph API for fetching e-mail and other resources.

To restrict access from unknown clients to Exchang Online with the use of the Outlook for iOS or Android app we chose to make use of Conditional Access for Azure Active Directory. And restrict access from any other networks then the public IP address from the Sentry server. To make use of this feature an Azure Active Directory Premium P1 license is required though!

A last fun fact to end this blogpost with is the fact that the documentation provided by Microsoft on TechNet is incorrect. The technet documentation on Limiting Access to Office 365 Services Based on the Location of the Client lists an incorrect HTTP Header for Imap traffic Microsoft.Exchange.PopImap. After a lot of searching and troubleshooting with Microsoft our eye fell on a little detail in the ADFS trace logs which caused the initial claimrule for Imap to fail. We found out that HTTP Headers for Imap traffic use the value Microsoft.Exchange.Imap and not Microsoft.Exchange.PopImap as described in the article!! Below here you can find the event registered in the AD FS Trace Logs from a IMAP client:

Following request context headers present:

X-MS-Client-Application: Microsoft.Exchange.Imap
X-MS-Client-User-Agent: –
client-request-id: 6338b8c2-c283-4c93-2c00-0080000000c6
X-MS-Endpoint-Absolute-Path: /adfs/services/trust/2005/usernamemixed
X-MS-Forwarded-Client-IP: xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxx
X-MS-Proxy: WAP
X-MS-ADFS-Proxy-Client-IP: xxx.xxx.xxx.xxx

Big shout-out to my fellow friend and teammember Kevin Raap for working together on the claimrules, and finding out the flaw in Microsoft Technet documentation.

Intune device enrollment AD FS sign-in error “An error occurred. Contact your administrator for more information.”

Recently a client of mine added Windows Intune to their existing Office 365 subscription. The enablement of Intune requires users to install the Company Portal App on their mobile device which enrolls their device to your Office 365 organization.

In the process of enrolling a device it asks to login to Office 365. When a user tries to login with a federated Identity useraccount the login session will be redirected to your local AD FS sign-in page. However, when this is done from a mobile device it throws an error.

“An error occurred. Contact your administrator for more information.”

4-2-2016 14-17-03

Now once you have a look on the AD FS Admin eventviewer logging which can be found under the Applications and Services tree in the eventviewer MMC snap-in.

There you will find the error listed below:

Encountered error during federation passive request.

Additional Data

Protocol Name:
wsfed

Relying Party:
urn:federation:MicrosoftOnline

Exception details:
Microsoft.IdentityServer.Service.Policy.PolicyServer.Engine.InvalidAuthenticationTypePolicyException: MSIS7102: Requested Authentication Method is not supported on the STS.
at Microsoft.IdentityServer.Web.Authentication.GlobalAuthenticationPolicyEvaluator.EvaluatePolicy(IList`1 mappedRequestedAuthMethods, AccessLocation location, ProtocolContext context, HashSet`1 authMethodsInToken, Boolean& validAuthMethodsInToken)
at Microsoft.IdentityServer.Web.Authentication.AuthenticationPolicyEvaluator.RetrieveFirstStageAuthenticationDomain(Boolean& validAuthMethodsInToken)
at Microsoft.IdentityServer.Web.Authentication.AuthenticationPolicyEvaluator.EvaluatePolicy(Boolean& isLastStage, AuthenticationStage& currentStage, Boolean& strongAuthRequried)
at Microsoft.IdentityServer.Web.PassiveProtocolListener.GetAuthMethodsFromAuthPolicyRules(PassiveProtocolHandler protocolHandler, ProtocolContext protocolContext)
at Microsoft.IdentityServer.Web.PassiveProtocolListener.GetAuthenticationMethods(PassiveProtocolHandler protocolHandler, ProtocolContext protocolContext)
at Microsoft.IdentityServer.Web.PassiveProtocolListener.OnGetContext(WrappedHttpListenerContext context)

Solution:

  1. Logon to AD FS server(s).
  2. Open the AD FS Management Console
  3. On the right hand side right click on the Authentication Policies folder
  4. Choose “Edit Global Primary Authentication…”
  5. In this menu you should check (enable) Forms Authentication on both Intranet and Extranet.

 

After enabling forms authentication on both sides the AD FS requests sent from mobile devices will be succesfully authenticated by the AD FS secure token service.

Filter OU’s to be synchronized to Office 365 with Windows Azure Active Directory Sync

When performing Office 365 deployments for most companies DirSync comes in the picture. Or as Microsoft prefers to call it, Windows Azure Active Directory Sync. Since most of the IT environments become polluted when time flies by most of my client’s prefer to perform a limited synchronization with DirSync.

As said earlier, most IT environments become polluted by time. As Active Directory Users & Computers is one of the most heavily administered you can imagine how much dirt sneaks in which makes it very interesting for businesses. Therefore Microsoft has a way to perform a limited DirSync based on OU (Organizational Unit) hierarchy and selection. For this we have to digg our way into ForeFront Identity Manager.

For this we have to open the FIM 2010 console by navigating to the following directory “C:\Program Files\Windows Azure Active Directory Sync\SYNCBUS\Synchronization Service\UIShell”.

Here you will find a executable called miisclient.exe. Run this application with “Run as administrator” priviliges. Make sure the account which initiates the request is member of the “Domain Admins” and the “Enterpirse Admins” security groups within your ADS forest. It’s also required to be a member of the local security group “FIMSyncAdmins” on the DirSync server.

Please refer to the image illustrated here for the instructions listed below.
FIM_console_instructions1
1. Click on “Management Agents” in the top ribbon.
2. Right click on the “Active Directory Connector” management agent and select “Properties”.
3. Click on “Configure Directory Partitions” on the left hand side of the menu.
4. Click on “Containers” and fill in the credentials of the local ADS service account.
5. After filling in the credentials a windows opens with the AD forest hierarchy. Here you can select the required Organizational Unit’s. Please refer to the image illustrated below.
FIM_console_instructions2

After selecting the prefered OU’s select OK and save the configuration. Next is waiting for DirSync to kick of a fresh Delta Sync. If you can’t wait then fire up PowerShell on the DirSync server and run the following two cmd-lets:

1. Import-Module DirSync
2. Start-OnlineCoexistenceSync -FullSync

Hope this helps fellow IT Professionals deploying succesfull Office 365 product. And obviously it is best to configure this filtering before Windows Azure Directory Sync synchronizes for the first time.

Change explicit User Principal Names to match Office 365 domain suffix

Most Enterprise Office 365 clients will use Active Directory Federation Services and Windows Azure Active Directory Sync, also known as DirSync for Single Sign-On functionality with Office 365.

Standard AD FS will use the on-premises UPN to access services in Office 365. Therefore Microsoft advises to make sure User Principal Name suffixes and e-mail adress suffixes match to make life simpler. Most ADS domains still use an internal routable domainname for instance contoso.local. However when implementing AD FS with Office 365 it permitted to have an “internet routable” domain suffix for instance contoso.com.

The best solution for this before implementing and running a DirSync is to create a new User Principal Name suffix to match your Office 365 domain suffix. This can be done by adding a new UPN suffix by going to:

  1. Open Active Directory Domains and Trusts
    2. Right click on the top level of the tree in the left pane and select properties
    3. Add the new internet routable UPN suffix e.i. contoso.com

Next step is to change the explicit User Principal Names for all the designated user objects in Active Directory which you plan to synchronize to Office 365. The easiest way to do this is with the help of allmighty PowerShell.

I wrote this easy one-liner which allows you to target a specific OU in Active Directory. Don’t forget to use the Active Directory Module for PowerShell.

Get-ADUser -Filter * -SearchBase ‘OU=Users,DC=fabrikam,DC=local’ -Properties userPrincipalName | foreach { Set-ADUser $_ -UserPrincipalName “$($_.samaccountname)@contoso.com”}

After succesfully running the cmd-lets you will notice the new UPN suffix is configured for the targeted user objects in ADS.

Set Calendar Reviewer rights to all users in Office365

Most companies have policies which permit all users to share their calendars with everyone. There are several PowerShell scripts available online to configure this. However the tricky thing is most enterprises have different Outlook client languages. Because the Outlook client language determines the mailboxfolder attribute to it’s unique language. In this case it is set to the Dutch version “kalender” and the Engilsh version “calendar”.

  1. The fist thing which needs to be done is creating a mail-enabled universal securitygroup on-premises which contains all user objects. Make sure it syncs to Office365 with Windows Azure DirSync.
  2. Once the objects have been succesfully synchronized to the cloud run the script below to determine which language the calendar mailbox folder is:

    $GroupMembers = Get-DistributionGroupMember SG_CalendarReviewer
    $GroupMembers | foreach {
    try
    {
    $isNL = ((Get-MailboxRegionalConfiguration -Identity $_.PrimarySmtpAddress | where {$_.Language -eq “nl-NL”} | Measure).Count -eq 1)
    if ($isNL)
    {
    $identity = $_.PrimarySmtpAddress + “:\Kalender”
    }
    else
    {
    $identity = $_.PrimarySmtpAddress + “:\Calendar”
    }$permission = Get-MailboxFolderPermission -Identity $identity -ErrorAction SilentlyContinue | where {$_.User.toString() -eq “SG_CalendarReviewer”}
    if ($permission)
    {
    write-host “$identity has permission”
    }
    else
    {
    write-warning “$identity doest not have permission”
    } }
    catch
    {

    }
    }

  3. Once you have determined which language the mailboxfolder is for the calendar run this PowerShell script to grant all users in the created securitygroup with the ” Reviewer” on every mailbox belonging to each user object in the securitygroup. The PowerShell script listed below grants the access-right to all English calendars:

    $GroupMembers = Get-DistributionGroupMember SG_CalendarReviewer
    $GroupMembers | foreach {
    $identity = $_.PrimarySmtpAddress + “:\calendar”
    $permissionExists = ((Get-MailboxFolderPermission -Identity john.doe@domain.com:\calendar | where {$_.User.toString() -eq “SG_CalendarReviewer”} | measure).Count -eq 0)
    #Add-MailboxFolderPermission -Identity -User SG_CalendarReviewer -AccessRights Reviewer
    }

  4. Now change the mailboxfolderpermission attribute to the appropiate language and run the last script again.

Blog at WordPress.com.

Up ↑