A Dojo Confirmation Dialog

By Chris L Hardin
Sr. Software Architect

One of the things that is going to included in an upcoming release of the Dojo framework is a popup confirmation dialog like you have in Javascript. This should have already been included in the framework, but we won’t get into that… Until this functionality is actually released, I decided to write my own confirmation dialog since I had a realtime need to have one and the version that is going to be included in the future Dojo release is not at a stage of completion that allowed me to use it.

In a lot of ways, the answer I came up with was really clean. Here is the method.

doj.require("dijit.Dialog");
doj.require("dijit.form.Button");

function confirmDialog(title, question, callbackFn, e) {

var errorDialog = new dij.Dialog({ id: 'queryDialog', title: title });

var callback = function(mouseEvent) {

errorDialog.hide();
errorDialog.destroyRecursive();

if (window.event) e = window.event;

var srcEl = mouseEvent.srcElement? mouseEvent.srcElement : mouseEvent.target; //IE or Firefox

if (srcEl.id == 'yes') {
callbackFn(true, e);
} else {
callbackFn(false, e);
}
};
var questionDiv = dojo.create('div', { innerHTML: question });
var yesButton = new dij.form.Button(
{ label: 'Yes', id: 'yes', onClick: callback });
var noButton = new dij.form.Button(
{ label: 'No', id: 'no', onClick: callback });

errorDialog.containerNode.appendChild(questionDiv);
errorDialog.containerNode.appendChild(yesButton.domNode);
errorDialog.containerNode.appendChild(noButton.domNode);
errorDialog.show();
}

//utilize the method like this
dialogConfirm("Confirm Change", "Are you sure you want to change?", cancelConfirmCallback, e);

This is pretty straight forward and it works great for those annoying Vista-like popups like, “Are you sure you want to do this?” or “Are you really sure you want to do this?” and everyone’s favorite, “Are you real, really, cross your heart and hope to die, sure that you want to do this?”

IT Interviewer Tips – Getting a better candidate and keeping them

By Chris L Hardin
Sr. Software Architect

I’ve had quite a few job interviews in the past month, some were really good and some were really bad, but I as I talked to some of these folks, one thing became abundantly clear, the interviewer rarely considered that the candidate was also interviewing them.

For the most part, interviewers are courteous with a few exceptions, but they all hit you from the standpoint of, “You should bend over backward because it is a privilege to work for us.” I spend just as much effort in trying to ascertain whether or not I want the job as trying to actually get it.

Here is a good example, I interviewed with a company in Nashville for a Senior Development position and they initial interview was pretty hostile, the interviewer almost seemed frustrated that I continued to ask questions. He came off and haughty and rude, thus really turning me off to the job. Would you be interested in a job in that kind of environment?

Another interview with a company in Nashville started with an initial call where I had got off work early to take it and the guy was 15 minutes late calling me and had to get to another interview 15 minutes later. He requested that I talk to him again the next day at the same time and he was 15 minutes late again and then put me on hold while he talked to someone in his office for 15 minutes. Also, he pretty much had the personality of a wet sponge, which made the interview like pulling teeth. Why would I want to take a job at a company when my time is apparently not as important as his?

Another interview I had with Amazon was really interesting. I spent an hour on the phone with the guy. He appeared to just be going through the motions of the technical interview. I could hear it in his voice. He had probably talked to 20 or more people that day and I was just another number he had to dial. I was excited about interviewing with Amazon, too bad he wasn’t as interested in talking to me. I did Perl years ago and he asked me a question about how to match a fragment in a string. I answered from what I could remember and he disagreed. I said I thought that I was correct, but he seemed to still disagree. After this horrible interview, I emailed the guy the correct answer after I looked it up and it was exactly as I described to him. He also asked me to write him a method that removes duplicates from a String in Java. I wrote two versions and sent it to him with no response. I didn’t get the job. I guess he didn’t like that he was wrong about the Perl question.

On another interview, a lady with a company called Market Access in New York called me, talked to me for a couple hours almost about a job. I agreed to a technical interview and we scheduled it for the next day and they never called. Apparently, I wasn’t important enough to them to call me back.

I’ve had several good interviews with folks. One in particular that stands out is Elavon in Knoxville, TN. These guys had their stuff together. They always called on time, treated me like they actually wanted me to come to work there and I even traded emails with the hiring manager. I was impressed by the manager and the team. I was genuinely interested in the job, but they decided to go with another guy who was cheaper and unemployed. I can’t fault them for that. I actually told the recruiter who was presenting me to them that I would back down if I had to so that the unemployed guy could have a job. I mean, I was still working at the time and I would have felt guilty if I had gotten the job over the other fella.

