SOLVED

ADFS Claims Based Rules - I'm stuck!

Iron Contributor

In my environment we are running Exchange 2013 Hybrid.  All mailboxes are in O365.  We have certain requirements around our implementation that require ADFS.  With that being said, I am really struggling with coming up with the set of claims based rules to accomplish my goal.  Our ADFS environment is in Azure (vpn to on-prem network, 1 DC, 2 ADFS servers, 2 ADFS Proxy).  Federation itself is up and running fine.  I feel like I have read the same handful of technet / blog post articles on setting this up but I must be missing something.  I am also struggling with being able to debug / trace to see excatly which claims are coming in with their values to determine why I am not getting expected results  

 

Here are the scenarios that I need (and have rules for):

1.  Block external Outlook access unless user is in the ADFS_Allow External Outlook AD Security Group

	exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy"])
	 && exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path", Value == "/adfs/services/trust/2005/usernamemixed"])
		 && exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application", Value == "Microsoft.Exchange.Autodiscover|Microsoft.Exchange.OfflineAddressBook|Microsoft.Exchange.RPC|Microsoft.Exchange.WebServices"])
	 && NOT exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip", Value =~ "\bXXX\.XXX\.XXX\.XXX\b|\bXX\.XX\.XX\.XX\b|\bXX\.XX\.XX\.XX\b"])
	 && NOT exists([Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "\bS-1-5-21-XXXX-XXXX-XXXX-XXX2\b"])
=> issue(Type = "http://schemas.microsoft.com/authorization/claims/deny", Value = "true"); 

2.  Block external OWA unless user is in the ADFS_Allow External OWA AD Security Group

exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy"])
 && exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path", Value == "/adfs/ls"])
 && NOT exists([Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "\bS-1-5-21-XXXX-XXXX-XXX-XXX\b"])
 && NOT exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip", Value =~ "\bXXX\.XXX\.XXX\.XX]\b|\bXX\.XXX\.XX\.XX\b|\bXX\.XX\.XX\.XX\b"])
=> issue(Type = "http://schemas.microsoft.com/authorization/claims/deny", Value = "true"); 

In both examples the IP addresses included in the regex are the public IP addresses of our 3 locations.  IP and SID have been redacted.  

 

I have looked at the insidecorporatenetwork rule vs the proxy / forwarded-client-ip -- and either way, I can't seem to get anywhere.  I would really love to be able to trace end-to-end to view all of the claims and values to understand why someone is allowed / denied access.

 

Any help in pointing me in the right direction would be greatly appreciated.

 

Steve

13 Replies

@Trevor Seward gave a presentation on configuring ADFS in Azure yesterday, he may be able to offer some assistance.

best response confirmed by Stephen Bell (Iron Contributor)
Solution

Which version are you using? x-ms-proxy only works with the 2008 R2 version, if you are on 2012 R2 you should use insidecorporatenetwork. If your clients are Office 2016/Office 2013 SP1, you most likely have modern authentication enabled and all traffic will be hitting the passive endopoint (/adfs/ls), so you should account for this. To monitor the rules, check your event logs (assuming auditing is enabled for AD FS).

Thank you for the response!

 

My clients are running Office 2013 (not sure on service pack version) OR  some Office 2016.  I do not believe that I have Modern Authentication turned on because I knew that everything would present itself as passive.  I figured I would cross that bridge once I got my entire environment to v2016.

 

My servers are 2012 R2.  

 

I have been looking at my event logs and cannot see what I would expect to see.  May have to do with the proxy vs insidecorporatenetwork.  I will give this a shot and post back.

 

Thank you again

Steve

Modern auth is enabled by default on Office 2016, so definitely check for that. But yes. the first priority should be changing the rules to use insidecorporatenetwork if you are on 2012 R2.

I have had some success with using insidecorporatenetwork and as a result I am trying to re-engineer my rules.  I am currently trying to block OWA for users outside our walls and NOT in a specific security group.  I am not having luck.  Here is my rule:

