Hi Chris, On 2025/05/28 14:23:56 Christopher Schultz wrote: > Michael, > > On 5/26/25 9:14 AM, Michael Osipov wrote: > > Hi folks, > > > > I seek guidance on a larger problem I need to solve where I do have a few > > ideas, > > but am also considering to what degree it would make sense to add code to > > the > > Tomcat codebase for the common good: > > > > I have a realm impl called MyRealm which sources from "store A", is has > > roles > > (groups) in a specific format and user attributes. It returns MyPrincipal. > > Consider you have a webapp which has logical roles "user", "editor", > > "admin", > > etc. and also uses those specific attributes. The webapp context maps the > > roles from "store A" into the logical roles with the > > PropertiesRoleMappingListener. > > > > Now an additional MyRealm with "store B" comes into play. Of course, the > > CombinedRealm works perfectly, but "store B" has different role names and > > different attribute names. > > > > The problem: Both "String Context#findRoleMapping(String)" and > > "#addRoleMapping(String, String)" do not support 1:n mapping, e.g., > > "user" role maps to "store_a_role_1" and "store_b_role_5". > > This would require changing/extending the interface and other classes. > > The other problem is, of course, realm-specific. Say "store A" has attribute > > "gid" which is semantically identically identical "store B" attribute > > "employeeID". From an application PoV this is a consolidation nightmare > > to touch every single spot to accommodate that. > > > > My idea is going from: > > > > <CombinedRealm> > > <MyRealm source="store A" /> > > <MyRealm source="store B" /> > > </CombinedRealm> > > > > to > > > > <TransformingRealm roleMapper=... attributeMapper=...> > > <CombinedRealm> > > <MyRealm source="store A" /> > > <MyRealm source="store B" /> > > </CombinedRealm> > > </TransformingRealm> > > > > While the attributeMapper cannot be part of Tomcat because it is > > realm-specific, > > do you see a benefit of modifying Context to accommodating 1:n mappings and > > of > > course the aftermath? > > Let me know your opinion whether this is of good use for the Tomcat code > > base. > > > > For the same of completeness, I cannot add "user1", etc. to the application > > because it will require some hefty code changes as well. > > I must admit I've never used the role-mapping capabilities of the > servlet context before; I've only written applications that use the > one-and-only-one set of roles exposed by my user database. So perhaps my > comments come from a position of ignorance to your particular situation. > > It seems to me that this can be entirely fixed by using a custom > Principal object: one that is already under the control of the Realm. > > public class MyRealm extends RealmBase { > public Principal authenticate(...) { > ... > return new CustomPrincipal(...); > } > > public boolean isInRole(Wrapper wrapper, Principal principal, String > role) { > if(principal instanceof CustomPrincipal > && ((CustomPrincipal)principal).isMine(this) { > return super.isInRole(reverseMapRole(role)); > } else { > // Principal is not from this Realm > > return false; > } > } > > protected String reverseMapRole(String role) { > if("user".equals(role)) { > // Obviously, implement this as a configurable Map > return "CN=users,OU=groups,DC=example,DC=org"; > } else { > return role; > } > > public class CustomPrincipal extends GenericPrincipal { > private boolean isMine(MyRealm realm) { > return realm == MyRealm.this; > } > ... > } > } > > You can use the same class MyRealm for both of your Realms, each with a > different configuration. Since Tomcat already supports any attribute you > want to configure, just do something like: > > <Realm class="com.example.authn.MyRealm" > roleMappings="user=CN=users,OU=groups,DC=example,DC=org; > editor=CN=editors,OU=groups,DC=example,DC=org"; and so on" /> > > Would what I have above work for you? It doesn't work for an application > that tries to manually perform reverse-role-mapping (because the Context > doesn't know about these mappings), but without changes to Jakarta EE > APIs, the application will /never/ be able to do this.
Thanks for your input. I have actually ended up doing the following: > <Realm > className="com.innomotics.dynamowerk.tomcat.realm.PrincipalTransformingRealm"> > <Realm className="net.sf.michaelo.tomcat.realm.ActiveDirectoryRealm" > connectionPoolSize="5" > dirContextSourceName="gc/ad001.siemens.net" > additionalAttributes="displayName,siemens-gid" /> > <Realm className="net.sf.michaelo.tomcat.realm.ActiveDirectoryRealm" > connectionPoolSize="5" > dirContextSourceName="gc/innomotics.net" > additionalAttributes="displayName,extensionAttribute6" /> > </Realm> and the realm is: https://gist.github.com/michael-o/39dff88679427badf2e617bf2285b437 I will look later into Tomcat code whether the one-to-many mapping can be added. The benefit is that if you have many groups for the same role they can be managed by individual groups from different departments in a central portal. All you need is to add them one to your application and the rest is self-service. The app will treat both equally. Michael --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org