I had another interview with Overstock.com that went really, really well. I was completely interested in relocating to Salt Lake City, Utah and working for such a prestigious company. Unfortunately, the recruiter (Parallel) botched this one. The lady had communication issues and couldn’t understand that I had minimum requirements that had to be met. She thought that I should just drop my current job, just to fly out there to interview. I learned after this experience that unless you speak really good English and your company is not based in the city that the job is located in, I am going to prob hang up.

Unfortunately, the Elavon interview was a rare occurrence. I have had some others that were pretty close to that level, but more have been like the bad ones I talked about earlier.

Everyone knows the techniques for interviewing for a job. Dress appropriately, don’t act like an idiot, know your stuff, be on time, but few people rarely talk about the proper way to interview a job candidate. Let’s list a few.

1. Be on time. The candidate is just as bus as you are…unless they are unemployed.

2. Be courteous…what can it hurt

3. Have some personality…If your people skills are lacking, you probably don’t need to be an interviewer.

4. Interviewing for a job is a tense enough situation, put the candidate at ease, offer them a cold drink, a comfortable chair

5. Don’t grill them like a fish. You’re not interrogating a terrorist. Politely profile your candidate.

6. If they are already certified in the technology, don’t test them. For example, if the candidate says they are Java certified, just ask them to email you the certification. Don’t throw your piddly little 10 question Java test at them. They have already been tested.

7. Tell them about the things you might find frivolous. For example, tell them that you have a team lunch monthly, or that you can dress in jeans everyday of the week or that your building has a fitness room. Different things matter to different people.

8. Make sure you offer a job that will satisfy the candidate. Don’t interview an architect for a senior developer position, for example. You want them to stay, so what you want to do is get someone who isn’t completely over qualified for the title and salary you are offering.

9. This isn’t the Army. don’t promise things you can’t deliver on. If you promise the candidate they they will get to work on cool cutting edge stuff, you had better mean it if you want to keep them.

10. Be sure you know the correct answer to the questions you are going to ask and the variations on answers that are also correct. Arrogance is the worst trait to have when interviewing. On either side of the table, this is bad.

I want you to remember that just because the economy is faltering, it doesn’t mean that you have the right to act like it is a privilege just to be getting an interview. You might get the candidate, but when the economy picks back up, he/she might just leave you hi and dry and he’ll also tell all of his friends.

It reminds me of when I worked in a restaurant years ago. My boss always said, “A satisfied customer might tell noone, but a dissatisfied customer will tell everyone.”

My advice:

Put your best foot forward when interviewing. You may not get the candidate or you may not want the candidate, but either way, you want that candidate to walk away from the interview process thinking that they had the best experience they ever had. After several iterations of this, you’ll have folks beating down the door to get their resume to you.

Spring 3.0 RestTemplate

I started looking at the RestTemplate from the upcoming Spring 3.0 release and I really started thinking about where this class could be plugged in to save me some trouble. Anytime I need to access another site via HTTP, I have mostly using the Apache HTTP client and until today, that would have been my answer and I would have had to create the client, get the data, parse it myself, write routines…eh. Very manual and just reeks of hard to maintain. The RestTemplate is the answer to all that ails me. Let’s look at the technique.

There are many templates in the Spring Framework, JdbcTemplate is the first that comes to mind and it can be very powerful when writing straight JDBC applications, which I never do by the way. I can just about always write it just as efficiently by a Hibernate mapping.

All the usual suspects are included in the RestTemplate.

HTTP RestTemplate
DELETE delete(String, String…)
GET getForObject(String, Class, String…)
HEAD headForHeaders(String, String…)
OPTIONS optionsForAllow(String, String…)
POST postForLocation(String, Object, String…)
PUT put(String, Object, String…)

One you create the RestTemplate, each method accepts an argument of a uri. I’m going to take the example that Arjen Poutsma used on the Spring blog.

