Thursday, January 15, 2009

An alternative to req:isUserInRole

For me, HttpServletRequest's getRemoteUser() and isUserInRole(role) have always felt like the right place to obtain user information in a web application. My experience with JASIG CAS filter and SecurityFilter has taught me that it is easy to create a servlet filter and drop in a request wrapper (HttpServletRequestWrapper) and create a method to set the remoteUser value. Couple this filter with something like Spring's DelegatingFilterProxy and it is easy obtain user details from some dependency injected external database.

Once the remoteUser value exists in the wrapped request you can acquire the details in a JSP page using JSTL e.g:


<c:out value="${pageContext.request.remoteUser}"/>

or with simple expression language alone (JSP 2.4+), e.g:


${pageContext.request.remoteUser}

The question is how to obtain the role information for a user. Jakarta's Request tag library enables you to make use of role information.


<req:isUserInRole role="admin">
<h1>Hello Admin User</h1>
</req:isUserInRole>

For some reason the request tag library is now deprecated. Of course you can still use it (and it is in the Maven repository) but there is something of a stigma associated with using deprecated code! So I have come up with an alternative. The issue is that it is not easy to invoke methods with parameter arguments from expression language. You cannot simply call:


${pageContext.request.isUserInRole('admin')}

Using expression language you can access scoped variables, arrays, lists and maps. Most of the time this data will be acquired and stored in some scope prior to loading the JSP page (such as in a typical MVC application). However, I have discovered that you can acquire runtime generated responses from a Map using Commons Collection's LazyMap and this technique can be used to effectively perform a user role lookup. I added the following method to my request wrapper (and made sure the request wrapper was publically accessible):


public Map getIsUserInRole() {
Transformer factory = new Transformer() {
public Object transform(Object mapKey) {
return isUserInRole((String) mapKey);
}
};
Map lazyMap = MapUtils.lazyMap(new HashMap(), factory);
return lazyMap;
}

and this means I can now access role information in a way that looks very much like a direct call to request.isUserInRole(role).


${pageContext.request.isUserInRole['admin']}

Using an idea that Matthew Sgarlata had for the request tag library it is even possible to include support for multiple role queries.


public Map getIsUserInRole() {
final String ROLE_DELIMITERS = ", \t\n\r\f";
Transformer factory = new Transformer() {

public Object transform(Object mapKey) {
StringTokenizer tokenizer = new StringTokenizer((String) mapKey, ROLE_DELIMITERS);
boolean result = false;
while (tokenizer.hasMoreTokens() && !result) {
if (isUserInRole(tokenizer.nextToken())) {
result = true;
}
}
return result;
}
};
Map lazyMap = MapUtils.lazyMap(new HashMap(), factory);
return lazyMap;
}
and the expression language becomes:

${pageContext.request.isUserInRole['admin,staff']}

and this can be easily negated:


${!pageContext.request.isUserInRole['admin,staff']}

Sample WAR with source code available (Assuming Java 1.5+ and Maven build "mvn compile war:war").

Update

As an update to this, I am now using the above technqie with what I call a ClearingLazyMap. This class implements the LazyMap interface but does not cache any values when they are fetched. This is necessary in order to pick up the most recent database updates, see also LazyMap that always calls transform, good idea?

11 comments:

madin said...

Buy a discounted replica watches uk IWC watch from this Time and get free shipping. replica iwc watches Large selection in stock. IWC watches, is an iconic brand. The IWC Portuguese, a collection that includes the IWC Portuguese automatic and IWC Yacht Club chronograph is legendary. IWC Schaffhausen is also known for the IWC Aquatimer, Top Gun, Big Pilot watch, Mark XVII, Pilot's Watch, Spitfire chronograph and their Big Pilot Watch, the St-Exupery.

madin said...

What makes Giuseppe Zanotti pumps, Giuseppe Zanotti sandals, replica giuseppe zanotti uk and Giuseppe Zanotti boots so unique is cheap man giuseppe zanotti espadrilles their consummate synthesis of design awareness and quality: "design awareness keeps you up to speed with the major trends that, season after season, dominate the worlds of ready-to-wear and haute couture; and it's also important for building up a repertory of ideas and images taken from music videos, from art, the cinema, from design, in short from everything which reflects changing fashions," explained Zanotti. "Technique and taste work in a reciprocal relationship, allowing all these ideas to come together."

madin said...

Ha sido un hito en la industria desde que Longines estableció su marca en Saint-Imier en 1832.relojes réplica Hoy, la marca ofrece una variedad de relojes para hombres y mujeres. longines relojes réplicaLos relojes Longines se han utilizado a lo largo de la historia, desde la aventura hasta la expresión elegante. Además de ser conocido por su conexión con el mundo de las carreras y la equitación, Longines también es conocido mundialmente por su refinamiento elegante y atemporal. Tenemos una variedad de relojes Longines a la venta, todos nuevos, hermosos y garantizados para ser auténticos. Aún mejor, cuando compra Longines en línea, sabe que está obteniendo el mayor valor. Explore nuestra lista de selección para encontrar los mejores precios de relojes en Longines en Internet.

madin said...

high quality replica cartier watches is a noted jewelry brand with luxurious elegance and technical innovation.replica calibre de cartier diver blue watches It has massive selection of product lines ranging from jewellery, bridal, accessories, leather goods to timepieces. In our leading online shop, we are particularly specialized in selling Swiss replica Cartier watches. There is no denying the fact that Cartier watches are within the dream list of many women. However, they come with astronomical prices which are far beyond the reach of many people. In consideration of this problem, we website provide the final products of Swiss replica Cartier watches, which are much more authentic than that of our competitors, and at a fraction of the cost of originals. Furthermore, we always take attention to details, high-end materials, fine watchmaking and advanced design.

madin said...

Best cheap Soccer Jerseys Shirts Wholesale Shop for Custom Team Soccer Jerseys Online,cheap walter gael sandoval Jerseys FCB Jerseys,cheap Euro 2020 Kit Top.

madin said...

Rolex watches are crafted from the finest raw materials and assembled with scrupulous attention to detail. cheap replica watchesEvery component is designed, replica rolex watchesdeveloped and produced in-house to the most exacting standards.

madin said...

nike air max scarpe Acquista scarpe Nike da uomo su replichenk.com. repliche air huarache Ottieni le ultime sneaker Nike da uomo in una gamma di colori e dimensioni. trovi un prezzo più basso su uomini e donne Nike.

madin said...

Synonymous with more than 80 years of impolite style, replica Ray-Ban Sunglasses picture frame crosses cultural boundaries and tells a true,replica Ray-Ban Sunglasses erika diverse, bold and dramatic story. Today, the story of Ray-Ban's authentic frame prescription glasses continues. This is a revolutionary new way to enjoy the clear vision of Ray-Ban's signature style.

madin said...

Use Alexander McQueen shoes to create a look from the feet.Cheap ALEXANDER MCQUEEN Shoes Wacky women's sneakers use jewellery replica mens ALEXANDER MCQUEEN embellishments and iconic skull motifs to instantly elevate any casual outfit to luxury, while glossy leather boots

madin said...

fake rolex watches are crafted from the finest raw materials and assembled with scrupulous attention to detail.fake rolex air king watches Every component is designed, developed and produced in-house to the most exacting standards.

heavy said...

Replica luxury handbags free shipping worldwide,the highest quality and lowest price,GUCCI LV DIOR CHANEL
PRADA website:kelly online shop

https://www.zhongximaoyi.com