Reputation: 1112
I have configured a LDAP realm in Glassfish, and authentication works just fine.
Now I am wondering how could I match the Principal.getName() return to a certain attribute of my LDAP user object. I thought it would use something such as "givenName" by default, but it returns the username used for authentication.
I don't mind making an extra trip to the LDAP server to obtain the additional information, but instead of keeping the LDAP connection attributes in my application, I'd like to inject the security realm (if such a thing is possible) and use its own connection.
So, in short, the questions are:
1) Can I map additional attributes to the Principal returned by the realm?
2) If number one is not possible, then how could I reuse the realm's information in order to connect to the LDAP server and obtain the data I need?
Thanks in advance for any help or suggestions.
Upvotes: 4
Views: 1643
Reputation: 1218
Edited: I was under the impression that the following used to work, at least with GlassFish 4.0. Unfortunately, that doesn't (any longer) seem to be the case. A workaround can be found in the comments of this issue.
Not really a solution per se; just a little detail I kept overlooking for a while, and which was quite a relief for me to have now become aware of. So --skipping the boring specifics-- I realized that a CallerPrincipalCallback(Subject s, Principal p)
constructor is additionally available, which, when supplied with my custom Principal
, causes the server to actually retain it, instead of wrapping it in or transforming it into an internal GlassFish implementation instance, as I previously thought it would. From "userspace" I was then able to access my "enriched" (more Subject
- than Principal
-like, to be honest) version the usual way (e.g. ExternalContext#getUserPrincipal
, etc.), cast it and enjoy the convenience of not having to care about deriving custom Principal
s from generic ones in each application from now on :) .
Upvotes: 2
Reputation: 1112
Well, I could not extend the Principal attribute mapping without using a custom LoginModule; so, instead I opted to the solution described here: http://docs.oracle.com/cd/E19798-01/821-1751/abllk/index.html
What I do is, upon authentication, use the injected LDAP context to go back to the LDAP server and obtain the attributes I want. The downsides are obvious: two trips to the server instead of a single one, and the extra code to probe attributes and tie them to the Principal (or another POJO) in some way.
Upvotes: 1
Reputation: 3769
The JAAS Subject often contains many principals, each one representing a different attribute.
For Java EE one, and only one, of these Principals is selected for the one that is returned when you call HttpServletRequest#getUserPrincipal and similar methods. The other Principals are for the Java EE API just lost.
You can determine which of those Principals to select by writing a JASPIC authentication module if the login happens via HTTP or SOAP.
You can preserve the entire Subject by putting it into the HTTP session from within the JASPIC authentication module. Other code can pick it up from there.
Upvotes: 2