Apache Wicket vs. JSF PrimeFaces Evaluation

My team was recently tasked with selecting a replacement for GWT (Google Web Toolkit). We have a few pet peeves about GWT but our biggest is the compilation time.

It turns out there are quite a few options.  However, we didn’t have the luxury of trying out every tool.  Instead, we chose 2.

We decided that Apache Wicket and JSF PrimeFaces would be the most viable candidates taking into account the state of the current application.

We also decided that we needed to put together a proof of concept that was to be evaluated by the team and the client.  We had 2 teams of 2.  Each team replicated the same existing application screen with their chosen UI framework.

The evaluation was based on:

Reduced Compile Time

Overall Effort

Performance

Look n Feel

Support/Documentation

Extendability

Widget Set

Developer Experience

While JSF did not win in every category it was the overall winner by the team and the client.

Given our time constraints it was difficult to determine which framework had better performance.

Advertisements

Java 8 and GoDaddy SSL certificates

I recently ran into an issue where I was trying to integrate two applications over SSL.

I was getting this error (which was covered in one of my earlier blog posts):

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Essentially, GoDaddy is phasing on SHA-1 certs and moving to SHA-2 certs.  Check this out for further information:

http://tozny.com/blog/godaddys-ssl-certs-dont-work-in-java-the-right-solution/

Solution:

In my case we were running Java 8 u60, so we had to import gd_bundle-g2-g1.crt into cacerts by running:

%JAVA_HOME%\jre\lib\security>keytool –import –alias gd_bundle-g2-g1 –file gd_bundle-g2-g1.crt –keystore cacerts -trustcacerts

And as you probably know, the password is changeit

Spring Security: Supporting Multiple LDAP Directory Services

Scenario/Problem:

The application I was working on authenticated against Active Directory (AD).  However, I wanted each developer to have the ability to run the full-fledged application on their own developer machine, and running AD on a developer machine isn’t ideal. Hence, problem #1.

Options:

Thankfully, there are free LDAP servers available.  Apache Directory Studio and Active Directory Lightweight Directory Services (AD LDS) are just a few.

Approach A:

We first tried Apache Directory Studio but the application would not recognize the username.  Finally we determined that AD accepts the sAMAccountName attribute as the username, while most other LDAP servers simply use uid.  So problem #2 became, how do we support both?

Approach B:

It turns out what I really needed to do was create an LDAP search filter.  And I found a great how-to on the Atlasssian website of all places.

https://confluence.atlassian.com/display/DEV/How+to+write+LDAP+search+filters

So the spring security configuration went from:


<bean id=”userSearch”
class=”org.springframework.security.ldap.search.FilterBasedLdapUserSearch”>
<constructor-arg index=”0″ value=”” />
<constructor-arg index=”1″ value=”(sAMAccountName={0})” />
<constructor-arg index=”2″ ref=”contextSource” />
</bean>


to this:


<bean id=”userSearch”
class=”org.springframework.security.ldap.search.FilterBasedLdapUserSearch”>
<constructor-arg index=”0″ value=”” />
<constructor-arg index=”1″ value=”(|(uid={0})(sAMAccountName={0}))” />
<constructor-arg index=”2″ ref=”contextSource” />
</bean>


Another problem:

I wish I could say that solved everything.  Unfortunately, Apache Directory Studio became non-responsive on multiple developer machines after a restart.

We were unable to get it up and running again so we switched to AD LDS.  This proved to be a better fit for us because Apache Directory Studio was required to run in the foreground.  With AD LDS we could run it in the background.  However, one downside of AD LDS is that you require a client tool, like ADSI Edit to configure it.  Also, there was 1 gotcha.  You need to add your newly created users to the ‘Reader’ role.  You do that by adding them to the ‘member’ attribute of the Reader role.

Spring Security: Migrating from 3.x to 4.x

So I started out migrating the Spring components of my web application by updating Maven to pull the 4.x Spring releases.

I expected some changes with regards to Spring MVC, but I didn’t expect changes related to Spring Security.

The spring-security.xml started out as follows:

And the login.jsp had the standard fields and action:


<form name='loginForm' action="<c:url value='/j_spring_security_check' />" method='POST'>

<table>

<tr>

<td>User:</td>

<td><input type='text' name='j_username'></td>

</tr>

<tr>

<td>Password:</td>

<td><input type='password' name='j_password' /></td>

</tr>

<tr>

<td colspan='2'><input name="submit" type="submit" value="submit" /></td>

</tr>

</table>

</form>


The problem started when I had the application entirely running on Spring 4.x and I tried logging in without success.

Nothing made sense.  I examined the logs which reported “Access is denied” and “anonymousUser”.  This seemed odd because the http posts seemed fine.

I tried modifying the spring-security.xml many times without success.  Then I tried to move the security configuration from xml to Java based.  Essentially, I introduced a SecurityConfig class (with @EnableWebSecurity annotation) but that didn’t work either.

Finally, I went back to the xml based configuration and added j_spring_security_check/j_username/j_password.  This solved the problem.  It still doesn’t make sense to my why I had to do that.

Here’s what the spring-security.xml ended up looking like:


<sec:http use-expressions=”true” auto-config=”true”>

