question

MayurDighe-1944 avatar image
0 Votes"
MayurDighe-1944 asked ·

Claims rule to get WindowsAccountName

I have configured Claims Provider Trust in ADFS and I am getting only Email in NameID. I can not make changes to Third party Claims Provider Trust, so I have to get WindowsAccountName using Email which I received in NameID from Third Party IDP and forward it to applications ahead.

Can someone please help me to write Claim Rules to support this?

(Context: Publishing OWA with ADFS)

adfs
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

piaudonn avatar image
2 Votes"
piaudonn answered ·

Hi! According to this documentation you need to send the PrimarySID of the user as well as its UPN.

Assuming that a user exist in your forest with the UPN matching the NameID sent by the claim provider trust, you an just lookup the PrimarySID and the UPN. To look up the AD attribute store, you actually do not need the WindowsAccountName but just the domain name. Let's say the NetBIOS name of your domain is CONTOSO, then something of the sort would work.

Also, the suggested rules can be added at the end of the existing rules if you also have users from your own domain using it OWA. Else you can just remove the old rules and replace them with the following:

Rule 1: Take the NameID and make it the UPN

 c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"]
  => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", Value = c.Value);

Rule 2: Look for the PrimarySID with that UPN

 c1:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"] && c2:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"]
  => issue(store = "Active Directory", types = ("http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid"), query = "(&(objectCategory=person)(objectClass=user)(|(userPrincipalName={0})(&(mail={0})(!(userPrincipalName={0})))));objectSid;CONTOSO\random", param = c2.Value);
 

A couple of thing about this rule.

  1. If the UPN is not found because it is not set, then we fall back looking for the mail attribute. I wrote it that way because it is possible to not have UPN in AD. When that's the case the UPN is "calculated" but the attribute is empty else the query just looking for the UPN would fail. The fall back to mail isn't great either because modify the mail attribute of a user might grant some access. If you don't want to use that fallback, here would be the rule:

    c1:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";] && c2:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn";] => issue(store = "Active Directory", types = ("http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid";), query = "(&(objectCategory=person)(objectClass=user)(userPrincipalName={0}));objectSid;CONTOSO\random", param = c2.Value);

  2. You need to replace CONTOSO by your domain. You don't need ro replace "random" this does not matter. And because of this, the rule will not work well in multi domain environment. If that's your case, let us know.

· 7 · Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Really appreciate your answer. I will try and let you know the results. Just one question - Where should I put these rules? In Claims Provider or Relying Party?

0 Votes 0 · ·
piaudonn avatar image piaudonn MayurDighe-1944 ·

At the relying party trust (as long as you have a pass through rule for the NameID claim at the claim provider trust level).

0 Votes 0 · ·

Got it. Thank you very much for your response.

0 Votes 0 · ·

Could you by any chance help me adapt this a little?

I'm in mostly the same situation as the OP: I get a SAML assertion from a third-party claims provider containing among other things the NameID with the value of "username". My RP needs this in the format "DOMAIN\username" as type "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname";.

Using your excellent example above I can get ADFS to issue the right type of claim and populate it with the user's SID. How do I get it to populate the value with DOMAIN\username instead of the SID? I have only one domain so hardcoding isn't a problem for me.

0 Votes 0 · ·

My syntax thus far, 1000 char limit wouldn't let me post it all at once:

c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";] => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name";, Value = c.Value);

c1:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";] && c2:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name";] => issue(store = "Active Directory", types = ("http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname";), query = "(&(objectCategory=person)(objectClass=user)(samaccountname={0}));objectSid;MYDOMAIN\random", param = c2.Value);

0 Votes 0 · ·

It would be, two rules:

c1:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";] && c2:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn";] => add(store = "Active Directory", types = ("temp:claim/sam"), query = "(&(objectCategory=person)(objectClass=user)(userPrincipalName={0}));samaccountname;CONTOSO\random", param = c2.Value);

c:[Type == "temp:claim/sam"] => issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname";, Value = "CONTOSO\" + c.Value);

And you can replace CONTOSO by your domain.

1 Vote 1 · ·
Show more comments