exists([Type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", Value == "false"])
 && NOT exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip", Value =~ "\b1XX.XXX.XX.4]\b"])
 && exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path", Value == "/adfs/ls"])
 && NOT exists([Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "\bS-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-2107\b"])
 => issue(Type = "http://schemas.microsoft.com/authorization/claims/deny", Value = "true");

The user I am testing with is not a member of my Allow OWA group, and therefore I would expect the attempt to fail.  If I look in my event log here is what I see for this particular authentication attempt - which succeeds.

These are all event id 500 or 501:

 Issued identity: 
http://schemas.xmlsoap.org/claims/UPN 
shelleyc@mycompany.com 
http://schemas.microsoft.com/LiveID/Federation/2008/05/ImmutableID 
<redacted> 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier 
<redacted> 
http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant 
2016-10-28T18:16:55.203Z 
http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod 
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport 

Caller identity: 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/implicitupn 
shelleyc@mycompany.local 
http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod 
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport 
http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant 
2016-10-28T18:16:55.203Z 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn 
shelleyc@mycompany.com 
http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid 
S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-513 
http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid 
S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-2104 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name 
mycompany\shelleyc 
http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname 
mycompany\shelleyc 
http://schemas.microsoft.com/claims/authnmethodsreferences 
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-513

Caller identity: 
http://schemas.microsoft.com/2012/01/requestcontext/claims/client-request-id 
1f08feb8-927f-4e6f-ad8a-0859da3a4398 
http://schemas.microsoft.com/2012/01/requestcontext/claims/relyingpartytrustid 
https://login.microsoftonline.com/login.srf 
http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip 
66.XXX.XX.19 
http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip 
66.XXX.XX.19 
http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-ip 
40.XXX.XXX.225 
- 
- 
- 
- 
- 
- 
- 
- 
- 
-

Caller identity: 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-1-0 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-32-545 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-2 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-11 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-15 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-18-2 
http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-user-agent 
Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko 
http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path 
/adfs/ls/ 
http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork 
false 
http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy 
sic-wap-a

Caller identity: 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/implicitupn 
shelleyc@mycompany.local 
http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod 
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport 
http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant 
2016-10-28T18:16:55.203Z 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn 
shelleyc@mycompany.com 
http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid 
S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-513 
http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid 
S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-2104 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name 
mycompany\shelleyc 
http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname 
mycompany\shelleyc 
http://schemas.microsoft.com/claims/authnmethodsreferences 
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-513

Caller identity: 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-1-0 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-32-545 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-2 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-11 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-15 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-18-2 
- 
- 
- 
- 
- 
- 
- 
-

Issued identity: 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/implicitupn 
shelleyc@mycompany.local 
http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod 
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport 
http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant 
2016-10-28T18:16:55.203Z 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn 
shelleyc@mycompany.com 
http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid 
S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-513 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-513 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-1-0 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-32-545 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-2 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-11

Issued identity: 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-15 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-18-1 
http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid 
S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-2104 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name 
mycompany\shelleyc 
http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname 
mycompany\shelleyc 
- 
- 
- 
- 
- 
- 
- 
- 
- 

Caller identity: 
http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname 
mycompany\shelleyc 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn 
shelleyc@mycompany.com 

Caller identity: 
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name 
mycompany\shelleyc 
http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid 
S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-2104 
http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid 
S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-513 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-513 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-1-0 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-32-545 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-2 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-11 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-5-15 
http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid 
S-1-18-1

 

The missing piece is this user does not match the groupsid in the rule - which I would expect to issue a deny???

 

Thanks

Steve

 

There seems to be an extra bracket in the rule you entered:

 

Value =~ "\b1XX.XXX.XX.4]\b"

 

Also, try doing exact match agains the group SID, for example:

 

exists([Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value == "S-1-5-21-...."])

 

Lastly, I'd recommend avoiding the use of both insidecorporatenetwork and x-ms-forwarded-client-ip in the same rule.

Looks like I finally got this - turns out I was missing a "/" on the "/adfs/ls" portion of the rule.

 

exists([Type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", Value == "false"])
 && NOT exists([Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "S-1-5-21-XXX-XXX-XXX-2107"])
 && exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path", Value == "/adfs/ls/"])
 => issue(Type = "http://schemas.microsoft.com/authorization/claims/deny", Value = "true");

Thank you for your help with this.  Now on to doing the same thing with outlook access

Steve

Stephen,

 

Were you ever able to "Block external Outlook access unless user is in the ADFS_Allow External Outlook AD Security Group"?  If so, would you be able to share the syntax you used to accomplish the task please?  Also, is Modern Authentication enbled in your tenant?

 

Thank you,

 

Kevin

Kevin --

 

I never got it to work - but to be honest, I had to put it down and work on other, higher priority projects.  That being said - I had a rule that seemed to work *sometimes*, and I couldn't pin down exactly what was going on.  I did learn a lot about reading the logs and I intend to pick this up again in the future.

 

I believe this is where I left off:

 

exists([Type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", Value == "false"])
&& NOT exists([Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "S-1-5-21-xxx-xxx-xxx-xxxx"])
&& exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path", Value == "/adfs/services/trust/2005/usernamemixed"])
&& exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application", Value == "???????"])
=> issue(Type = "http://schemas.microsoft.com/authorization/claims/deny", Value = "true");

I believe the x-ms-client-application should be Microsoft.Exchange.RPC OR Microsoft.Exchange.ActiveSync (not sure on the case), OR Microsoft.Exchange.Autodiscover (not sure on case), OR Microsoft.Exchange.Webservices.  I just never got the syntax quite right.

 

Also - my clients are not using modern authentication.  Last I knew, all modern authentication traffic presented itself to the adfs/ls endpoint and thus - you could not decipher active from passive connections.  Maybe that has changed in the past couple of months?!?!

 

If this helps or you end up getting the rule right - please let me know.  I would love ot have someone working in toward the same goal to bounce ideas off of.

 

Thanks

sb

I'm working on this exact same problem. Discouraging to see there is no accepted solution. Also using ADFS 3.0 with WAP, Outlook 2016 and modern auth. Need a solution to this MS! I'll let you know what we find as it's high priority for us.

The best way to troubleshoot ADFS claims is with fidler. Fidler can catch your certificate thumbprint so you can see the claims which are communicating. If you are doing this make sure you have your ADFS, and party trust in the right order. Then you go to the page https://adfs.domain.nl/adfs/ls/IdpInitiatedSignOn.aspx and logon with an account that needs SSO. Make sure Fidler runs simultaneously and catches your data.

Thanks to much help from Vasil and research in Azure AD Conditonal Access, I was able to determine that nothing is going to prevent Modern Authentication clients at the AD FS level.  There is no x-ms-client-application being presented by the application anymore (with modern auth).  Instead you have to use Azure AD Conditional Access which is in preview in the new portal.  It seems to work well. 


I used conditional access for the modern auth and for legacy auth I used this claim rule

 

NOT exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip", Value =~ "\bXXX\.XXX\.XXX\.XXX\b"])
 && exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application", Value =~ "Microsoft.Exchange.Mapi|Microsoft.Exchange.Autodiscover|Microsoft.Exchange.OfflineAddressBook|Microsoft.Exchange.WebServices"])
 => issue(Type = "http://schemas.microsoft.com/authorization/claims/deny", Value = "DenyUsersWithClaim");

 

It is quite easy to see what is going on in the Security Log when you properly enable auditing per this article https://jorgequestforknowledge.wordpress.com/2013/07/08/enabling-auditing-of-issued-claims-in-adfs-v...

 

Look for EventIDs, 299, 500 & 501

 

This way you can adjust your claim rules to your environment.


Hope this helps!

This was what worked for me. I eventually had to use the user agent claim. Agreed, it will only cover Outlook but that works for now, will add additional useragents in future.

 

Although I am not sure at this point, it looks like this started affecting users on the network who had mailboxes on prem but archives in the cloud, or who had calendar sharing with users int he cloud because they continued to see prompts in Outlook, which makes no sense because all the conditions are ANDed and insidecorporatenetwork is set to false.

 

exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path", Value =~ "/adfs/(ls/|services/trust/2005/usernamemixed)"])
&& exists([Type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", Value == "false"])
&& exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-user-agent", Value =~ "Outlook"])
=> issue(Type = "http://schemas.microsoft.com/authorization/claims/deny", Value = "true");

1 best response

Accepted Solutions
best response confirmed by Stephen Bell (Iron Contributor)
Solution

Which version are you using? x-ms-proxy only works with the 2008 R2 version, if you are on 2012 R2 you should use insidecorporatenetwork. If your clients are Office 2016/Office 2013 SP1, you most likely have modern authentication enabled and all traffic will be hitting the passive endopoint (/adfs/ls), so you should account for this. To monitor the rules, check your event logs (assuming auditing is enabled for AD FS).

View solution in original post