Jump to content
We've recently updated our Privacy Statement, available here ×
  • Configuring LDAP using HTTP Headers with the TIBCO JasperReports® Server 6.0 SSO Framework


    Steve Park
    • Version: v6, v6.0.1 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-60.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 TIBCO JasperReports® Server versions 6.x beginning with 6.0.1.  If you're planning to use JasperReports® Server 6.0.0 or earlier, the original version of this page is 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.web.authentication.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.core.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.ldap.userdetails.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.userdetails.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.web.authentication.preauth.RequestHeaderAuthenticationFilter">
        <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">
        <security:filter-chain-map path-type="ant" request-matcher="ant">
            <security:filter-chain pattern="/xmla" filters="httpSessionContextIntegrationFilter,${bean.loggingFilter},${bean.basicProcessingFilter},JIAuthenticationSynchronizer,${bean.diagnosticLoggingFilter},anonymousProcessingFilter,basicAuthExceptionTranslationFilter,filterInvocationInterceptor"/>
            <security:filter-chain pattern="/services/**" filters="httpSessionContextIntegrationFilter,${bean.loggingFilter},delegatingCASSingleSignOutFilter,delegatingPreAuthenticatedFilter,${bean.portletAuthenticationProcessingFilter},delegatingBasicProcessingFilter,${bean.passwordExpirationProcessingFilter},JIAuthenticationSynchronizer,${bean.diagnosticLoggingFilter},anonymousProcessingFilter,wsBasicAuthExceptionTranslationFilter,filterInvocationInterceptor"/>
            <security:filter-chain pattern="/rest/login" filters="httpSessionContextIntegrationFilter,${bean.loggingFilter}, encryptionFilter,delegatingCASSingleSignOutFilter,delegatingPreAuthenticatedFilter,delegatingAuthenticationRestProcessingFilter,JIAuthenticationSynchronizer,${bean.diagnosticLoggingFilter},anonymousProcessingFilter,filterInvocationInterceptor"/>
            <security:filter-chain pattern="/rest/**" filters="httpSessionContextIntegrationFilter,${bean.loggingFilter},delegatingCASSingleSignOutFilter,delegatingPreAuthenticatedFilter,${bean.portletAuthenticationProcessingFilter},delegatingBasicProcessingFilter,${bean.passwordExpirationProcessingFilter},JIAuthenticationSynchronizer,${bean.diagnosticLoggingFilter},anonymousProcessingFilter,wsBasicAuthExceptionTranslationFilter,filterInvocationInterceptor"/>
            <security:filter-chain pattern="/rest_v2/**" filters="httpSessionContextIntegrationFilter,encryptionFilter,delegatingCASSingleSignOutFilter,textOnlyResponseWebAppSecurityFilter,jsCsrfGuardFilter,${bean.loggingFilter},${bean.userPreferencesFilter},delegatingPreAuthenticatedFilter,${bean.authenticationProcessingFilter},${bean.userPreferencesFilter},delegatingBasicProcessingFilter,delegatingRequestParameterAuthenticationFilter,JIAuthenticationSynchronizer,${bean.diagnosticLoggingFilter},anonymousProcessingFilter,restExceptionTranslationFilter,filterInvocationInterceptor"/>
            <security:filter-chain pattern="/**" filters="httpSessionContextIntegrationFilter,requestAuthFilter,encryptionFilter,delegatingCASSingleSignOutFilter,multipartRequestWrapperFilter,webAppSecurityFilter,jsCsrfGuardFilter,${bean.loggingFilter},${bean.userPreferencesFilter},delegatingPreAuthenticatedFilter,delegatingAuthenticationProcessingFilter,${bean.userPreferencesFilter},delegatingBasicProcessingFilter,delegatingRequestParameterAuthenticationFilter,JIAuthenticationSynchronizer,${bean.diagnosticLoggingFilter},anonymousProcessingFilter,delegatingExceptionTranslationFilter,filterInvocationInterceptor,switchUserProcessingFilter,iPadSupportFilter"/>
        </security:filter-chain-map>
    </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-60.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.

    NOTE - Since headers are not passed for Studio connections, the initial primary login attempt via Studio will fail and the backup mechanism of SOAP will be used.  But in JasperReports Server version 7.1.0 SOAP is removed so Studio connections will no longer work with JasperReports Server 7.1.0 using the above approach.

    ji-ldap-sso-mt-60.zip


    User Feedback

    Recommended Comments

    We have used the same instructions above when we set up our JASPER 6.4 with SSO ( 99 % same instructions above, except some environmet related changes ) BUT now we have to upgrade to jasper 7.5 and when we brought the ldap-mt.xml file from old to new JASPER 7.5 and SSO and LDAP is no more working. Does anyone know the changes we need to make to JASPER 7.5 ? Any pointers will be appreciated. Thanks in advance

    Link to comment
    Share on other sites



    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...