Jump to content
  • Configuring LDAP using HTTP Headers with the JasperReports Server 5.1 SSO Framework


    Steve Park
    • Version: v6.0.0, v5 Product: JasperReports® Server

    [toc on_off::hide=1]

    IMPORTANT:  This is community-contributed content and is not supported by TIBCO Analytics.  It is provided as-is with no express or implied warranties of any kind.  The source code is included in the ji-ldap-sso-mt.zip file and may be modified to meet your business requirements.  By doing so, however, the end consumer assumes all liabilities and responsibilities for modifying the code.

    IMPORTANT:  This configuration has been tested and verified on JasperReports Server through version 6.0.0.  If you're planning to use JasperReports Server 6.0.1 or newer, there's a new version of this page available here.

    Normally, one would use the sample-applicationContext-externalAuth-ldap[-mt].xml as the basis to configure LDAP integration with JasperReports Server.  Once configured, end users would be able to login to JasperReports Server using their LDAP credentials, but they would still see the login screen even if they were being redirected from a third party application.

    In order to bypass the login screen and authenticate via HTTP headers, some additional beans need to be defined and configured in the sample-applicationContext-externalAuth-ldap[-mt].xml file.  A sample configuration for these beans are as follows:

    <!-- This pre-authentication header will handle LDAP authentication using a request header -->
    <bean id="preAuthProvider" class="org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider">
        <property name="preAuthenticatedUserDetailsService"><ref local="wrappedUserDetailsService"/></property>
        <property name="throwExceptionWhenTokenRejected" value="true"/>
    </bean>
    
    <!-- This wrapped user details service is used by the preauth provider defined above and provides a hook into the LdapUserDetails Service -->
    <bean id="wrappedUserDetailsService" class="org.springframework.security.userdetails.UserDetailsByNameServiceWrapper">
        <property name="userDetailsService"><ref local="ldapUserDetailsService"/></property>
    </bean>
    
    <!-- This LdapUserDetailsService creates UserDetails objects using the userSearch and ldapAuthoritiesPopulator beans -->
    <bean id="ldapUserDetailsService" class="org.springframework.security.userdetails.ldap.LdapUserDetailsService">
        <constructor-arg index="0">
            <ref local="userSearch" />
        </constructor-arg>
        <constructor-arg index="1">
            <ref local="ldapAuthPopulator" />
        </constructor-arg>
    </bean>
    
    <!-- This authorities populator bean retrieves roles automatically from the LDAP server -->
    <bean id="ldapAuthPopulator" class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
        <constructor-arg index="0">
            <ref local="ldapContextSource" />
        </constructor-arg>
        <constructor-arg index="1">
            <value></value>
        </constructor-arg>
        <property name="groupRoleAttribute">
            <value>cn</value>
        </property>
        <property name="searchSubtree">
            <value>true</value>
        </property>
    </bean>
    
    <!-- This filter will be added to the wildcard filter chain to intercept the request headers and pass them to the authentication manager -->
    <bean id="requestAuthFilter" class="org.springframework.security.ui.preauth.header.RequestHeaderPreAuthenticatedProcessingFilter">
        <property name="principalRequestHeader" value="uname"/>
        <property name="credentialsRequestHeader" value="upass"/>
        <property name="authenticationManager" ref="ldapAuthenticationManager"/>
    </bean> 
    

    Additionally, you'll need to add the preAuthProvider bean to the list of provider beans in the ldapAuthenticationManager bean:

    <bean id="ldapAuthenticationManager" class="org.springframework.security.providers.ProviderManager">
        <property name="providers">
            <list>
                <ref local="preAuthProvider"/>
                <ref local="ldapAuthenticationProvider"/>
                <ref bean="${bean.daoAuthenticationProvider}"/>
                <!--anonymousAuthenticationProvider only needed if filterInvocationInterceptor.alwaysReauthenticate is set to true
                <ref bean="anonymousAuthenticationProvider"/>-->
            </list>
        </property>
    </bean>

    Once these changes are made, copy the sample-applicationContext-externalAuth-LDAP[-mt].xml file to the <jasperserver[-pro]>/WEB-INF folder and rename the file to applicationContext-externalAuth-LDAP[-mt].xml.  Additionally, the requestAuthFilter bean will need to be defined and configured in the WEB-INF/applicationContext-security-web.xml file. This bean will need to be added to the wildcard (/**) filter chain in the filterChainProxy bean immediately after the httpSessionContextIntegrationFilter bean:

    <bean id="filterChainProxy" class="org.springframework.security.util.FilterChainProxy">
        <property name="filterInvocationDefinitionSource">
            <value>
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                PATTERN_TYPE_APACHE_ANT
                /xmla=httpSessionContextIntegrationFilter,${bean.loggingFilter},${bean.basicProcessingFilter},JIAuthenticationSynchronizer,anonymousProcessingFilter,basicAuthExceptionTranslationFilter,filterInvocationInterceptor
                /services/**=httpSessionContextIntegrationFilter,${bean.loggingFilter},${bean.portletAuthenticationProcessingFilter}, delegatingBasicProcessingFilter,${bean.passwordExpirationProcessingFilter},JIAuthenticationSynchronizer,anonymousProcessingFilter,wsBasicAuthExceptionTranslationFilter,filterInvocationInterceptor
                /rest/login=httpSessionContextIntegrationFilter,${bean.loggingFilter}, encryptionFilter,delegatingAuthenticationRestProcessingFilter,JIAuthenticationSynchronizer,anonymousProcessingFilter,filterInvocationInterceptor
                /rest/**=httpSessionContextIntegrationFilter,${bean.loggingFilter},${bean.portletAuthenticationProcessingFilter},delegatingBasicProcessingFilter,${bean.passwordExpirationProcessingFilter},JIAuthenticationSynchronizer,anonymousProcessingFilter,wsBasicAuthExceptionTranslationFilter,filterInvocationInterceptor
                /rest_v2/**=httpSessionContextIntegrationFilter,encryptionFilter,textOnlyResponseWebAppSecurityFilter,jsCsrfGuardFilter,${bean.loggingFilter},${bean.userPreferencesFilter},${bean.authenticationProcessingFilter},${bean.userPreferencesFilter},delegatingBasicProcessingFilter,delegatingRequestParameterAuthenticationFilter,JIAuthenticationSynchronizer,anonymousProcessingFilter,restExceptionTranslationFilter,filterInvocationInterceptor
                /**=httpSessionContextIntegrationFilter,requestAuthFilter,encryptionFilter,multipartRequestWrapperFilter,webAppSecurityFilter,jsCsrfGuardFilter,${bean.loggingFilter},${bean.userPreferencesFilter},delegatingAuthenticationProcessingFilter,${bean.userPreferencesFilter},delegatingBasicProcessingFilter,delegatingRequestParameterAuthenticationFilter,JIAuthenticationSynchronizer,anonymousProcessingFilter,delegatingExceptionTranslationFilter,filterInvocationInterceptor,switchUserProcessingFilter,iPadSupportFilter
            </value>
        </property>
    </bean>
    

    The principalRequestHeader and credentialsRequestHeader property values can be renamed to match any existing HTTP headers generated by your application.

    Multi-tenancy Only

    To use these filters in a multi-tenant environment, you will need the following jar file:

    ji-ldap-sso-mt.zip

    Download and unzip this jar file and copy it to your <jasperserver-pro>/WEB-INF/lib folder.  Then make the following changes to the following beans as shown below:

     <!-- This wrapped user details service is used by the preauth provider defined above and provides a hook into the LdapUserDetails Service -->
     <bean id="wrappedUserDetailsService" class="com.jaspersoft.jasperserver.multipleTenancy.MTUserDetailsByNameServiceWrapper">
         <property name="userDetailsService"><ref bean="ldapUserDetailsService"/></property>
         <property name="tenantService"><ref bean="${bean.hibernateTenantService}"/></property>
     </bean>
    
     <!-- This LdapUserDetailsService creates UserDetails objects using the userSearch and ldapAuthoritiesPopulator beans -->
     <bean id="ldapUserDetailsService" class="com.jaspersoft.jasperserver.multipleTenancy.MTLdapUserDetailsService">
         <constructor-arg index="0">
             <ref local="userSearch" />
         </constructor-arg>
         <constructor-arg index="1">
             <ref local="ldapAuthPopulator" />
         </constructor-arg>
         <property name="ldapExternalTenantProcessor"><ref local="ldapExternalTenantProcessor"/></property>
     </bean>
    
     <!-- This filter will be added to the wildcard filter chain to intercept the request headers and pass them to the authentication manager -->
     <bean id="requestAuthFilter" class="com.jaspersoft.jasperserver.multipleTenancy.security.externalAuth.processors.ldap.MTRequestHeaderPreAuthenticatedProcessingFilter">
         <property name="principalRequestHeader" value="uname"/>
         <property name="credentialsRequestHeader" value="upass"/>
         <property name="authenticationManager" ref="ldapAuthenticationManager"/>
         <property name="externalDataSynchronizer" ref="externalDataSynchronizer"/>
     </bean>
    

    Testing

    To test this setup, install the Mozilla Firefox browser and install the Modify Headers plugin. To install this plugin, click the Tools > Add-ons menu, click the Get Add-ons tab, and search for the Modify Headers plugin.

    Once the plugin is installed, perform the following steps:

    1. Click the Firefox menu and select Web Developer > Modify Headers.
    2. Click the Select Action button at the top of the dialog box and choose Add.
    3. In the Header Name text field, type uname.
    4. In the Header Value text field, type a username in your LDAP directory.
    5. Click the Add button.
    6. Click the Select Action button again and choose Add.
    7. In the Header Name text field, type upass.
    8. In the Header Value text field, type the password for the user specified in step 4.
    9. Click the Add button.
    10. Click OK to close the dialog box.
    11. In Firefox, navigate to http://localhost:8080/jasperserver-pro.

    Result: 

    The standard landing screen appears instead of the login screen.


    User Feedback

    Recommended Comments

    There are no comments to display.



    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

×
×
  • Create New...