javabeats
javabeats

Reputation: 1112

How to map additional LDAP attributes to the Principal object in Glassfish?

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

Answers (3)

Uux
Uux

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 Principals from generic ones in each application from now on :) .

Upvotes: 2

javabeats
javabeats

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

Mike Braun
Mike Braun

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

Related Questions