Thursday, June 22, 2017

ADFS : Moving the "Active Directory" IDP entry to the top of the list

This is for ADFS 4.0 (Server 2016).

This post shows how to rename the "Active Directory" IDP and at the bottom of the post is a comment around "move Active Directory to Top" and some script.

This script assumes a set number of IDP and looking at the script, it seems to move the names but not the URL i.e. if you had two IDP viz. IDP A and "Active Directory", it would swop the names around but clicking "Active Directory" would in fact navigate to IDP A.

Also, there are other considerations as mentioned by @Jorge in a reply:

"The list of IdPs in general is dynamic as you may add or remove an IdP. The code should take that into account.

In addition, per RP trust you can also specify a list of IdP that are allowed to use that RP trust and that list is a subset of the overall list of IdPs. Again, the code should take that into account.

It should not matter how long the IdP list is.

Is it possible to make this dynamic where the logic is something like:

* if more than 1 IdP is listed and the AD IdP is included, then move that IdP to the top."

I needed to move this entry to the top.

I would not have got this to work without having the ability to debug.

This is the script I came up with:

// This script moves the "Active Directory" entry (the local IDP) to the top of the list.

// Per RP trust you can specify a list of IdP that are allowed to use that RP trust and that list is a subset 
// of the overall list of IdPs. This list may not have an "Active Directory" entry.

// If there is only one entry, no point in re-ordering!

// The logic is:

// If more than one IDP is listed and the "Active Directory" IDP is included, then move that IdP to the top.

//debugger;

var idp = document.getElementsByClassName("idp");

var totElements = idp.length;

var listAllSpanForIdp = document.getElementsByClassName("idpDescription float");

var adElementPresent = false;

var inc;

for (inc = 0; inc < listAllSpanForIdp.length; inc++) {
  if (listAllSpanForIdp[inc].innerText == "Active Directory") {
    adElementPresent = true;
  }
}

if ((totElements > 1) && (adElementPresent)) {
  var lastElement = totElements - 1;

  idp[lastElement].parentNode.insertBefore(idp[lastElement], idp[0]);
}

I move the elements around in the DOM as per this.

idp[lastElement].parentNode.insertBefore(idp[lastElement], idp[0]);

This inserts one node before the other.

You get the parent of the node. You then call the insertBefore method on the parent and you pass it the idp[lastElement] node (the "Active Directory" IDP  one) and tell it you want it inserted before idp[0] (the first one). This then swops their order.

This seems to work across all the requirements.

Enjoy!

4 comments:

Tim van Dijen said...

I have two ADFS environments where I wanted to use this script to put one specific IDP on top.. One was already in the right order, the other was not. However for consistency and to prevent future issues when IDPs are added/removed I wanted to use the script on both environments..
Strangely enough the one that used to be in the right order got broken after running this. Apparently if the IDP that needs to be in top is already on top, it will move it down.

I have made two minor changes to the code:
```
for (inc = 0; inc < listAllSpanForIdp.length; inc++) {
if (listAllSpanForIdp[inc].innerText == "Active Directory") {
adElementPresent = true;
break
}
}
```
The `break` was added

```
if ((totElements > 1) && (adElementPresent) && (inc > 0)) {
var lastElement = totElements - 1;

idp[lastElement].parentNode.insertBefore(idp[lastElement], idp[0]);
}
```
The `inc > 0` was added

nzpcmad said...

Thanks!

Anonymous said...

Thanks so much. Helped me changed the order on our ADFS.

Tim van Dijen said...

It's cute, but 10 months later I have no clue what I was doing here..
Apparently I helped someone, so that good!