• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Junilu Lacar
  • Tim Cooke
Saloon Keepers:
  • Carey Brown
  • Stephan van Hulst
  • Tim Holloway
  • Peter Rooke
  • Himai Minh
Bartenders:
  • Piet Souris
  • Mikalai Zaikin

Hooking realm name defined in <login-config> to <Realm/>

 
Ranch Hand
Posts: 66
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Ranch members,

I am migrating configurations from JBoss to Tomcat 8.5. I would like anybody accessing the app to be authenticated through LDAP via BASIC authentication. Unlike in Jboss 6.x, in Tomcat 8.5 I don't see the Realm name attribute available which can be then referred in the login-config of the app's web.xml instructing the container to use the specified Realm for authentication. In the below example, I have supplied a Realm name in the <login-config> to use which is "MySecurityRealm" as seen in the web.xml, however I don't see a way to map that name to <Realm/> as the name attribute is not supported. In this instance, how to instruct the login module to use the JNDI Realm for authentication? Any inputs is much appreciated.

Here is the link to apache configuration reference for 8.5 - http://tomcat.apache.org/tomcat-8.5-doc/config/realm.html#JNDI_Directory_Realm_-_org.apache.catalina.realm.JNDIRealm

In the web app's context.xml I have the Realm defined as below.



In the web app's web.xml, I have the following security configuration.




Many thanks
Arun
 
Saloon Keeper
Posts: 26894
192
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In JEE, you do not hard-code the security Realm in the webapp. It is applied externally and is plug-replaceable.

The realm-name element in your web.xml file is actually what displays in the title bar of the client's Basic Authentication pop-up dialog, I think.

I recommend defining the Realm itself in an external Context definition file (in conf/Catalina/localhost/) . You have 3 different location options. server.xml, which should only be done if you want multiple webapps under the same Realm, Context xml files, which is my preference, and the webapp's META-INF/context.xml file. If my memory is correct, the Catalina/localhost Context overrides the other two.

Mostly I only use context.xml to define test configurations. For one thing, I don't believe in putting sensitive production information (such as userids and passwprds) into source code.
 
Arun Somasundaram
Ranch Hand
Posts: 66
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for your response, Tim. Yes, I am just testing the migrations in a lower environment. Sorry, I have not been more clear about the setup structure.

As you could see from my post that I have defined a JNDIRealm in context.xml. That context.xml has been placed in CATALINA_BASE/webapps/myapp/META-INF as I expect only "myapp" to use LDAP authentication.

The web.xml as seen in my post above is placed in CATALINA_BASE/webapps/myapp/WEB-INF.

My query is how does the login-config in web.xml would know it has to use the JNDI Realm for authentication if there is no scope to define a name for <Realm/> defined in META-INF/context.xml? I interpret from your reply, since the auth-method in login-config of web.xml is set to BASIC, the container would automatically pick up the JNDI Realm defined in META-INF/context.xml?
 
Tim Holloway
Saloon Keeper
Posts: 26894
192
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It doesn't.

JEE uses container-managed authentication and authorization. That is, the Realm is part of the webapp server (Tomcat, in this case), and not part of the webapp.

When you deploy a web application to a JEE container, there are two deployment descriptors that describe the deployed webapp. The container-independent deployment descriptor is the /WEB-INF/web.xml resource in the webapp's WAR.

The container-dependent deployment descriptor is entirely defined both in source and in format by the webapp container. It may or may not be an XML file. It may or may not even be a file at all. All that is required is that there be a way of injecting container-specific information into the deployment process. That can include JNDI definitions (env-entry's), Database Connection Pools, Security Realms, and other stuff.

For Tomcat, that information is a tree of information commonly packaged under a Context element, which may be in the Tomcat config file, a separate deployment descriptor file under conf/Catalina/localhost (my preferred way) or in the WAR's META-INF/context.xml file. Other webapp servers use other filenames, locations and formats, but they're not important here.

There can be only one Realm controlling login and privilege checking per webapp, so the one that the webapp is deployed under is going to be the one that gets used It is the container that makes the decision, not the webapp. The web.xml file doesn't need to match to anything. All it can do is say "BASIC" or "form-based" login and what roles and rules apply for user security screening.

The Realm is a plug-replaceable module. It has only a limited and rigidly-defined set of external functions. It can accept credentials from the login mechanism (which is part of the container - container-managed security does not implement its own login code) and return a pass/fail indication. It can construct a java.security.Principal object, which is an interface anchoring whatever internal Realm housekeeping elements there may be and is accessible via the HttpServletRequest getUserPrinicpal() method for a logged-in user. It can see if the user is allowed to operate in a certain security Role. And that's about it. That means that you can use LDAP in production for the exact same WAR that you tested using a MemoryRealm.
 
Arun Somasundaram
Ranch Hand
Posts: 66
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Cheers Tim, nice explanation. Just wanted to confirm the setup I shared works. There was a configuration mistake with one of the <Realm> attributes which prevented successful LDAP authentication.

The corrected Realm looks like this. I have removed the userPattern and replaced it with userBase and userSearch. In the original config I have mixed userPattern and userSubtree which doesn't go together as per the tomcat config spec. It's either userPattern or userBase, userSearch and userSubtree to locate a user based on DN in directory server.


I have a follow up question, if it is ok to continue that in this thread. The use case is to use LDAP only for authentication, once authenticated I would like to apply a role only to a certain subset of authenticated users i.e. something of the sort that roles will be locally maintained in tomcat in a file. I suppose the tomcat-users.xml is not effective here as the authentication happens through JNDIRealm and not through the MemoryRealm. Happy to create a new post if the policy does not allow to continue this discussion in this thread.
 
Tim Holloway
Saloon Keeper
Posts: 26894
192
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Users and Roles relate in a many-to-many correspondence. I, for example, can simultaneously hold an "administrator" role, an "auditor role", an "app-user"  and a "manager" role. Or no roles at all.

Like the user ID/'password, the LDAP server also stores the roles for each userid. If memory serves, there are at least 2 different ways to relate roles and users in LDAP for Tomcat, which should be illustrated in the Tomcat documentation.

Changes to roles (and for that matter user IDs) are not instantaneous. When a user logs in, that user id is their user ID for the life of the logged-in session, and the roles assigned at login time apply all through the session even if the underlying (LDAP) database changes. This prevents unpredictable security issues that could arise when you're between different role settings.
 
reply
    Bookmark Topic Watch Topic
  • New Topic