Greetings, Background: I have been assigned the task of evaluating the suitability of WSO2 Identity Server for use by some existing products, as a replacement for our own custom security back-ends. The motivation for this effort has been parallel development of two pieces of new software by different teams which each chose a different security route – one has already been built on WSO2 but is using only the built-in stores and has only a simple user model – users either have admin privilege or they do not. This product is at the demo stage but not yet available to customers. The other, slightly older software chose to fork an existing security back-end that I originally wrote for an even older, legacy product. This particular product is currently deployed with customers and needs very fine-grained security, since it controls access to scarce and sensitive test devices.
These two teams now have to merge their products onto a common platform within about the next six months, and are debating which route to go for security – Team A worries WSO2 doesn’t fit their needs based on seeing only the limited security granularity in the demo product from Team B, and Team B claims WSO2 will meet all of Team A’s needs if configured properly. The manager over both of those teams requested my help in researching the decision – I have no personal involvement with either project. That manager wanted me to weigh in simply because I’ve a long history of either building or fixing the security implementations behind several different products spanning many technologies. My direct manager agreed to loan me for this evaluation, but set me a strict limit of 12 hours effort. I've reached that limit. I do, however, have someone else I can hand further work and investigation off to if I have learned enough. Problem: I have downloaded WSO2 Identity Server 5.4.1 and configured it to use ReadOnlyLDAPUserStoreManager, pointing this at an OpenLDAP server I have configured to model the LDAP repository of one of our most important customers. I maintain a user store to model each of our major customers that don’t just use our own, built-in proprietary user store. The WSO2 configuration was quite easy and “mostly” works, except I am not able to enumerate groups. I’ve tracked this down to an idiosyncrasy of this customer’s LDAP data combined with what I consider to be a bug in the WSO2 ReadOnlyLDAPUserStoreManager implementation. This customer assigns two common name values to each of their LDAP groups – one of these is unique within the search base, but the other is not. They’re essentially “tagging” groups as being one of two classes – either admins or plain users. This must be done for some other vendor’s application – none of ours look at these at all. So, for example, a group might have both CN=northeast-managers *and* CN=category-sysadmin, where “northeast-managers” is unique and CN=northeast-managers is part of the DN for the group. Our own existing LDAP back-end honors a setting very similar to WSO2’s GroupDNPattern. If present, when enumerating the list of attribute values returned for the naming attribute (equivalent to WSO2’s GroupNameAttribute), we substitute the group name value into the pattern(s) and throw out any that don’t result in a match for the DN of the group. In this way, we pick the “correct” CN value, since LDAP returns these things in some sort of random order. WSO2-IS doesn’t do this, though it appears to employ a similar technique in other places. Thus, I consider this a bug/oversight. Consider the following code: https://github.com/wso2/carbon-kernel/blob/4.4.x/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/ldap/ReadOnlyLDAPUserStoreManager.java#L1401 On that line of code, WSO2-IS is fetching only a *single* attribute value for the “roleNameProperty”, when there may be multiple. In the customer's existing LDAP, more often than not, their category- groups are being returned as this single value, instead of the one that actually is unique and matches the DN. I believe that WSO2 should be calling .getAll() here rather than .get(), and then should iterate over these attribute values. For each value, it should attempt to substitute that potential role name into the GroupDNPattern(s) (if the property has been defined) and then ensure that the result matches the DN of the SearchResult, (sr). When a match is found, add the role name, but otherwise, discard it. I’m basically out of time for my evaluation at this point. I’d like to go ahead and recommend WSO2 – I have no particular affinity for our own proprietary security code (even though I wrote this particular part of it) and think that an actively-maintained code base is likely to be the safer bet in the long run. However, this particular issue would stymie deployment at the very first customer it would go into – and we’re in no position to demand that they simplify their LDAP schema in order to satisfy our application. I’ve attached a PNG screenshot taken from Apache Directory Studio showing a sample problem entry. In WSO2, this “sample-admin-role” group is showing up as “category-sysadmin”, along with every other role that is tagged the same way. Trying to interact with these in the WSO2-IS management dashboard results in errors about duplicate group names. What I’m Looking For: I do have a resource available for a few days that I can hand some work off to. I’d like to assign him the task of fixing this bug – but need to give him pretty good instructions. I find the number of repositories and branches related to WSO2 on GitHub to be a bit overwhelming to understand in just a few hours. I’d like to be able to point him to the proper repository and branch to fork and work on, and to instructions on how to build, deploy, and test the changes. I’m particularly confused that the current release is 5.4.x, but that I can only find the LDAP code beneath 4.4.x branches. Also, in the possible event that upstream might not agree that this really is a bug, I’d like to know if there is a general approach to adding custom user store managers into WSO2? If this works out well, down the road it might be possible for us to integrate other backends – the WSO2 APIs are already remarkably similar to our proprietary implementation from years ago, and we have some esoteric backends for things such as RADIUS/TACACS+ from specific deployments over the years. Thanks in advance for any pointers. Best Regards, --Robert
_______________________________________________ Dev mailing list [email protected] http://wso2.org/cgi-bin/mailman/listinfo/dev
