Hi All,
I have successfully configured CAS integration with JasperServer 5.6.
CAS Configuration changes:
Step-1: Copied "applicationContext-externalAuth-CAS-db-mt.xml" file from samples and placed in "WEB-INF" directory with few changes.
<!-- ~ Copyright (C) 2005 - 2013 Jaspersoft Corporation. All rights reserved. ~ http://www.jaspersoft.com. ~ Licensed under commercial Jaspersoft Subscription License Agreement --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- - Sample configuration of SSO via CAS Spring API. - Additional user details are extracted via an external database (externalDataSource) - An organization id query is used to find the user's organization id. --> <bean id="proxyAuthenticationProcessingFilter" class="com.jaspersoft.jasperserver.api.security.externalAuth.cas.JSCasProcessingFilter"> <property name="authenticationManager"> <ref local="casAuthenticationManager"/> </property> <property name="externalDataSynchronizer"> <ref local="externalDataSynchronizer"/> </property> <property name="sessionRegistry"> <ref bean="sessionRegistry"/> </property> <property name="internalAuthenticationFailureUrl" value="/login.html?error=1"/> <property name="defaultTargetUrl" value="/loginsuccess.html"/> <property name="invalidateSessionOnSuccessfulAuthentication" value="true"/> <property name="migrateInvalidatedSessionAttributes" value="true"/> <property name="filterProcessesUrl" value="/j_spring_security_check"/> <property name="authenticationDetailsSource"> <bean class="org.springframework.security.ui.AuthenticationDetailsSourceImpl"> <property name="clazz"> <value>com.jaspersoft.jasperserver.multipleTenancy.MTWebAuthenticationDetails</value> </property> </bean> </property> </bean> <bean id="proxyAuthenticationSoapProcessingFilter" class="com.jaspersoft.jasperserver.api.security.externalAuth.cas.JSSoapProcessingFilter"> <property name="authenticationManager" ref="casSoapAuthenticationManager"/> <property name="externalDataSynchronizer" ref="externalDataSynchronizer"/> <property name="invalidateSessionOnSuccessfulAuthentication" value="true"/> <property name="migrateInvalidatedSessionAttributes" value="true"/> <property name="filterProcessesUrl" value="/services"/> </bean> <bean id="proxyAuthenticationRestProcessingFilter" class="com.jaspersoft.jasperserver.api.security.externalAuth.cas.CasRestProcessingFilter"> <property name="authenticationManager" ref="casRestAuthenticationManager"/> <property name="externalDataSynchronizer" ref="externalDataSynchronizer"/> <property name="filterProcessesUrl" value="/rest/login"/> <property name="invalidateSessionOnSuccessfulAuthentication" value="true"/> <property name="migrateInvalidatedSessionAttributes" value="true"/> </bean> <bean id="proxyExceptionTranslationFilter" class="org.springframework.security.ui.ExceptionTranslationFilter" depends-on="externalAuthProperties"> <property name="authenticationEntryPoint"> <bean class="org.springframework.security.ui.cas.CasProcessingFilterEntryPoint"> <property name="loginUrl" value="#{externalAuthProperties.externalLoginUrl}"/> <property name="serviceProperties"> <ref local="casServiceProperties"/> </property> </bean> </property> <property name="accessDeniedHandler"> <bean class="com.jaspersoft.jasperserver.war.themes.ThemeAwareAccessDeniedHandlerImpl"> <property name="errorPage" value="/WEB-INF/jsp/modules/system/AccessDeniedPage.jsp"/> <property name="themeResolver" ref="themeResolver" /> <property name="themeSource" ref="themeSource" /> </bean> </property> </bean> <bean id="casAuthenticationManager" class="org.springframework.security.providers.ProviderManager"> <property name="providers"> <list> <ref local="casAuthenticationProvider"/> <ref bean="${bean.daoAuthenticationProvider}"/> <!-- anonymousAuthenticationProvider only needed if filterInvocationInterceptor.alwaysReauthenticate is set to true--> <ref bean="anonymousAuthenticationProvider"/> </list> </property> </bean> <bean id="casRestAuthenticationManager" class="org.springframework.security.providers.ProviderManager"> <property name="providers"> <list> <ref local="casRestAuthenticationProvider"/> <ref bean="${bean.daoAuthenticationProvider}"/> <!-- anonymousAuthenticationProvider only needed if filterInvocationInterceptor.alwaysReauthenticate is set to true--> <!--<ref bean="anonymousAuthenticationProvider"/>--> </list> </property> </bean> <bean id="casSoapAuthenticationManager" class="org.springframework.security.providers.ProviderManager"> <property name="providers"> <list> <ref local="casSoapAuthenticationProvider"/> <ref bean="${bean.daoAuthenticationProvider}"/> <!-- anonymousAuthenticationProvider only needed if filterInvocationInterceptor.alwaysReauthenticate is set to true--> <!--<ref bean="anonymousAuthenticationProvider"/>--> </list> </property> </bean> <bean id="casAuthenticationProvider" class="org.springframework.security.providers.cas.CasAuthenticationProvider" depends-on="externalAuthProperties"> <property name="userDetailsService"><ref local="casJDBCUserDetailsService"/></property> <property name="serviceProperties"> <ref local="casServiceProperties"/> </property> <property name="ticketValidator"> <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator"> <constructor-arg index="0" value="#{externalAuthProperties.ssoServerLocation}" /> </bean> </property> <property name="statelessTicketCache"> <bean class="org.springframework.security.providers.cas.cache.EhCacheBasedTicketCache"> <property name="cache"> <bean id="ticketCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager" ref="cacheManager"/> <property name="cacheName" value="casTicketCache"/> </bean> </property> </bean> </property> <property name="key" value="casCacheKey"/> </bean> <bean id="casRestAuthenticationProvider" class="org.springframework.security.providers.cas.CasAuthenticationProvider" depends-on="externalAuthProperties"> <property name="userDetailsService"><ref local="casJDBCUserDetailsService"/></property> <property name="serviceProperties"> <ref local="casRestServiceProperties"/> </property> <property name="ticketValidator"> <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator"> <constructor-arg index="0" value="#{externalAuthProperties.ssoServerLocation}" /> </bean> </property> <property name="statelessTicketCache"> <bean class="org.springframework.security.providers.cas.cache.EhCacheBasedTicketCache"> <property name="cache"> <bean id="ticketCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager" ref="cacheManager"/> <property name="cacheName" value="casTicketCache"/> </bean> </property> </bean> </property> <property name="key" value="casCacheKey"/> </bean> <bean id="casSoapAuthenticationProvider" class="org.springframework.security.providers.cas.CasAuthenticationProvider" depends-on="externalAuthProperties"> <property name="userDetailsService"><ref local="casJDBCUserDetailsService"/></property> <property name="serviceProperties"> <ref local="casSoapServiceProperties"/> </property> <property name="ticketValidator"> <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator"> <constructor-arg index="0" value="#{externalAuthProperties.ssoServerLocation}" /> </bean> </property> <property name="statelessTicketCache"> <bean class="org.springframework.security.providers.cas.cache.EhCacheBasedTicketCache"> <property name="cache"> <bean id="ticketCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager" ref="cacheManager"/> <property name="cacheName" value="casTicketCache"/> </bean> </property> </bean> </property> <property name="key" value="casCacheKey"/> </bean> <bean id="casJDBCUserDetailsService" class="com.jaspersoft.jasperserver.api.security.externalAuth.cas.CasJDBCUserDetailsService"> <property name="dataSource" ref="externalDataSource"/> <property name="usersByUsernameQuery" value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"/> <property name="authoritiesByUsernameQuery" value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"/> <property name="detailsQuery" value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"/> </bean> <bean id="casServiceProperties" class="org.springframework.security.ui.cas.ServiceProperties"> <property name="service" value="http://myserver:8080/kpi-server/j_spring_security_check"/> <property name="sendRenew" value="false"/> </bean> <!--we rely on the customer coming with a ticket that was issued to their system. this is where they need to specify the url--> <bean id="casRestServiceProperties" class="org.springframework.security.ui.cas.ServiceProperties"> <property name="service" value="http://myserver:8080/kpi-server/rest/login"/> <property name="sendRenew" value="false"/> </bean> <bean id="casSoapServiceProperties" class="org.springframework.security.ui.cas.ServiceProperties"> <property name="service" value="http://myserver:8080/kpi-server/services"/> <property name="sendRenew" value="false"/> </bean> <!-- ############ SSO auth ############ --> <!-- ############ Synchronizer ############ --> <bean id="externalDataSynchronizer" class="com.jaspersoft.jasperserver.api.security.externalAuth.ExternalDataSynchronizerImpl"> <property name="externalUserDetailsService"> <ref local="casJDBCUserDetailsService"/> </property> <property name="externalUserProcessors"> <list> <!--<ref local="externalTenantSetupProcessor"/>--> <ref local="mtExternalUserSetupProcessor"/> <!-- Example processor for creating user folder--> <!--<ref local="externalUserFolderProcessor"/>--> </list> </property> </bean> <bean id="abstractExternalProcessor" class="com.jaspersoft.jasperserver.api.security.externalAuth.processors.AbstractExternalUserProcessor" abstract="true"> <property name="repositoryService" ref="${bean.repositoryService}"/> <property name="userAuthorityService" ref="${bean.userAuthorityService}"/> <property name="tenantService" ref="${bean.tenantService}"/> <property name="profileAttributeService" ref="profileAttributeService"/> <property name="objectPermissionService" ref="objectPermissionService"/> </bean> <bean id="externalTenantSetupProcessor" class="com.jaspersoft.jasperserver.multipleTenancy.security.externalAuth.processors.MTExternalTenantSetupProcessor" parent="abstractExternalProcessor"> <property name="multiTenancyService"><ref bean="internalMultiTenancyService"/></property> <!--<property name="tenantIdNotSupportedSymbols" value="#{configurationBean.tenantIdNotSupportedSymbols}"/>--> <property name="defaultOrganization" value="organizations"/> </bean> <bean id="mtExternalUserSetupProcessor" class="com.jaspersoft.jasperserver.multipleTenancy.security.externalAuth.processors.MTExternalUserSetupProcessor" parent="abstractExternalProcessor"> <!--Default permitted role characters; others are removed. Change regular expression to allow other chars.--> <!--<property name="permittedExternalRoleNameRegex" value="[A-Za-z0-9_]+"/>--> <property name="organizationRoleMap"> <map> <!-- Example of mapping customer roles to JRS roles --> <!-- <entry> <key> <value>ROLE_ADMIN_EXTERNAL_ORGANIZATION</value> </key>--> <!-- JRS role that the <key> external role is mapped to--> <!--<value>ROLE_ADMINISTRATOR</value>--> <!-- <value>ROLE_ADMINISTRATOR|*</value> </entry>--> </map> </property> <property name="userAuthorityService"> <ref bean="${bean.internalUserAuthorityService}"/> </property> <!-- If the username is in adminUsernames list assign the user internal roles from defaultAdminRoles; - otherwise, assign the user all the roles from defaultInternalRoles list. --> <property name="adminUsernames"> <list> <value>myorgadmin</value> </list> </property> <property name="defaultAdminRoles"> <list> <value>ROLE_USER</value> <value>ROLE_ADMINISTRATOR</value> </list> </property> <property name="defaultInternalRoles"> <list> <value>ROLE_USER</value> <value>ROLE_ADMINISTRATOR</value> </list> </property> <property name="externalAuthProperties" ><ref local="externalAuthProperties"/></property> </bean> <!-- EXAMPLE Processor <bean id="externalUserFolderProcessor" class="com.jaspersoft.jasperserver.api.security.externalAuth.processors.ExternalUserFolderProcessor" parent="abstractExternalProcessor"> <property name="repositoryService" ref="${bean.unsecureRepositoryService}"/> </bean> --> <!-- ############ Synchronizer ############ --> <!-- ############## external dataSource: config in master.properties ############### --> <bean id="externalDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${external.jdbc.driverClassName}"/> <property name="url" value="${external.jdbc.url}"/> <property name="username" value="${external.jdbc.username}"/> <property name="password" value="${external.jdbc.password}"/> </bean> <!-- ############## external dataSource ############### --> <bean id="externalAuthProperties" class="com.jaspersoft.jasperserver.api.security.externalAuth.ExternalAuthProperties"> <property name="externalLoginUrl" value="https://myserver:8443/snd-sso/login"/> <!-- external logout url. If specified, logout will redirect to that address. --> <property name="logoutUrl" value="https://myserver:8443/snd-sso/logout"/> <property name="ssoServerLocation" value="https://myserver:8443/snd-sso"/> </bean></beans>
Step-2: Minimal changes on "applicationContext-security-web.xml" file in "WEB-INF" directory
<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},delegatingPreAuthenticatedFilter,${bean.portletAuthenticationProcessingFilter},delegatingBasicProcessingFilter,${bean.passwordExpirationProcessingFilter},JIAuthenticationSynchronizer,anonymousProcessingFilter,wsBasicAuthExceptionTranslationFilter,filterInvocationInterceptor
/rest/login=httpSessionContextIntegrationFilter,${bean.loggingFilter}, encryptionFilter,delegatingPreAuthenticatedFilter,delegatingAuthenticationRestProcessingFilter,JIAuthenticationSynchronizer,anonymousProcessingFilter,filterInvocationInterceptor
/rest/**=httpSessionContextIntegrationFilter,${bean.loggingFilter},delegatingPreAuthenticatedFilter,delegatingAuthenticationRestProcessingFilter,${bean.portletAuthenticationProcessingFilter},delegatingBasicProcessingFilter,${bean.passwordExpirationProcessingFilter},JIAuthenticationSynchronizer,anonymousProcessingFilter,wsBasicAuthExceptionTranslationFilter,filterInvocationInterceptor
/rest_v2/**=httpSessionContextIntegrationFilter,encryptionFilter,textOnlyResponseWebAppSecurityFilter,jsCsrfGuardFilter,${bean.loggingFilter},${bean.userPreferencesFilter},delegatingPreAuthenticatedFilter,delegatingAuthenticationRestProcessingFilter,${bean.userPreferencesFilter},delegatingBasicProcessingFilter,delegatingRequestParameterAuthenticationFilter,JIAuthenticationSynchronizer,anonymousProcessingFilter,restExceptionTranslationFilter,filterInvocationInterceptor
/j_spring_security_check=httpSessionContextIntegrationFilter,delegatingAuthenticationProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
/**=httpSessionContextIntegrationFilter,encryptionFilter,multipartRequestWrapperFilter,webAppSecurityFilter,jsCsrfGuardFilter,${bean.loggingFilter},${bean.userPreferencesFilter},delegatingPreAuthenticatedFilter,delegatingAuthenticationProcessingFilter,${bean.userPreferencesFilter},delegatingBasicProcessingFilter,delegatingRequestParameterAuthenticationFilter,JIAuthenticationSynchronizer,anonymousProcessingFilter,delegatingExceptionTranslationFilter,filterInvocationInterceptor,switchUserProcessingFilter,iPadSupportFilter
</value>
</property>
</bean>
Step-4: Restart jasperserver, with the above changes, CAS working successfully.
Now I have a small problem, while autheticating with "visualize.js".
Exaplantion:
Step-1: Visualize.js integration, to get the available resources from jasperserver [resource type : "adhocDataview"]
visualize({ auth: { token : ticket }},function(v){ alert("Authentication Success ...!"); v.resourcesSearch({ folderUri:'/public/Samples/Ad_Hoc_Views/', recursive:true, success:listRepository, types: ["adhocDataView"], error:function (err) { alert(err); } }); }, function(err){ alert(err.message); });
In the above code, "ticket" parameter passing dynamically from the application.
Step-2: While Accessing from client side, it was invoking following code in the "visualize.js"
var JrsAuthenticationExecutor = { login: function(properties, request){ var dfd = $.Deferred(); request({ url: properties.url + "/j_spring_security_check?forceDefaultRedirect=true&" + getParametersString(properties) }).done(function (result, a, b) { if (b.getResponseHeader("LoginRequested")) { dfd.reject(b); } else { dfd.resolve(result); } }).fail(function (xhr) { dfd.reject(xhr); }); return dfd; }, logout: function(properties, request){ return request({ url: properties.url + "/logout.html" }); } };
After executing above code, I am getting authetication error.
I think you people understand the configuration, what i have done. So kindly suggest me for the visualize.js integartion for token based authetication.
Note:
I am working on jasperserver since 2013, with in few days I am planning post my R &D points for the community people.
Related points:
- Ad hoc view design with domain & topic
- Jasper server Internationalization
- Russian Langauge support for Jasperserver
- Embedding JasperServer in External Application
- External DB authetication for jasperserver
- Parameter passing from external Application domin level as well as topic level
- Basic Examples in visualize.js
- CAS integartion with jasperserver
- Few more...
Thanks & Regards,
Nagesh.
0 Answers:
No answers yet