Quantcast
Channel: Active Directory Federation Services – Hybrid Identity
Viewing all articles
Browse latest Browse all 26

AD FS 2.0 Issuance Authorization Rules: ensure two attributes match

$
0
0

I previously posted a couple of examples of AD FS 2.0 Issuance Authorization (AuthZ) Rules that I’ve used.  Troy posted a comment asking whether or not there is a way to ensure that two attributes match.  His specific example was can we only grant access if we can guarantee that UPN and e-mail are the same.

The short answer is yes, you can do this.  Although it wasn’t easy!  Smile

At first I figured we’d use a combination of exists and regex however that won’t work because there’s no way of injecting variables into the regex and if you did something like exists(Type = sometype, Value =~ someregex) && (Type = sometype, Value =~ someregex) that would match anything that matched the regex, e.g. paul@contoso.com and chuck@fabrikam.com.

My colleague Rahul Gangwar, an AD FS and WIF expert, pointed me in the right direction.  He said to use two rules.  One to create a temporary claim that is a concatenation and the second to parse it for equality.  How to deduce equality in a regex?  As I’ve already stated you can’t compare two values using the same regex and you can’t use repetition.  You can, however, use back-references.

So after several attempts, and thanks to the indispensable RegEx Builder, I finally worked out a regex that matches two e-mail addresses with a delimiter:

(?i)(^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4});\1

With the background described let’s look at how we achieve Troy’s ask.  We need two AuthZ rules:

  1. Concatenate
  2. Match

Here they are:

Concatenate equality values

c1:[Type == “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn“]
&& c2:[Type == “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress“]
=> add(Type = “http://tmp/emailupn“, Value = c1.Value + “;” + c2.Value);

Compare values

c:[Type == “http://tmp/emailupn”, Value =~ “(?i)(^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4});\1”]
=> issue(Type = “http://schemas.microsoft.com/authorization/claims/permit”, Value = “true”);

The first rule, concatenate equality values, adds the UPN claim and the Email Address claim, delimited by a semi-colon, into a single temporary claim of the arbitrary type http://tmp/emailupn.

The second rule, compare values, issues a permit claim if the UPN and the e-mail address match.  The match is case-insensitive, i.e. paul.williams@contoso.com and Paul.Williams@contoso.com are the same.

Summary

I probably shouldn’t have used UPN and email as an example for this technique as it’s a bit of a tricky example.  But I wanted to address the comment.  After all, Troy was good enough to read my post and comment.  The approach is sound and can be used for other values too.  You just need to adopt the regex, e.g. (?i)(\w+);\1 would match any two words, so you could check two simple string values.  I think it wise to always perform a case-insensitive match via (?i) and let me give you a tip – don’t double escape like you would in C# or Java…



Viewing all articles
Browse latest Browse all 26

Trending Articles