Creat rich text (HTML) emails with inline images from Japser Report

This blog demonstrates how to create and export a HTML file with inline images with Jasper Report for use as an email message in Java Mail.

First, create the report from Jasper Report template in JasperPrint object:

JasperPrint jasperPrint = … // Run report

Now setup HTML exporter:

JRHtmlExporter exporter = new JRHtmlExporter();

Map imageData = new HashMap();

exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STRING_BUFFER, buffer);   exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, “cid:”);      exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, imagesData);
exporter.exportReport();

Of particular interest is the parameters IMAGES_URI and IMAGES_MAP of the HTML exporter. You provide the URI for inlining and an empty hashmap for the exporter to store the images rendered in the  output html string.

Next add inline images to the Java Mail message by processing the imageData map populated by the exporter as follows using the addInLine method of Java Mail class MimeMessageHelper:

MimeMessageHelper helper = new MimeMessageHelper(message, MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED);
// attach the html data from htmlOutputData to inline images
for (Iterator<Entry> it = imagesData.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = it.next();
String imageName = (String) entry.getKey();
byte[] imageData = (byte[]) entry.getValue();
// attach imageData using imageName as Content-ID
helper.addInline(imageName, new ByteArrayResource(imageData), “image/jpeg”);
}

Active Directory Authentication with Spring Security 3.1

Spring Security v3.1 adds new support for Active Directory authentication with the new authentication provider class ActiveDirectoryLdapAuthenticationProvider. This article will provide a step-to-step on how to set up Spring Security to authenticate users in a J2EE web application using AD. I will also demonstrate how to configure a custom filter to the authentication filter chain.

Getting Spring Security 3.1

I use version 3.1.0.RELEASE with the following Maven setup:

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>

Configure Active Directory Authentication

Configure Spring Security to use class ActiveDirectoryLdapAuthenticationProvider  is rather straight forward:

<beans:bean id=”ldapAuthProvider”
class=”org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider”>
<beans:constructor-arg value=”${ldap.domain}” />
<beans:constructor-arg value=”${ldap.url}” />
</beans:bean>

<authentication-manager alias=”authenticationManager”>
<authentication-provider ref=”ldapAuthProvider”>
</authentication-provider>
</authentication-manager>

So all you need is to set up Spring Security to use the AD class as authentication provider and provide the domain and url as constructor parameters.

Custom Login Filter

Now the fun part. In many cases you would need to customise the authentication/authorisation performed by Spring Security. For example, to use extra information such as user’s company/division as part of the authentictaion/authorisation process. Spring Security allows you to replce the default filter with your own custom filter for this.

First implement your custom filter by extending class UsernamePasswordAuthenticationFilter. See the javadoc for methods supported. For example, to perform some processing on successful authentication:

public class MyUsernamePasswordAuthFilter extends UsernamePasswordAuthenticationFilter {

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain, Authentication authResult)
throws IOException, ServletException {
super.successfulAuthentication(request, response, filterChain, authResult);
String username = super.obtainUsername(request);
// do something with  username


}

In Spring bean configuration, add the following:

<beans:bean id=”navSecurityFilter” class=”com.rlee.example.security.MyUsernamePasswordAuthFilter”>
<beans:property name=”authenticationManager” ref=”authenticationManager” />
<beans:property name=”authenticationFailureHandler” ref=”failureHandler” />
<beans:property name=”authenticationSuccessHandler”ref=”successHandler” />
</beans:bean>

<beans:bean id=”successHandler”
class=”org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler”>
<beans:property name=”defaultTargetUrl” value=”/”/>
<beans:property name=”alwaysUseDefaultTargetUrl” value=”true”/>
</beans:bean>
<beans:bean id=”failureHandler”
class=”org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler”>
<beans:property name=”defaultFailureUrl” value=”/login.jsp?login_error=true”/>
</beans:bean>

Note I also include the success and failure handlers properties to the custom filter. The next step is to include the custom filter in the Spring Security http configs.

<http auto-config=’false‘ entry-point-ref=”LoginUrlAuthenticationEntryPoint“>
<custom-filter ref=”mySecurityFilter” position=”FORM_LOGIN_FILTER” />
<intercept-url pattern=”/login.jsp*” access=”IS_AUTHENTICATED_ANONYMOUSLY” requires-channel=”https” />
<intercept-url pattern=”/**” access=”ROLE_REGISTERD_USER” />
<anonymous />

<logout />
</http>

Note you have to disable the auto-config option and insert the custom-filter tag to replace the default Spring Security filter in the  position FORM_LOGIN_FILTER. See Spring Security documentation here for more details on filter chain. For completeness, the entry point config is shown below:

 <beans:bean id=”LoginUrlAuthenticationEntryPoint”
class=”org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint”>
<beans:property name=”loginFormUrl” value=”/login.jsp” />
<beans:property name=”forceHttps” value=”true” />
</beans:bean>

Conclusions

That’s all. The new Active Directory authentication support in Spring Security 3.1 makes things much easier to configure than using LDAP authentication provider in v3.0. I also show how you can replace the default filter used by Spring Security with your own custom filter. Hope this helps.