Hi Team,
We are doing some work to integrate ignition for Active directory.
Following is what my college has done and results of it. Do we have other documentation which can help us to setup users within ignition.
The businesses are transitioning towards standardizing the use of Azure Active Directory SAML for authentication for all business applications. During my , I successfully implemented SAML integration in Ignition by following the instructions provided in the documentation: https://docs.inductiveautomation.com/display/DOC80/SAML+Example. However, I'm currently uncertain about the subsequent steps necessary to map users with their respective roles and permissions within the Ignition application. Additionally, I'm a bit confused about how to integrate the Active Directory security groups into the Ignition application.
@mandeep_gill what you will get back from a SAML IDP is a list of AD group names that you have been granted access to. What you want to do is convert those to roles.
We accomplish this with a scripting module that plugs into ignition and is called from the roles user attribute field with an expression. We pass in the ad groups and the host name like this:
runScript("system.idp.processIdpResponse("+{idp-attributes://saml:Attribute[@Name='adgroups']}+", system.net.getHostName())")
In the actual module it simply does this (some things retracted for privacy):
@Override
protected ArrayList<String> assignRoles(List<String> samlResponse, String hostName, String country) {
ArrayList<String> adGroups = new ArrayList<>();
ArrayList<String> assignedRoles = new ArrayList<>();
HashMap<String, List> roleMap = new HashMap<>();
for (String member: samlResponse){
adGroups.add(member.split(",")[0].replace("CN=", ""));
}
String siteNum = getSiteNum(hostName);
if(!siteNum.equals("other")) {
String base = "hidden" + siteNum;
roleMap.put("User", Collections.singletonList(base));
roleMap.put("Operations", Arrays.asList(base + "_ops", "hidden"));
roleMap.put("Maintenance", Collections.singletonList("hidden"));
}
else roleMap.put("Operations", Collections.singletonList("hidden"));
roleMap.put("ReadOnlyUse", Collections.singletonList("hidden"));
roleMap.put("siteEngineering", Collections.singletonList("hidden"));
roleMap.put("remoteEngineering", Collections.singletonList("hidden"));
roleMap.put("Developer", Arrays.asList("hidden"));
for (String role : roleMap.keySet()) {
for (String adGroup : adGroups) {
if (roleMap.get(role).contains(adGroup.toLowerCase())) {
if (!assignedRoles.contains(role)) {
assignedRoles.add(role);
}
}
}
}
return assignedRoles;
}
}
Rgds,
Nick
Any particular reason for making a module?
I do a similar thing but utilise the gateway scripting project and just call a function there.
1 Like
Thanks Nic,
I can't compile the script in gateway script under timer. I believe there is syntax error.....
or i am doing something wrong here?.... i haven't dealt with classes or modules in ignition...
NIck's example is java from a 3rd-party add-on module, not jython. You will need to reimplement in jython or develop a 3rd-party module.
Thanks Pturmel,
Is there any other way to use the built in functions of ignition to deal with SAML..... or best practice to go about it?
Nick's sample looks pretty good. Treat it as pseudocode as you write your own jython. (As noted by deon, that is perfectly reasonable.) I don't do any of this with my clients, so I have no first-hand samples for you.
We use OpenID Connect for Azure AD instead of SAML but they should be close in implementation. It seems you have the roles coming across already.
You should be able to use those Roles everywhere where you used to use a native Ignition role. Ignition might not recognize it when you type it in but it should work. Have you tried to see if it works?
Thanks David,
No i havn't tried it yet. what is the syntax to use in scripting?
Our roles are mapped to security groups in Enterprise Applications (Azure AD terminology). Therefore we add users to those groups in Azure AD, then that information is brought over to Ignition via the mapping in the Users/Groups section of Enterprise Applications.
In Ignition, the user comes across with the roles. I believe you had this in one of your screenshots so that is showing that it is working. The difference is that the same role list would have all of our Ignition roles in it as well (created in Azure AD as security groups, then mapped to Roles in AzureAD)
Therefore, no more mapping of users to roles is needed in Ignition. I believe we did not create roles in Ignition either (just Azure AD)
We just add the roles wherever we used them before such as Client Roles for Login.
We don't do a hybrid method (creating Roles in Ignition while doing Azure AD authentication). My guess is it's possible, but we decided not to do that. We figured internet is required for authentication, might as well just do the groups in Azure AD as well.
Thanks Everyone, I am able to setup most of it.
When i logon to gateway or designer it is going through IdP. but when i opened the project, it is not showing the configured security level for that IdP. I am not sure if anything else needs to be configured? or i am making mistake somewhere.
The main reason to do it as a module and not python code is distributability and being more able to lock down the code. Modules are far more difficult to modify than python code in the designer and something that affects the ability to login is something you want to be as secure as possible.
Nick