J2EE security: When to use the container versus custom security

Discussions

News: J2EE security: When to use the container versus custom security

  1. J2EE offers a standard security mechanism, we also have other standards such as JAAS. Every time you start a new J2EE project, you make a choice on how you want to handle security. This article goes through the choices, asks for some new features, and tries to help you decide what to do.

    Summary
    This article covers the factors to consider when choosing between custom security and J2EE standard security, also known as container security. It briefly covers how each type of security works and then illustrates their differences, strengths, and weaknesses. Although J2EE security itself applies to all components of an enterprise application, this discussion's main focus is Web application security or, more specifically, authentication.
    J2EE Improvements
    To make J2EE security more readily available and easier to implement, the J2EE specification needs a variety of changes. The most prominent of these being a standard interface that any application could implement to allow the container to authenticate credentials and assign user roles. As discussed above, each vendor has a different way of handling that functionality. (Recall that BEA requires application developers to write SSPI implementations and some XML). This standard interface could be as simple as a single authenticate method that takes a username and password and returns a Principal object. Or the interface could be expanded to provide much more than authentication. One possible layout for this interface might be:

    package javax.servlet.security;

    public interface SecurityContext {
        public Principal authenticate(String username, String password)
        throws ProviderException, InvalidCredentialsException, SecurityException;
    }
    Read J2EE security: Container versus custom

    Threaded Messages (23)

  2. Far from a toss up[ Go to top ]

    The author of the article comes to the conclusion that the decision between custom and J2EE security is a toss-up, depending on the complexity of the project. Strangely, he favors custom security for small projects, and J2EE security for large projects. I don't know that I could disagree more.

    The deployment profile of J2EE security is trivial. Most app servers come with at least a few standard adapters (LDAP, RDBMS, file-based). Snapping these in is usually a matter of clicking a few buttons in the admin console. Then, you may have to specify an additional deployment descriptor in your webapp. Those are the only pieces of the puzzle that smell of the "vendor lock-in" he hammers on. By that rationale, you might as well not use EJB, JCA, JMS, etc, because they all have vendor-specific deployment descriptors.

    I find J2EE Security to be one of the most underutilized, misunderstood, potentially useful pieces of the J2EE puzzle. It's written for you, and has been tested and proven. You don't have to rewrite it when you switch your security implementation, just change the connector. The role-management allows for both declarative and programmatic authorization security that integrates well with both the JSP/Servlet specs and EJB specs in a clear and simple way. Custom code isn't going to do this.

    In my opinion, J2EE Security is suitable for even the simplest of projects (as long as they still require security), and shouldn't be abandoned unless there is a compelling reason not to. It seems to be weak in the cases of 2+ factor authentication or if you want to have fine-grained permissions to the point that roles are not a good solution.
  3. Far from a toss up[ Go to top ]

    Yeah, I do not know why author has issues with J2EE authentication. It seems working pretty well and easy to use or customize. However in ‘big’ applications role-based “authorization” might not be sufficient, common example is a need to have ‘instance’ based authorization: user should be allowed to modify only own account(s).
    Is there somewhere list of “authorization” frameworks? Comparisons?
    How about role hierarchies?
    Some other hierarchical dependencies for authorization? Like this: a user has “admin’ role in a “Chicago” office and its departments, but does not in “NY” branch.
  4. Far from a toss up[ Go to top ]

    The quality of the J2EE implementation is also important. Does the J2EE server user realm handle thousands of users? If not you must use custom authentication.

    I expect container authorization to be more efficient than custom authorization so I would use both. First do a fast check for execution privileges using the container authorization and then the application specific verifications.
  5. Far from a toss up[ Go to top ]

    I expect container authorization to be more efficient than custom authorization so I would use both. First do a fast check for execution privileges using the container authorization and then the application specific verifications.
    J2EE spec defines role permissions in descriptors and does not define runtime access to modify those definitions, it means that we can define new role on the fly (in LDAP for instance) but cannot assign permissions to that role. IMO it makes container provided authorization unusable even in cases where role-based authorization would be sufficient.
    Same story on web tier, I can deploy new directories and jsp-s and html-s on the fly, but there is no (standard) way to say what roles have what permissions on those pages on the fly...
    So the need for custom authorization...
  6. Far from a toss up[ Go to top ]

    If you need to add roles to a running application then J2EE authorization is not good for you, the functionality is not there.

    Most of the time deployed applications are not modified on the fly so in this case
    is worth checking out the authorization solution provided by the J2EE server. After all you we are paying for it.
  7. J2EE authorization[ Go to top ]

    J2EE spec defines role permissions in descriptors and does not define runtime access to modify those definitions, it means that we can define new role on the fly (in LDAP for instance) but cannot assign permissions to that role. IMO it makes container provided authorization unusable even in cases where role-based authorization would be sufficient.
    Yes, you cannot assign permissions (which are described in deployment descriptor, and in general could be treated as map between business methods and roles) to role (in the datasource - database, LDAP, file, etc) on the fly. But you should not do it. At run time you have a freedom in managing associations between users and roles (in the datasource). And this is enough if you are not looking for instance based access control.
    What could be the reason for adding new role without new business method? I don't know.
    Assume, in the 'limit' case, you can have the set of roles equals to the set of business methods - with one to one relationship between roles and methods. After the deployment you don't need to change/add/remove roles at all. Manage users and their associations with roles at run time.
    I cannot understand why this approach is used very seldom.

    Alexander
  8. J2EE authorization[ Go to top ]

    And this is enough if you are not looking for instance based access control.
    What could be the reason for adding new role without new business method? I don't know.
    Looks like J2EE guys do not know too, however there is simple but not infrequent desire to define role with different set of “existing” permissions. Oversimplified Example: an application controls CRUDs on apples, oranges and cherries.
    - As a developer I might come up with AppleManager, OrangeManager and CherryManager roles with full access to the respective CRUDs;
    - But customer of the application might want to have AppleCherryCounter role with read only (R) access to the Apples and Cherries or something like that.
    But new ‘business’ methods could arrive as well: consider a new set of pages on a web site. They might need separate access rules…
    It looks like designers did not think enough about non-stop applications when parts of it could be deployed and un-deployed on the fly, so the security is ‘carved in stone’ and implies application stop-start cycle….
  9. J2EE authorization[ Go to top ]

    And this is enough if you are not looking for instance based access control.What could be the reason for adding new role without new business method? I don't know.
    Looks like J2EE guys do not know too, however there is simple but not infrequent desire to define role with different set of “existing” permissions. Oversimplified Example: an application controls CRUDs on apples, oranges and cherries. - As a developer I might come up with AppleManager, OrangeManager and CherryManager roles with full access to the respective CRUDs;- But customer of the application might want to have AppleCherryCounter role with read only (R) access to the Apples and Cherries or something like that.But new ‘business’ methods could arrive as well: consider a new set of pages on a web site. They might need separate access rules…
    In your example: suppose three different entity types and four operations => twelve business methods and twelve (in the 'limit' case) roles. Then, you have a principal-group-user model (following to composite pattern), where principal is an abstract parent for users and groups. Roles are associated with principals. You can compose group associated with roles with read access to Apples and Cherries (or something like that) at run time. Then you can create any number of users and add them to this group. Then you can modify group, add/remove associations, etc. All I wrote could be done without redeployment.
    Again, it is the 'limit' case. In real (perfect) world you begin the project from analyses and use cases, where the set of real necessary roles and their permissions on business operations are shown. You can make the set of roles little more granular and complicated to predict possible future extensions, but in any case the set of role will be limited and less then (or equal to) the set of business methods.
    It looks like designers did not think enough about non-stop applications when parts of it could be deployed and un-deployed on the fly, so the security is ‘carved in stone’ and implies application stop-start cycle…
    new pages on site usually means new business methods => new or old roles, some additional permissions, which will be described in the deployment descriptor. Independently from the deployment unit, you can work with roles, principals and their associations in the datasource, and this information will be used by container for authorization after deployment at run-time.

    Alexander
  10. Fair Article[ Go to top ]

    I think it's a reasonable article. Security is in my opinion one of the poorer areas of the J2EE spec, for some of the reasons outlined in the article. The fact that J2EE does not deal with authentication is really quite ridiculous and does mean having to resort to app server vendors' proprietary solutions.

    BEA did a reasonable job of extending J2EE in the areas it is weak - adding a role mapper for example. The identity assertion provider concept that they produced was less than stellar though! I think however that by WLS 9 they should have something that overall is very good.

    Making your J2EE app kerberized (including implementing SPNEGO) is an interesting exercise to understand the limitations of the J2EE security model and your app sever vendor's extensions.

    For example, in web.xml not being able to define your own auth-method can be problematical - you might have to resort to a variation on FORM auth in conjunction with servlet filters.

    JAAS is all very well but was never designed for distributed applications. The spec really needs to split the concept of LoginModule into client-side and server-side login modules.

    I think that the "J2EE improvements" section in the article is a bit naive. Any solution needs to deal with authentication that does not necessarily involve username/password combinations (e.g. certificates or encoded tokens) and works for both thick and thin client applications with as little duplication of code as possible.

    Robert
  11. Unimpressed[ Go to top ]

    I was unimpressed with the article really as i don't think it addressed some of the main problems with J2EE security and concequently some of the main problems of implementing a custom security method.

    I think the article was over simplified conclusions were incorrect,contradictory and undeterministic.

    <quote>Large enterprise applications should consider using container security for a variety of reasons</quote>

    is contradicted in the next paragraph with

    <quote>Some large-scale applications may not need the strength of container security</quote>

    Here are some of my points

    * surely we can assert that security should be declarative where possible and hopefully programmatic where necessary through an interception methodology. To implement a custom declarative authorisation for both web applications and business service requests (EJB) would be far more work than is made out in the article, so you would be forced into writing in programtic security into your code which will be no guarretee of constistancy and less maintainability. Effectively you will have to replicate the web.xml etc security-constraints..

    * Use of JAAS in J2EE security is much more powerful than is made out in the article. Again JAAS allows a PAM (Plugable Authentication Module) based approach to authentication and identity management (establishing the principals of an ide ntity) which gives a declarative based approach to security

    * <quote>Another consideration is vendor lock-in. Using container security essentially locks the application into that container until the interfaces required by other containers can be implemented to support container authentication.<quote> Why do people always believe that bespoke code=no lock-in. Its just as easy to get locked into your own frameworks as it is to a vendor (although in this case we are talking a pretty standardised framework). In three years time when all the original developers have left and new guys are left to having to deal with a custom (probably organically expanding) security model they get caught in a learning curve (when probably they know something about container security) and a quality/security-risk issue using it. There are certainly people who have implemented a custom security model (which they raved about at the time) and come back a couple years later and seriously regretted what they did - Not mentioning any names but you know who you are -

    * I agree with Robert that the J2EE security improvements section is naive. The suggestion interface would provide no support for other credentials such as X509 certs, encoded tokens (liberty alliance anyone), kerberos tickets etc.. which JAAS based container security will handle just fine. Not to mention implementation of WS-Security authentications for XML (Its a whole new world) all of which can be comfortably handled by container security.

    So my own 2 british pennies on improvements..

    * Right there with you Robert, when you start having to apply web security for different types of credentials (tokens, tickets, multi-phase) the auth method becomes your first bug bear. The web application security model is a pain restricting you to the basic BASIC, FORM, CERT, DIGEST which can not be customised (Custom error handling/message display anyone?? or maybe trying to post to j_security_check from a page without first accessing a security-constraint page..) You need to be able to define your own custom AUTH methods which effectively deal with interfacing between your "web" world (requests, GETs POSTs, the session) and the JAAS PAMs. This should also be configurable from the web.xml in a custom way beyond just <form-login-config>.

    BTW Robert in tomcat (and Jboss-tomcat) you can define your own auth-methods by writing an Authenticator class that extends org.apache.catalina.authenticator.AuthenticatorBase and jar it with a org.apache.catalina.startup.Authenticators.properties
    such as
    BASIC=org.apache.catalina.authenticator.BasicAuthenticator
    CLIENT-CERT=org.apache.catalina.authenticator.SSLAuthenticator
    DIGEST=org.apache.catalina.authenticator.DigestAuthenticator
    LIBERTY_SSO=com.codebitches.security.catalina.authenticator.LibertySSOAuthenticator
    DIRECTFORM=com.codebitches.security.catalina.authenticator.DirectFormAuthenticator
    FORM=org.apache.catalina.authenticator.FormAuthenticator
    NONE=org.apache.catalina.authenticator.NonLoginAuthenticator
    Add it to the classpath and presto new auth-methods to use in web.xml
    BUT people tell me you can't do this with weblogic

    * The biggest problem with J2EE security is the map between the JAAS model (Subject-*Principal-*Credential) and the J2EE model (Principal-*Role)
    Why not just use the JAAS model straight off for authorisations

    Id suggest a declarative interface for security that used the JAAS model and a JSTL EL type syntax. How good would this be...

       <security-constraint>
        <web-resource-collection>
          <web-resource-name>Secure Content</web-resource-name>
          <url-pattern>/jsp/restricted/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
          <jaas-constraint>subject.publicCredentials.x509 && ((subject.principal.adminRole && subject.principal.UkLocation) || subject.principal.superAdminRole) </jaas-constraint>
        </auth-constraint>
        <user-data-constraint>
          <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
      </security-constraint>

    Which restricts access to only users who have authenticated with a certificate and either have the adminRole identity and uk location or have the superAdmin role identity.

    Stuart
  12. Unimpressed[ Go to top ]

    I agree that JAAS does make sense but it isn't a complete solution. It is certainly good for web applications but you need to consider how thick clients will use it. For example, the whole CallbackHandler isn't going to work unless that becomes a remote object. And don't forget CORBA clients.

    I'm not trying to defend the author of the article but I think that he meant with his comments on vendor lock-in that if you develop custom providers (e.g. implement SSPIs in WLS) then you have to re-implement that when you want to move container (e.g. create the appropriate Realms in Tomcat). Also some containers give you nice features like Role Mappers (WLS) but these don't necessarily exist in Tomcat. If these were standardised then portability would be easier (not that portability is actually a number one priority for most large enterprises).

    I am interested in the Tomcat Authenticators.properties. You are right that WLS does not provide such a feature and it is very annoying. You can work around it in WLS if you scratch your head for long enough but it is an obvious omission.

    Your JAAS credential approach looks like a good idea but I believe a key requirement is that Roles (or credentials in your case) are evaluated dynamically (e.g. when you call isCallerInRole or when the container evaluates it for you). This handles the cases where roles change while a user is logged in and also allows roles to vary e.g. based on time of day (a given user can do something between only 9am and 5pm for example).

    With WLS you can populate credentials in the Principal as you see fit during authentication and roles can provide a dynamic capability. It is just a pity as you say that credentials cannot be used in the declarative security constraints.

    Robert
  13. Unimpressed[ Go to top ]

    The difference between principals and credentials is that principals are used to indicate identity ("this is who i am, and the things that describe me) while credentials are used to assert identity ("and this is how i prove it"). Generally "Roles" are something that describes identity to the system and are in fact just principals (describes of an identity). So when we think of roles they are just a form of principal that makes sense to the system.

    I just think it would be great to form declarative security that could incorporate some basic logic on credentials (these resources should only be available to people that have given sufficient prove of identity and/or have this identity)

    The callbackhandler can work for JAAS in some of the most extreme circumstances and can set up remote syncronous calls to other objects. But in most cases it is necessary to form client side login and server side login where some form of credential handshake needs to take place. Of course your right and JAAS wont handle this itself and you need to have some form of interception which understands the underlying protocall.

    On vendor lock-in, in general login modules can be implemented in a standard JAAS fashion and ported. Both Tomcat(can) and JBoss(must) use JAAS authentication rather than realms. Of course the main difference in this case between WLS and JBoss is that WLS can dynamically (and some declaratively) map principals->roles while JBoss relies on statically (and programmatically) mapping principals->roles at LoginModule.commit() time. This is a real good nice-to-have feature, and would love to see it in the spec.

    As with all vendor "value-add" features, using them restricts portability sure but adds value without coding effort. It really depends on your architectural values as to whether vendor-portability has a lot of value attached to it, and i think this only really matters for product vendors rather than enterprises.

    Really love to hear about your workaround in WLS for auth-method.
  14. hi guys,
    yous should have a look at the jGuard library (http://sourceforge.net/projects/jguard) to enable JAAS in a J2EE environment, in a suitable way.

    have fun,

    charles.
  15. Ticket Granting Ticket[ Go to top ]

    Hey, about the kerberos tickets - is the security only works in Windows Server '03? And what about Red Hat Enterprise Linux? I wish to check it over an Euroleague tickets system from a site hosted in Israel. TGT should work well? any J2EE problems known in this issues?
  16. IMHO JAAS and J2EE Security is *mostly* suitable for simple project and *barely* suitable for large projects.

    There are few important issues that are not handled correctly or at all.
    For example:

    1. Many application are required to handle more than just two user credentials for authentications (username and password). For example, National regulations forces banks to require username, personal-id and password. Another example is when users can enter different identifiers and tell the application what type of identifier did they pass (for example: phone-number and userid as alternate ids).

    Does someone know how to fulfill these requirements with J2EE form/basic authentication ?

    2. Instance based authentication: Beside some restrictions to admin jsp pages i cant think of *many* other uses for J2EE role based authentication. Most application require instance based authentication. For-Example: can a teller in a banking application use a component to read data related to a vip account?
    What happens is that some developers use role-based authentication to apply instance based security and the outcome is horrible.

    3. Logout functionality is not well defined by the spec and usually purely implemented in most J2EE containers.

    4. Access to user security context is handed differently by different cotainers. Some offer more information and some offer less.

    5. Handling of different type of login failures in form-based authentication is very hard and limited. Can you easily tell a user that he is not authneticated because his password is wrong and in different situation tell him he is not authneticated because his account is revoked?

    Generally, a good spec that defines authentication/authorization/auditing/account-management would be awsome
    JAAS and J2EE Security are still not there, i wonder how .NET is addressing these issues.

    y.
  17. 1. Yep this is often the case, and your problem is not with the J2EE specification or JAAS more with the servlet specification and the interface from "web" to the container security. To solve this you need to write a custom authenticator (see previous post for Tomcat/JBoss details) that handles the POST of credentials and forces the credentials to JAAS/Container Security Manager. JBoss for instance allows you to set an Object Credential (which can hold all your credentials which can then get picked up by your LoginModule)

    2. This is definately an instance where programmatic security should be used "does user x have the ability to update entity y" and should be enforced at an architecture level

    3. I so agree. An in J2EE -> JAAS is often hard to distinguish the difference between logging a user out of the web app (no longer persisting their session) and logging the principals out of the JAAS login context on the current thread. (A subject should login in to the JAAS login context at the beginning of a HTTPRequest and logout of the JAAS login context at the end.

    4. Yeah damn vendors..... At least in some cases you can read the code...

    5. This is right and forces you to implement your own Authenticator nearly every time you want to do something very different. The servlet spec just doesnt give the flexability in auth-method. Another trick is forcing a "pre-auth" to your authentication forcing the user to go through -for instance- your struts action to do an authentication and if successfull setting the username, credentials in the session before forwarding to a custom autenticator which takes out these credentials and uses them on a container authentication. This will work in all cases and allow all kinds of custom checks to be done in the pre-auth
  18. 1. Many application are required to handle more than just two user credentials for authentications (username and password). For example, National regulations forces banks to require username, personal-id and password. Another example is when users can enter different identifiers and tell the application what type of identifier did they pass (for example: phone-number and userid as alternate ids).

    Does someone know how to fulfill these requirements with J2EE form/basic authentication ?
    Easy enough with a form-based login. All you need is some javascript that collates together all the values from your various fields, and writes the combined string into j_password prior to calling submit() on the j_security_check form. Then use a custom JAAS login module that separates them back out again into the separate strings and checks each of them as appropriate.
  19. The question shouldn't be when to use which technology, but how to get to a consitent technology to use. Obviously both approaches have their advantages that applications could benefit from.

    As one of the previous posts mentions, J2EE security is quite static in that it doesn't allow to dynamically add roles or remove users from roles. JAAS in contrast is close to rocket science and may go beyond the skill set of the common application developer. Best is to have a framewrok that does JAAS but shows a nicer user interface to the application developers. Security is too important to leave room for discussion.

    Using container based authorization with JAAS and mapping this e.g. to J2EE's isUserInRole allows much more flexibility by good usability. As I can tell, there are more libraries on the market that use J2EE security than libraries using JAAS, e.g. see the Struts taglibraries. I think that we will see JAAS becoming the security implementation on the container side, while what we currently know as J2EE security will be used in applications. In the end you use both and don't care how big the project will be.

    Frank
  20. With JBoss you can implement custom security at the servlet level using a filter and/or at the EJB level with an interceptor. Filters are required by the servlet spec, and most vendors have interceptor implementations for EJB land.

    Even if you have custom security requirements it is quite useful to hook into J2EE's mechanism for propagating a security context. For instance, we've wrapped our connection pooling as a JCA resource so you can propagate your J2EE web logic username all the way to the database for end-to-end security.

    Bill
  21. I just wanted to react on some imprecisions.
    <quote> Credential authentication ... For example, BEA's WebLogic 8.1 requires developers to first implement special SSPI interfaces</quote>


    It's not totally true. WLS provides also some default LDAP and X509 certificates authentication modules that can be configured through WLS administration console. These modules accept the JAAS authentication flags and allow to create authentication chains. However, it's true that for WLS 8.1 there's no RDBMS authentication module and you need to develop your own one.
    Also, WLS offers the possibility to dynamically override the declarative authorizations set in the deployment descriptors of your application by declaring resources policies.
  22. Some applications maintain a list of its users, with username and password. In this cases the application wants to perform authentication. The problem here is that there is no standard way to do it so that the Principal you create becomes the Principal also for your j2ee container, if you still want to use j2ee authorization mechanism. There is a "JSR 196: JavaTM Authentication Service Provider Interface for Containers", but it does not seem it's making progress. Usually appservers have a custom mechanism to plug you authentication in, often by writing a JAAS module, as in JBoss. But then you may face bitter surprises. For example in Websphere the authentication mechanism is appserver wide (even cluser wide, if you use clusters), so you cannot have one specific to you application.
  23. JSR improvements[ Go to top ]

    I wouldnt want to be using Websphere then.......

    Interestingly JSR 115 Java Authorisation Contract for Containers should go some way in to provding "dynamic" permissions and roles for authorisation constraints. But it will depend how vendors implement it as to how declarative it is.

    JSR 196 looks really interesting as it goes towards solving the problems with binding the transport mechanisms of credential passing to authentication modules ("for instance FORM logons")

    Hopefully both these JSRs will improve J2EE security immensely.

    Stuart
  24. JSR improvements[ Go to top ]

    jsr115 is shipping with j2ee 1.4 I think, the other instead (which is more useful in my opinion) will ship with j2ee 1.5, that it in two years, at best.