String result = restTemplate.getForObject(“http://example.com/hotels/{hotel}/bookings/{booking}”, String.class, “42”, “21”);

Wondering where the Spring EL is coming from?


Map vars = new HashMap();
vars.put("hotel", "42");
vars.put("booking", "21");

The data retrieved by the RestTemplate is converted by the HttpMessageConverter or a converter that you specify.

In the example, Arjen gets the photos from Flicker and places them in a Swing GUI. A+ on the way to get them F- on the choice of a client to display them in, but it was quick for him I guess.


final String photoSearchUrl =
"http://www.flickr.com/services/rest?method=flickr.photos.search&;api+key={api-key}&tags={tag}&per_page=10";

Source photos = restTemplate.getForObject(photoSearchUrl, Source.class, apiKey, searchTerm);

List imageList = xpathTemplate.evaluate("//photo", photos, new NodeMapper() {
public Object mapNode(Node node, int i) throws DOMException {
Element photo = (Element) node;

Map variables = new HashMap(3);
variables.put("server", photo.getAttribute("server"));
variables.put("id", photo.getAttribute("id"));
variables.put("secret", photo.getAttribute("secret"));

String photoUrl = "http://static.flickr.com/{server}/{id}_{secret}_m.jpg";
return restTemplate.getForObject(photoUrl, BufferedImage.class, variables);
}
});

Arjen writes a custom converter for the images and plugs it into Spring.

public class BufferedImageHttpMessageConverter implements HttpMessageConverter {

public List getSupportedMediaTypes() {
return Collections.singletonList(new MediaType("image", "jpeg"));
}

public boolean supports(Class clazz) {
return BufferedImage.class.equals(clazz);
}

public BufferedImage read(Class clazz, HttpInputMessage inputMessage) throws IOException {
return ImageIO.read(inputMessage.getBody());
}

public void write(BufferedImage image, HttpOutputMessage message) throws IOException {
throw new UnsupportedOperationException("Not implemented");
}

}

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">




















Creating a custom converter is easy. I have one for JSON data if I can ever get it working properly. Using this technique included in Spring 3.0, I doubt I will ever use Commons HttpClient again.

Spring 3.0 – REST, MVC and more

Spring 3.0 is advancing development by leaps and bounds, especially in MVC/Controller and Security. I recently converted from Spring MVC 2.0 to the new 3.0 features and I wanted to share some of the things I learned about the new release, even if it isn’t final yet. Be warned that the new Spring libraries are separated into modules and the codebase has been restructured. When I converted, it took a while to replace all the package locations with the correct ones.

Let’s take a look at my configuration for Spring MVC using 3.0.

web.xml

dispatch

org.springframework.web.servlet.DispatcherServlet

2

dispatch
/rest/*

I moved to more of a REST style, so I prefixed the trigger for the DispatchServlet to be /rest.

dispatch-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans&quot;
xmlns:p=”http://www.springframework.org/schema/p&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xmlns:context=”http://www.springframework.org/schema/context&#8221;
xmlns:tx=”http://www.springframework.org/schema/tx&#8221;
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd”&gt;

<bean id="stringMessageConverter"
class=”org.springframework.http.converter.StringHttpMessageConverter” />

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
p:basename=”classpath:messages” p:cacheSeconds=”60″/>

Pretty simple on the dispatch-servlet.xml, now let’s write out first controller. Make note of my comments in the controller class. There is some important information regarding the configuration options.

@Controller("transactionController")
@RequestMapping(value="/transaction", //Everything in this class is accessed by /rest/transaction
method = { RequestMethod.GET, RequestMethod.POST })
public class TransactionController {

@Autowired
private IPaymentService paymentService;

@InitBinder
public void setAllowedFields(final WebDataBinder dataBinder) {
dataBinder.setDisallowedFields(new String[] { "id" });
}

@RequestMapping(value = "/lookup", //accessed by /rest/transaction/lookup - really shouldn't be a verb, but sue me, this was a converted application.
method = { RequestMethod.GET, RequestMethod.POST })
//@ResponseBody //Use this annotation just to return a plain String to output stream
public String lookup(@RequestParam("json") String json) throws Exception {

Account account = new Account();
...

return account; //Automatically converted to JSON data
}

@RequestMapping(value = "/payment/{paymentId}",
//URI access..very cool, makes REST easy
method = { RequestMethod.GET, RequestMethod.POST })
//@ResponseBody
public Payment payment(@PathVariable String paymentId) throws Exception {

...

return new Payment();
}

//You can also create paths and read information like this
///payment/{paymentType}/cancel/{paymentId}

@RequestMapping(value = "/payment/cancel/{paymentId}",
method = { RequestMethod.GET, RequestMethod.POST })
//@ResponseBody
//Would have used this annotation, but there is a problem with the output stream //being corruted. If it worked, you could just return string.
public String cancel(@PathVariable String paymentId) throws Exception {

String jsonData = JSON.prepareSuccess();
Integer id = null;
try {

...
return new String();
}

@RequestMapping(value = "/print",
method = { RequestMethod.GET, RequestMethod.POST })
@ResponseBody
public String print() throws Exception {

StringBuilder sb = new StringBuilder();
//I needed to see what user was logging in and groups they had during testing.
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof UserDetails) {

UserDetails userDetails = (UserDetails) principal;

sb.append("User: " + userDetails.getUsername());
sb.append("\nPassword: " + userDetails.getPassword());

List authorities =userDetails.getAuthorities();

for (GrantedAuthority grantedAuthority : authorities) {

sb.append("\nAuthority: " + grantedAuthority.getAuthority());
log.debug("Authority: " + grantedAuthority.getAuthority());

}

log.debug(sb.toString());

}

return sb.toString();
}

protected String getCurrentUser(){

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String user = "ADM";
if (principal instanceof UserDetails) {
user= ((UserDetails) principal).getUsername();

}
return user;
}

}

OK, so there are some cool new concepts here. My favorite is the @ResponseBody annotation, although I couldn’t use it. The URI variables are really nice. It makes it easier to support REST and you can eliminate ? and & in building a url.

@ResponseBody is suppose to render elements directly to the output stream, otherwise an object will get caught by the JacksonJsonConverter and converter to JSON and passed on the output stream.

A limitation of the @ResponseBody is that there isn’t currently a way to specify the content-type of the return object like in other REST frameworks. I have high hopes that this will be added. For example, I wanted to return a String of Json, but the StringHttpMessageConverter catches it and sends text/plain, but I want to send application/json. I tried to write a converter, but with no avail. In my opinion, the annotation really needs a attribute so that you can override the default content type in place without having to write a converter.

@ResponseBody(content-type=”application/json”) //This would be ideal.

<!– –>

<!–

–>

Here are some other examples of things you can do taken straight from the Spring blog.

http://blog.springsource.com/2009/03/08/rest-in-spring-3-mvc/

Please take a look at the RestTemplate. It is one of the best new features.
http://blog.springsource.com/2009/03/27/rest-in-spring-3-resttemplate/

Overall, I like the new features a lot. If I can get @ResponseBody and fix my JSON return issue, I will be gold though. All hail Spring, the King of the Java frameworks.

Spring Active Directory Configuration that works…

Authentication and authorization with Active directory and Spring is tough…tougher than it should be. Trying to find working examples is also very difficult, so once I had a working version, I decided to share it.

You really don’t need any custom classes to do this. Spring has all the necessary built-in objects. In order to run this, you will need Spring 3.0 and Spring Security 3.0.

The example below doesn’t take full advantage of the namespace configuration. I just didn’t have the time to get that all put together. If you have a cleaner “working” example, please post as a comment, so others can learn by your example.

<beans xmlns="http://www.springframework.org/schema/beans&quot;
xmlns:context=”http://www.springframework.org/schema/context&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xmlns:aop=”http://www.springframework.org/schema/aop&#8221;
xmlns:security=”http://www.springframework.org/schema/security&#8221;
xmlns:tx=”http://www.springframework.org/schema/tx&#8221;
xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd”&gt;

<!–
constructor = LDAP domain name userDn = user id used to query the
directory password = password for managerDn baseEnvironmentProperties
= additional ldap environment properties
–>
<bean id="initialDirContextFactory"
class=”org.springframework.security.ldap.DefaultSpringSecurityContextSource”>
<constructor-arg
value=”ldap://adserver:389/dc=domain,dc=com” />
<property name="userDn"
value=”CN=cipldap,OU=Service Accounts,OU=Organizational Units,DC=domain,DC=com” />

follow

<!–
Used to search active directory for the user id of the user attempting
to login to the system. 1. Instead of binding directly, Acegi uses the
filter to find a matching user 2. If no user is found, that’s a
failure. 3. If a user is found, takes that users DN and tries to bind
using it 4. Success to bind means that we are okay, failure means
incorrect password constructor 0 = BaseDN for user search constructor
1 = Filter statement for user id lookup constructor 2 = initial
context factory defined above searchSubtree = search the subtrees
beneath BaseDN.
–>
<bean id="userSearch"
class=”org.springframework.security.ldap.search.FilterBasedLdapUserSearch”>

<!–
Peform the LDAP user bind using the context factory and user search

constructor = initial context factory defined above userSearch =
userSearch defined above
–>
<bean id="bindAuthenticator"
class=”org.springframework.security.ldap.authentication.BindAuthenticator”>

<!–
Used for authorization. Populate the user with a set of roles based
upon AD groups. constructor 0 = context factory constructor 1 = BaseDN
for groups groupRoleAttribute = attribute used for role names
–>
<bean id="authoritiesPopulator"
class=”org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator”>

<!–
LDAP Authentication Provider uses the bindAuthenticator and
authoritiesPopulator to authenticate the user and populate the user
object with roles based upon Active Directory groups.
–>
<bean id="ldapAuthProvider"
class=”org.springframework.security.ldap.authentication.LdapAuthenticationProvider”>


You can use this section to map your groups and roles from your application to groups and roles in LDAP. I just restated the same ones that were stored in my Active Directory server.

<bean id="userDetailsContextMapper"
class=”org.springframework.security.ldap.userdetails.LdapUserDetailsMapper”>

ROLE_PROJECT_INQUIRY
ROLE_PROJECT_UPDATE

<bean id="userDetailsService"
class=”org.springframework.security.ldap.userdetails.LdapUserDetailsService”>

<security:authentication-provider
ref=”ldapAuthProvider” user-service-ref=”userService” />

Once your configuration is written, you can now access your user and group information via Spring.
@RequestMapping(value = "/print",
method = { RequestMethod.GET, RequestMethod.POST })
@ResponseBody
public String print() throws Exception {

StringBuilder sb = new StringBuilder();
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof UserDetails) {

UserDetails userDetails = (UserDetails) principal;

sb.append("User: " + userDetails.getUsername());
sb.append("\nPassword: " + userDetails.getPassword());

List authorities =userDetails.getAuthorities();

for (GrantedAuthority grantedAuthority : authorities) {

sb.append("\nAuthority: " + grantedAuthority.getAuthority());
log.debug("Authority: " + grantedAuthority.getAuthority());

}

log.debug(sb.toString());

}

return sb.toString();
}

Also, now that you have your setup, you can use security annotations and intercept-url elements in the config to lock down your application. It took me a while to get all of this working correctly. I’d much rather have authenticated against a database table instead of Active Directory and spared myself some of the pain.

Spring Security 3.0 – Worth the Frustration

I normally don’t get too frustrated with using Spring but…the migration to using the 3.0 version of the framework was fairly painful. Even though the framework is not final, I decided to go ahead and jump in. The codebase was entirely restructured into different jars that represent the subprojects in the framework. Two of the most notable changes are in the Security and MVC frameworks. I struggled for about four days trying to convert my application over. I want to try to save some of you that frustration by presenting some practical examples.

All in all, the new features in Spring 3.0 are great. The @PreAuthorize and @PostFilter annotations are a great new feature. The REST support and RestTemplate are also a nice new features. There are too many to even list at one time. Let’s dig into the code to see how I implemented security and you’ll get an idea of what you need to do to get it fired up.

I had a few requirements that I had to fulfill with my security setup. I had to support Active Directory and I also had to provide fairly flexible support for url security and method security. Let’s start by taking a look at the configuration and then we’ll look at some class examples.

I decided to use a hybrid of namespace and the old fashioned configuration. After four days of getting this to work, I really didn’t care about the looks of it. I just wanted it to work. Feel free to help me out if you see problems.

<beans xmlns="http://www.springframework.org/schema/beans&quot;
xmlns:context=”http://www.springframework.org/schema/context&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xmlns:aop=”http://www.springframework.org/schema/aop&#8221;
xmlns:security=”http://www.springframework.org/schema/security&#8221;
xmlns:tx=”http://www.springframework.org/schema/tx&#8221;
xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd”&gt;

Let’s enabled the new pre and post annotations

<security:global-method-security
pre-post-annotations=”enabled” />

If you need a special permission evaluation, here is where you do it
<!–

<bean id="expressionHandler"
class=”org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler”>

<bean id="permissionEvaluator"
class=”com.domain.project.web.security.LDAPPermissionEvaluator”>

–>


This is where my frustrations came in at. This is where you will do all your work for filtering url paths, setup your form authentication and whatnot. This section provides just about everything you need out of the box to authenticate and authorize. A cookbook of different configurations would be extremely helpful here.

<security:http use-expressions="true" auto-config='false'
realm=”Project” entry-point-ref=”authenticationProcessingFilterEntryPoint”>

<security:intercept-url pattern="/login.jsp*"
filters=”none” />

<security:intercept-url pattern="/logout.jsp*"
filters=”none” />

<security:form-login login-page='/login.jsp'
default-target-url=’/index.jsp’ always-use-default-target=’true’ />

<!–
<security:intercept-url pattern="/*.jsp"
access=”hasRole(‘ROLE_PROJECT_INQUIRY’)” />
–>

<security:intercept-url pattern="/portal.jsp"
access=”hasAnyRole(‘ROLE_PROJECT_UPDATE’,’ROLE_PROJECT_UPDATE’)” />

<security:intercept-url pattern="/"
access=”hasAnyRole(‘ROLE_PROJECT_UPDATE’,’ROLE_PROJECT_UPDATE’)” />

<security:intercept-url pattern="/index.jsp"
access=”hasAnyRole(‘ROLE_PROJECT_UPDATE’,’ROLE_PROJECT_UPDATE’)” />

<!–
<security:intercept-url pattern="/rest/transaction/payment/cancel/**"
access=”hasRole(‘ROLE_PROJECT_INQUIRY’)” />
–>

<security:intercept-url pattern="/rest/**"
access=”hasAnyRole(‘ROLE_PROJECT_UPDATE’,’ROLE_PROJECT_UPDATE’)” />

<!–
<intercept-url pattern="/listAccounts.html" access="isRememberMe()"
/>
–>

<!– –>

In order to really understand the filter chain process in 3.0, you really have to study this table.

Alias Filter Class Namespace Element or Attribute
CHANNEL_FILTER ChannelProcessingFilter http/intercept-url
CONCURRENT_SESSION_FILTER ConcurrentSessionFilter

http/concurrent-session-control
SESSION_CONTEXT_INTEGRATION_FILTER HttpSessionContextIntegrationFilter http
LOGOUT_FILTER LogoutFilter http/logout
X509_FILTER X509PreAuthenticatedProcessigFilter http/x509
PRE_AUTH_FILTER AstractPreAuthenticatedProcessingFilter Subclasses N/A
CAS_PROCESSING_FILTER CasProcessingFilter N/A
AUTHENTICATION_PROCESSING_FILTER UsernamePasswordAuthenticationProcessingFilter http/form-login
BASIC_PROCESSING_FILTER BasicProcessingFilter http/http-basic
SERVLET_API_SUPPORT_FILTER SecurityContextHolderAwareRequestFilter http/@servlet-api-provision
REMEMBER_ME_FILTER RememberMeProcessingFilter http/remember-me
ANONYMOUS_FILTER AnonymousProcessingFilter http/anonymous
EXCEPTION_TRANSLATION_FILTER ExceptionTranslationFilter http
NTLM_FILTER NtlmProcessingFilter N/A
FILTER_SECURITY_INTERCEPTOR FilterSecurityInterceptor http
SWITCH_USER_FILTER SwitchUserProcessingFilter N/A

You can also use the after or before attributes if you want your filter to be inserted before or after another filter in the stack. The names “FIRST” and “LAST” can be used with the position attribute to indicate that you want your filter to appear before or after the entire stack, respectively.
[Tip] Avoiding filter position conflicts

If you are inserting a custom filter which may occupy the same position as one of the standard filters created by the namespace then it’s important that you don’t include the namespace versions by mistake. Avoid using the auto-config attribute and remove any elements which create filters whose functionality you want to replace.

Note that you can’t replace filters which are created by the use of the element itself – HttpSessionContextIntegrationFilter, ExceptionTranslationFilter or FilterSecurityInterceptor.

If you’re replacing a namespace filter which requires an authentication entry point (i.e. where the authentication process is triggered by an attempt by an unauthenticated user to access to a secured resource), you will need to add a custom entry point bean too.
Setting a Custom AuthenticationEntryPoint

If you aren’t using form login, OpenID or basic authentication through the namespace, you may want to define an authentication filter and entry point using a traditional bean syntax and link them into the namespace, as we’ve just seen. The corresponding AuthenticationEntryPoint can be set using the entry-point-ref attribute on the element.

<!–
<concurrent-session-control max-sessions="1"
exception-if-maximum-exceeded=”true”/>
–>

<!– If you want to use basic authentication–>

<!–
constructor = LDAP domain name userDn = user id used to query the
directory password = password for managerDn baseEnvironmentProperties
= additional ldap environment properties
–>
<bean id="initialDirContextFactory"
class=”org.springframework.security.ldap.DefaultSpringSecurityContextSource”>
<constructor-arg
value=”ldap://adserver:389/dc=domain,dc=com” />
<property name="userDn"
value=”CN=cipldap,OU=Service Accounts,OU=Organizational Units,DC=domain,DC=com” />

follow

<!–
Used to search active directory for the user id of the user attempting
to login to the system. 1. Instead of binding directly, Acegi uses the
filter to find a matching user 2. If no user is found, that’s a
failure. 3. If a user is found, takes that users DN and tries to bind
using it 4. Success to bind means that we are okay, failure means
incorrect password constructor 0 = BaseDN for user search constructor
1 = Filter statement for user id lookup constructor 2 = initial
context factory defined above searchSubtree = search the subtrees
beneath BaseDN.
–>
<bean id="userSearch"
class=”org.springframework.security.ldap.search.FilterBasedLdapUserSearch”>

<!–
Peform the LDAP user bind using the context factory and user search

constructor = initial context factory defined above userSearch =
userSearch defined above
–>
<bean id="bindAuthenticator"
class=”org.springframework.security.ldap.authentication.BindAuthenticator”>

<!–
Used for authorization. Populate the user with a set of roles based
upon AD groups. constructor 0 = context factory constructor 1 = BaseDN
for groups groupRoleAttribute = attribute used for role names
–>
<bean id="authoritiesPopulator"
class=”org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator”>

<!–
LDAP Authentication Provider uses the bindAuthenticator and
authoritiesPopulator to authenticate the user and populate the user
object with roles based upon Active Directory groups.
–>
<bean id="ldapAuthProvider"
class=”org.springframework.security.ldap.authentication.LdapAuthenticationProvider”>

<bean id="userDetailsContextMapper"
class=”org.springframework.security.ldap.userdetails.LdapUserDetailsMapper”>

ROLE_PROJECT_INQUIRY
ROLE_PROJECT_UPDATE

<bean id="userDetailsService"
class=”org.springframework.security.ldap.userdetails.LdapUserDetailsService”>

<security:authentication-provider
ref=”ldapAuthProvider” user-service-ref=”userService” />

Like I said, it took about 4 days to get this working exactly the way I wanted it to for my application. This was mainly because good documentation on the new features was just hard to find, just a smattering of an article by Luke Taylor, a Spring developer and guru. The sample apps and documention were inaccurate in spots and contained holdovers from 2.0 that prevented my application for working.

Now that we have our application setup and we can login, we can annotate our Spring classes. I annotate at the Service level because I generally have many different types of clients accessing the application.

...
@Service("paymentService")
@Transactional
@PreAuthorize("hasAnyRole('ROLE_PROJECT_UPDATE','ROLE_PROJECT_UPDATE')")
public class PaymentServiceImpl extends ServiceImpl implements IPaymentService {

...

@PreAuthorize("hasRole('ROLE_PROJECT_UPDATE')")
public void terminate(Integer id, String user) throws Exception {

paymentWebService.cancelPayment(id,user);
}

...

What is happening here is that Spring Security is going to check to see if the user has the ROLE to execute this method before it actually executes it. You can also use these annotations on any other Spring bean and the expressions are really powerful. You can also use conjunctions like “and” to include multiple expressions.

Some of the available expressions are defined here. These are subject to change since 3.0 is not in the final release phase yet.

Here are some security configuration examples from a blog entry written by Luke Taylor. These can be used universally in the config or in annotations.

access=”hasRole(‘ROLE_SUPERVISOR’) and hasIpAddress(‘192.168.1.0/24′)

@PreAuthorize(“hasPermission(#contact, ‘admin’)”)

Using Spring-EL
@PreAuthorize(“#contact.name == principal.name)”)
public void doSomething(Contact contact);

@PreAuthorize(“hasRole(‘ROLE_USER’)”)
@PostFilter(“hasPermission(filterObject, ‘read’) or hasPermission(filterObject, ‘admin’)”)
public List getAll();

When used with the @PostFilter annotation, Spring Security iterates through the returned collection and removes any elements for which the supplied expression is false. The name “filterObject” refers to the current object in the collection. You can also filter before the method call, using @PreFilter, though this is probably a less common requirement. The syntax is just the same, but if there is more than one argument which is a collection type then you have to select one by name using the “filterTarget” property of this annotation.

The migration to 3.0 was really worth the frustration is getting it setup. I hope this will help others in getting it setup.

.NET Project Blues…Java vs .NET

By Chris L Hardin
Sr. Software Architect
It’s been almost 3 years since I have written a .NET project from scratch and I have to tell you, I am getting the itch. Don’t get me wrong, on any new project, I would choose Java hands down as the technology for the job due to one major factor…money, but a architect likes to keep his skills up.

This might be a good opportunity to list some of the reasons why I prefer Java/J2EE solutions over .NET solutions. Let’s look at a nice list and I’ll event throw in a few things that .NET is better at.

1. Java is more cost effective. You can do any Java project totally on the cost of writing the code. No purchases needed. Jboss or Tomcat for the Web/Application Server, Hibernate for the ORM mapping, Spring for the business layer and integrations and choose a great open source database like PostgreSQL and let me tell you…it rocks. Run it all on Linux servers. In .NET, I am going to get stuck for cost somewhere. The windows server, the database if I choose SQL Server, other components that Microsoft wants to stick me for. .NET does have a cost advantage in the area of developers. .NET developers typically make about 15% less than Java developers. I really can attribute this statistic to any one particular reason, however it is an advantage.

2. There is typically no difference between .NET and Java that you can name that make them night and day different. If a developed two applications,one in Java and the other in C#, you’d be able to follow them both easily if you know either language alone. I’d use nHibernate, Spring.NET and Spring MVC on the .NET side just like I would use Hibernate, Spring and Spring MVC on the Java side.

3. It is very easy to build a GUI in .NET with Visual Studio. Well, this is not really a fair comparison. Visual Studio is an expensive product and there is only one way to write a page in .NET and that is ASP.net. Java is more flexible, the good ideas are free…you know. I will say this though. If I had a requirement to build a fat client, I would download SharpDevelop and do it in C# before I would touch Java Swing. I’d rather had my head crushed in a vice than write Swing. Been there and done that. Also, I’d rather write an interface in ASP.NET using SharpDevelop than use Java Server “Feces”. My main preference is to write my front end in Dojo or some other Javascript framework and keep my front end neutral of .NET or Java.

4. VB.NET sucks…enough said. It should never have been allowed to live. .NET should have been C# only and if people still wanted to write VB, they just could stay on their old platforms and not upgrade. Now everyone thinks that VB will always be supported and it probably will…unfortunately. I prefer C# just because it is so much like Java. Don’t get me wrong, I like Perl, Javascript and Ruby too…just to let you know I am not completely bias. I know enough about VB to fill a small thimble, but I have seen it enough to know I hate it.

5. Hibernate and Spring are originally written in Java and ported to .NET later. There is always a wait for the latest version of nHibernate and Spring.NET.

6. EJBs are dead…get over it. I wrote em, I used em, I evangelized them… I let em go. Spring and Hibernate effectively killed them dead.

7. JSF is dying…get over that too…and Struts is dead as well. If you are looking at EJBs, Struts or JSF for a new project, you need your head examined. I’ve done many, many projects with these technologies, so don’t tell me I havn’t used them and don’t know what I am talking about. The Ajax craze is effectively killing page technologies like ASP,JSP…etc. Don’t even bother telling me, “Well there are Ajax components in JSF (ICE Faces) and in .NET. Go ahead put together an interface weave these components together and watch the different Ajax libraries clash at runtime. Just learn the Dojo, Ext, Google Web Toolkit, YUI frameworks and learn to use the widgets or hire me to do it for you.

8. Java is always going to be more advanced than .NET. It is always going to enjoy the benefits of more open source libraries in the language than you can shake a stick at because it is freely available and runs easier on more platforms. Unix/Linux servers are more stable, try to cobble a .NET project to run on one.

9. Microsoft changes it’s own standard when it sees fit, doesn’t matter to them if you have to change all your code. They change meaningless crap in the specifications their own browser supports, but keep VB.net. For cripes sake, I’d rather write an entire application in Intermediate Language.

10. C# is a clone of Java. Java was out there long before C# was even a gleam in some Microsoft engineers eye. C# was based on Java and it is no mistake that C# looks exactly like it except for subtle changes. The changes aren’t really big enough to call it another language in my opinion. I worked on a project once where I went back and forth all day. I had a minor stutter here and there but no major issues.

I think I started telling you something interesting and it developed into a rant on top of a soapbox. Although I do love Java, I do enjoy doing a .NET project every so often to keep myself at least versed enough to be able to explain what I am talking about. Imitation is the most sincere form of flattery. I guess I should be thankful that C# came out looking like Java rather than an advanced form of VB.

I’m just waiting for that next big language to come around like Java and C# when they came onto the scene. I thought Ruby was going to be it, but boy was I fooled. Ruby enjoys a great following, but I’d call it more of a cult. Now that I have said that I am looking over my shoulder for some Ruby zealot to smite me.