<sec:csrf disabled=”true”></sec:csrf>

<sec:intercept-url pattern=”/css/*” access=”permitAll”/>

<sec:intercept-url pattern=”/images/*” access=”permitAll”/>

<sec:intercept-url pattern=”/jsp/login.jsp” access=”permitAll”/>

<sec:intercept-url pattern=”/**” access=”isAuthenticated()” />

<sec:form-login login-page=”/jsp/login.jsp” login-processing-url=”/j_spring_security_check” username-parameter=”j_username” password-parameter=”j_password” default-target-url=”/index.html” authentication-failure-url=”/jsp/login.jsp?login_error=1″ always-use-default-target=”true”/>

<sec:logout logout-url=”/j_spring_security_logout” invalidate-session=”true” logout-success-url=”/jsp/login.jsp?loggedout=true” />

</sec:http>


CSD (Certified Scrum Developer)

I’ve had my eye on the course for quite some time but unfortunately I’ve never seen it offered in Canada.  So I decided to take the course in Minneapolis.

It’s a 3 day course that is very technical (i.e. you will be coding).  It focuses on many aspects as programming but the ones that stand out to me are TDD and Refactoring.

If you’re looking to obtain the CSD certification there are some additional requirements.  You will need to take an additional 2 days of Scrum training.  So if you already have the CSM certification and you take this course, you will qualify for the CSD.

I was very pleased with the outcomes of this course.  We practiced additional techniques which included pair programming and CRC.  I would highly recommend this course because I think a Scrum team practicing what I learned (in just 3 days) would be highly productive.

Here is a partial list of the technologies we used:

  • Java
  • Jenkins
  • JUnit
  • Git
  • Gradle

I hope to see more of these hands-on technical courses.

MDC (Mapped Diagnostic Context) Filter

Problem:

I wanted to add username and ip address to each logging entry of my Java web application.  I assumed I would have to go through each logging entry and add it manually, or perform some sort of fancy find/replace.

Research:

After consulting my best friend Google, I discovered that an MDC servlet filter was the correct approach.  However, I wasn’t sure of how much effort was required.  After some pondering I decided the correct approach is what I needed to do.

Solution:

I required a new class (see below):

package com.example;
import org.jboss.logging.MDC;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class MDCFilter implements Filter {
@Override
 public void init(FilterConfig filterConfig) throws ServletException {
 }
@Override
 public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
 throws IOException, ServletException {
 Authentication authentication =
 SecurityContextHolder.getContext().getAuthentication();
 if (authentication != null) {
 MDC.put(Constants.mdc_username, authentication.getName());
 }
 HttpServletRequest httpRequest = (HttpServletRequest) req;
 String ipAddress = httpRequest.getHeader("X-FORWARDED-FOR");
 if (ipAddress == null) {
 ipAddress = req.getRemoteAddr();
 }
 MDC.put(Constants.mdc_ipaddress, ipAddress);
 try {
 chain.doFilter(req, resp);
 } finally {
 if (authentication != null) {
 MDC.remove(Constants.mdc_username);
 }
 MDC.remove(Constants.mdc_ipaddress);
 }
 }
@Override
 public void destroy() {
 }

}

Additionally, I required a modification to the web.xml:

 <filter>
 <filter-name>mdcFilter</filter-name>
 <filter-class>com.example.MDCFilter</filter-class>
 </filter>

 <filter-mapping>
 <filter-name>mdcFilter</filter-name>
 <url-pattern>/*</url-pattern>
 </filter-mapping>


Final Thoughts:

Considering how little work was required I’m convinced I made the right decision.  Also, if I need to add any additional fields to my log entries I simply need to modify the MDCFilter class.  That’s it.

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

The Problem

There are plenty of posts on this problem throughout the Internet.  However, I found very few of them useful.  When you come across this exception you really need to understand the problem in order to implement a solution.

If you’re seeing this error then you’re probably running a Java web server such as JBoss, WebLogic, or others.

In my experience the problem is this:

Your application is trying to connect to a url via https (i.e SSL).

Even though the site you’re trying to connect to has an SSL certificate, the certificate authority (CA) is not recognized by  Java.  In general, Java recognizes popular CAs such as VeriSign and GoDaddy which can be validated by running the keytool utility on the cacerts file which is located in %JAVA_HOME%\lib\security.

What should developers do?

You need to determine the CA of the SSL certificate.  You can typically do this by going to the site via a web browser and clicking on the lock button.  Then you need to navigate to the CA’s website and download the corresponding Root certificate (typically a .crt file).

Then you need to run the keytool utility to add the certificate to the cacerts file.  Make a note to use a unique alias.

Here is an example:

keytool -import -alias gdroot-g2 -file gdroot-g2.crt -keystore cacerts -trustcacerts

Restart the web server and you should be fine.

What should developers not do?

There are many posts out there that tell you how to implement a trust manager and/or a custom hostname verifier to get around this problem.  Please do not do that.  You really want to fix this problem correctly, especially if it is going in a production environment.

Final Thoughts

It is tempting to implement a quick fix and add a TODO.  We all know what that means.  Days, weeks, months, maybe years go by and the TODO is still there.