JasperReports Server Authentication Reference

JasperReports Server Authentication and Passwords

Introduction

JasperReports Server makes extensive use of Spring and uses the Spring sub-project, Acegi Security, for authentication and authorization. Acegi works through optional filters that can be wired together in a wide variety of ways.

The start of Acegi security is the security filter that is configured in your web.xml. The same mechanism can be used for Web and Web services applications.

<filter>
    <filter-name>
        securityFilter
    </filter-name>
    <filter-class>
        org.acegisecurity.util.FilterToBeanProxy
    </filter-class>
    <init-param>
        <param-name>
            targetClass
        </param-name>
        <param-value>
        org.acegisecurity.util.FilterChainProxy
        </param-value>
    </init-param>
</filter>

You can secure the parts of your application by defining the URLs you want to apply the security filter to. By default in JasperReports Server, we secure all pages - note the url-pattern below.

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

Next we define our FilterToBeanProxy in a Spring configuration file. Here is the default one in JasperReports Server. The filterChainProxy gets a bit more complex in JasperReports Server v5.1 onwards.

<bean class="org.acegisecurity.util.FilterChainProxy"
      id="filterChainProxy">
    <property name="filterInvocationDefinitionSource">
        <value>
            CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
            PATTERN_TYPE_APACHE_ANT
            /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,
            basicProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,
            filterInvocationInterceptor
        </value>
    </property>
</bean>

The list of filters are applied in order. Since we are focusing on authentication, let's follow the exceptionTranslationFilter first. This filter deals with unauthenticated users/interactions.

Getting Credentials for Authentication

<bean class="org.acegisecurity.ui.ExceptionTranslationFilter"
      id="exceptionTranslationFilter">
    <property name="authenticationEntryPoint">
         <ref local="authenticationProcessingFilterEntryPoint"></ref>
    </property>
</bean>
 
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"
      id="authenticationProcessingFilterEntryPoint">
    <property name="loginFormUrl">
         <value>/login.html</value>
    </property>
    <property name="forceHttps">
         <value>false</value>
    </property>
</bean>

This configuration forces form-based authentication. Unauthenticated users will be forced to go to /login.html to enter their credentials. When they enter this, the authenticationProcessingFilter will be invoked.

<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter"
      id="authenticationProcessingFilter">
    <property name="authenticationManager">
        <ref local="authenticationManager" />
    </property>
    <property name="authenticationFailureUrl">
        <value>/loginerror.html</value>
    </property>
    <property name="defaultTargetUrl">
         <value>/flow.html?_flowId=listReportsFlow</value>
    </property>
    <property name="filterProcessesUrl">
        <value>/j_acegi_security_check</value>
    </property>
</bean>

In this case, Acegi will authenticate using the authenticationManager when the login form posts to /j_acegi_security_check. It is easy to use non form-based authentication, like HTTP Basic or HTTP Digest, as Acegi comes with filters that can be wired up to implement those protocols.

Authentication Manager

So now we are finally at the authentication configuration. The authenticationManager in the authenticationProcessingFilter is a pluggable bean. Acegi comes with a variety of implementations. JasperReports Server by default authenticates against the metadata repository, so it uses a custom service which is part of the JasperReports Server API.

<bean class="org.acegisecurity.providers.ProviderManager"
      id="authenticationManager">
    <property name="providers">
        <list>
            <ref local="daoAuthenticationProvider" />
            <ref local="anonymousAuthenticationProvider" />
            <!-- ref local="jaasAuthenticationProvider"/ -->
        </list>
    </property>
</bean>
 
<bean class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"
      id="daoAuthenticationProvider">
    <!-- <property name="userDetailsService">
            <ref bean="inMemoryDaoImpl" />
         </property> -->
    <property name="userDetailsService">
        <ref bean="userAuthorityService"></ref>
    </property>
</bean>

The anonymousAuthenticationProvider allows anonymous access. In the above XML, you can have beans that provide alternative implementations of the authenticationProvider or userDetailsService, which looks up users.

External Authorization Strategies

The following is intended for JasperReports Server versions prior to v5.1. (See the attached JsperReports Server Authentication Cookbook, v4.0)

For v5.1 and on, please refer to The new JasperReports Server Authentication Cookbook v5.1 or JasperReports Server Authentication Cookbook v5.2 (HTML) (found in our Docs Area) for a comprehensive guide to implementing External Authorization using LDAP, CAS or external databases.

LDAP

<bean class="org.acegisecurity.providers.ldap.DefaultInitialDirContextFactory"
      id="initialDirContextFactory">
    <constructor-arg value="ldap://monkeymachine:389/dc=acegisecurity,dc=org" />
    <property name="managerDn">
        <value>cn=manager,dc=acegisecurity,dc=org</value>
    </property>
    <property name="managerPassword">
        <value>password</value>
    </property>
</bean>
 
<bean class="org.acegisecurity.providers.ldap.search.FilterBasedLdapUserSearch"
      id="userSearch">
    <constructor-arg index="0">
        <value />
    </constructor-arg>
    <constructor-arg index="1">
        <value>(uid={0})</value>
    </constructor-arg>
    <constructor-arg index="2">
        <ref local="initialDirContextFactory" />
    </constructor-arg>
    <property name="searchSubtree">
        <value>true</value>
    </property>
</bean>
 
<bean class="org.acegisecurity.providers.ldap.LdapAuthenticationProvider"
      id="ldapAuthProvider">
    <constructor-arg>
        <bean class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator">
            <constructor-arg>
                <ref local="initialDirContextFactory" />
            </constructor-arg>
            <property name="userDnPatterns">
                <list>
                    <value>uid={0},ou=people</value>
                </list>
            </property>
        </bean>
    </constructor-arg>
    <constructor-arg>
        <bean class="org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator">
            <constructor-arg>
                <ref local="initialDirContextFactory" />
            </constructor-arg>
            <constructor-arg>
                <value>ou=groups</value>
            </constructor-arg>
            <property name="groupRoleAttribute">
                <value>ou</value>
            </property>
        </bean>
    </constructor-arg>
</bean>
 
<!-- We would finally wire this into the authentication manager via: -->
 
<bean class="org.acegisecurity.providers.ProviderManager"
      id="authenticationManager">
    <property name="providers">
        <list>
            <ref local="ldapAuthProvider" />
            <ref local="anonymousAuthenticationProvider" />
        </list>
    </property>
</bean>

For full details, see: Acegi Security - LDAP authentication. There is a useful thread on the Spring forums that show LDAP authentication against Lotus Domino, Oracle Internet Directory 10g and Microsoft Active Directory - see LDAP directory integration on the Spring forums.

For More on LDAP and MS Active Directory

JAAS

<bean class="org.acegisecurity.providers.jaas.JaasAuthenticationProvider"
      id="jaasAuthenticationProvider">
    <property name="loginConfig">
        <value>/WEB-INF/login.conf</value>
    </property>
    <property name="loginContextName">
        <value>FileLogin</value>
    </property>
    <property name="callbackHandlers">
        <list>
            <bean class="org.acegisecurity.providers.jaas.JaasNameCallbackHandler" />
            <bean class="org.acegisecurity.providers.jaas.JaasPasswordCallbackHandler" />
        </list>
    </property>
    <property name="authorityGranters">
        <list>
            <bean class="org.appfuse.web.JaasAuthorityGranter" />
        </list>
    </property>
</bean>

See Also

Other Authentication Services

A variety of authentication providers come with Acegi, or are easily integrated:

Changing Database Passwords

You may want to change the database passwords used by JasperReports Server to connect to the repository.

References

Feedback