Spring MVC ThemeChangeInterceptor do not change theme - spring

I am stuck at something really painful.
I am trying to use the theming of Spring WebMVC.
This is the end of my web-context.xml file :
<beans:bean id="themeChangeInterceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" >
<beans:property name="paramName" value="theme" />
</beans:bean>
<beans:bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource">
<beans:property name="basenamePrefix" value="theme-" />
</beans:bean>
<beans:bean id="themeResolver" class="org.springframework.web.servlet.theme.CookieThemeResolver" >
<beans:property name="defaultThemeName" value="default" />
</beans:bean>
<beans:bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<beans:property name="interceptors">
<beans:list>
<beans:ref bean="themeChangeInterceptor" />
</beans:list>
</beans:property>
</beans:bean>
In my header file, I have something like :
<span style="float: right">
Default
|
Other
</span>
And to finish, my html head has (imported in all views) :
<link rel="stylesheet" href="<spring:theme code="css"/>" type="text/css" />
I got the two properties files in src/main/resources, which leads to my css. For example in theme-default.properties, there is :
css=static/css/dev.css
My css are in src/webapp/static/css/.
When I load the website for the first time, the theme is default, so I think that the property files and the css are correctly found by the Theme resolver.
But when I click on Default or Other in the header, nothing happens.
Do you know where the problem is ?
Thank you very much beforehand !
Olivier.

I think you are registering the interceptor wrongly. If you are configuring Spring-MVC by using <mvc:annotation-driven/> then having a separate handlerMapping will not work as a default handlerMapping is register by the custom mvc namespace also. Try registering it this way instead:
<mvc:interceptors>
<ref bean="themeChangeInterceptor"/>
</mvc:interceptors>

You should have <mvc:interceptors> declaration. And your ThemeChangeInterceptor bean should be there
<mvc:interceptors>
<beans:bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang" />
</beans:bean>
<beans:bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
<beans:property name="paramName" value="theme" />
</beans:bean>
</mvc:interceptors>

Related

How to implement two different spring security authentication from same login form

I have a requirement that on the login page I have a userId , password field and also another text entry field called customer. If a user logins in with userId and password , the spring-security configuration which I have works good.
Second login scenario is If the customer puts in only their customer Id , they are supposed to login to a different page as well. How do I make the two different logins works with the same spring-security xml configuration from the same login page.
<security:http auto-config="true" use-expressions="true" >
<!-- URL restrictions (order is important!) Most specific matches should be at top -->
<!-- Don't set any role restrictions on login.jsp. Any requests for the login page should be available for anonymous users -->
<security:intercept-url pattern="/login.jsp*" access="isAuthenticated()" />
<security:access-denied-handler error-page="/noaccess.jsp" />
<security:intercept-url pattern="/board.htm" access="hasRole('ROLE_ALL_USER')" />
<security:intercept-url pattern="/AddItems.htm*" access="hasRole('ROLE_USER')" />
<!-- Set the login page and what to do if login fails -->
<security:form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1" />
<!-- Set the logout page and where to go after logout is successful -->
<security:logout logout-url="/logout" logout-success-url="/logoutSuccess.jsp" />
<security:custom-filter position="PRE_AUTH_FILTER" ref="customPreAuthFilter" />
<security:custom-filter ref="switchUserFilter" position="SWITCH_USER_FILTER" />
</security:http>
<security:http>
</security:http>
<beans:bean id="customPreAuthFilter" class="org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="preauthAuthProvider" />
</security:authentication-manager>
<!-- Load the UserDetails object for the user. -->
<beans:bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<beans:property name="preAuthenticatedUserDetailsService">
<beans:bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<beans:property name="userDetailsService" ref="currentUserDetailsService"/>
</beans:bean>
</beans:property>
</beans:bean>
<!-- Aliasing (Switch User) -->
<beans:bean id="switchUserFilter" class="org.springframework.security.web.authentication.switchuser.SwitchUserFilter">
<beans:property name="userDetailsService" ref="currentUserDetailsService" />
</beans:bean>
Thanks
Dhiren
#Ritesh Thanks for the link.. I tried your solution but My Filter does not get invoked.
does web.xml need to be modified.
Any way I tried to implement the entire springSecurityFilterChain but still I have not able to invoke my Filter from my login form. My filter that I need invoked is customBadgeAuthFilter
<beans:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<beans:constructor-arg>
<beans:list>
<security:filter-chain pattern="/resources/**" filters="none"/>
<security:filter-chain pattern="/**"
filters="securityContextPersistenceFilterWithASCTrue,
logoutFilter,
customBadgeAuthFilter,
formLoginFilter,
formLoginExceptionTranslationFilter,
filterSecurityInterceptor" />
</beans:list>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="securityContextPersistenceFilterWithASCTrue"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<beans:constructor-arg>
<beans:bean class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="formLoginExceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:constructor-arg value="/login"/>
</beans:bean>
</beans:constructor-arg>
<beans:property name="accessDeniedHandler">
<beans:bean
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<beans:property name="errorPage" value="/exception" />
</beans:bean>
</beans:property>
</beans:bean>
<beans:bean id="formLoginFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="allowSessionCreation" value="true"/>
<beans:property name="authenticationSuccessHandler">
<beans:bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<beans:constructor-arg value="/"/>
<beans:property name="alwaysUseDefaultTargetUrl" value="true"/>
</beans:bean>
</beans:property>
<beans:property name="authenticationFailureHandler">
<beans:bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:constructor-arg value="/login?error=true"/>
</beans:bean>
</beans:property>
</beans:bean>
<beans:bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="accessDecisionManager" ref="accessDecisionManager" />
<beans:property name="runAsManager" ref="runAsManager" />
<beans:property name="securityMetadataSource">
<security:filter-security-metadata-source use-expressions="true">
<security:intercept-url pattern="/**"
access="isAuthenticated()" />
</security:filter-security-metadata-source>
</beans:property>
</beans:bean>
<beans:bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.access.vote.RoleVoter"/>
<beans:bean class="org.springframework.security.web.access.expression.WebExpressionVoter"/>
</beans:list>
</beans:constructor-arg>
<beans:property name="allowIfAllAbstainDecisions" value="false"/>
</beans:bean>
<beans:bean id="runAsManager"
class="org.springframework.security.access.intercept.RunAsManagerImpl">
<beans:property name="key" value="TELCO_RUN_AS"/>
</beans:bean>
<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg value="/login"/>
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler">
<beans:constructor-arg>
<beans:list>
<beans:value>JSESSIONID</beans:value>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="customBadgeAuthFilter" class="com.company.security.filter.BadgeProcessingSecurityFilter">
<beans:constructor-arg value="/login.jsp"></beans:constructor-arg>
<beans:property name="authenticationManager" ref="authManager" />
</beans:bean>
<security:authentication-manager alias="authManager" >
<security:authentication-provider ref='normalAuthenticationProvider ' />
<security:authentication-provider ref='badgeAuthenticationProvider ' />
<security:authentication-provider ref="preauthAuthProvider" />
</security:authentication-manager>
<beans:bean id="loginUrlAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.jsp"/>
</beans:bean>
<beans:bean id="badgeAuthenticationProvider" class="com.company.security.filter.BadgeAuthenticationProvider">
</beans:bean>
I think I finally figured how to get my securityFilter to get invoked.
I was doing debugging to see the springsecurity flow and see that there is a method called. requestAuthorization in the subclass of AbstractAuthenticationProcessingFilter. It compares the uri which is configured for the default value for the filter to get invoked and if they don't match the filter is bypassed. For some reason even thought the POSt request is /j_security_check .. it transforms into FSS/home.htm when it is being compared and so the filter was getting bypassed.

How to add X-Frame-Options to just some responses in Spring Security 3.2

I would like to add X-Frame-Options header to all but some pages in my Spring application. Spring Security 3.2 offers nice capability to add that header to all responses via <headers> <frame-options /> </headers> configuration.
But could it be possible to exclude this header from some paths? I considered subclassing XFrameOptionsHeaderWriter and do some path regexp matching inside, but it seems a bit ugly. Maybe there is more convenient way to accomplish this?
I found out how to do it with XML configuration:
<http>
<headers>
<header ref="xFrameOptionsHeaderWriter" />
</headers>
</http>
<beans:bean id="xFrameOptionsHeaderWriter" class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
<!-- Argument 1: RequestMatcher. This matcher will match all but some paths. -->
<beans:constructor-arg>
<beans:bean class="org.springframework.security.web.util.matcher.NegatedRequestMatcher">
<beans:constructor-arg>
<beans:bean class="org.springframework.security.web.util.matcher.OrRequestMatcher">
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher" c:pattern="/**/some-path/**" />
<beans:bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher" c:pattern="/**/another-path/**" />
</beans:list>
</beans:constructor-arg>
</beans:bean>
</beans:constructor-arg>
</beans:bean>
</beans:constructor-arg>
<!-- Argument 2: HeaderWriter -->
<beans:constructor-arg>
<beans:bean class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter" c:frameOptionsMode="SAMEORIGIN" />
</beans:constructor-arg>
</beans:bean>

Why isn't hibernate creating my tables from hbm.xmls?

I have several .hbm.xml mapping files set up in Spring, and I can tell from the logs that Spring sees them and does something with them, but no tables are created in the DB.
Bean setup:
<beans:bean id="dataSourceEmbedded" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="org.h2.Driver" />
<beans:property name="url" value="jdbc:h2:~/myDbName" />
<beans:property name="username" value="sa" />
<beans:property name="password" value="" />
</beans:bean>
<beans:bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
p:dataSource-ref="dataSourceEmbedded">
<beans:property name="mappingLocations">
<beans:list>
<beans:value>classpath:path/to/schemas/Page.hbm.xml</beans:value>
<beans:value>classpath:path/to/schemas/Navigation.hbm.xml</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:value>
hibernate.show_sql=true
hibernate.dialect=${hibernate.dialect}
hibernate.hbmToDdlAuto=create
</beans:value>
</beans:property>
</beans:bean>
I know that the path to the Page and Navigation mapping files is correct - an error is thrown if it's not, and I can see the fields being mapped during the tomcat startup:
DEBUG: org.hibernate.cfg.Configuration - Processing hbm.xml files
INFO : org.hibernate.cfg.HbmBinder - Mapping class: Page -> pages
DEBUG: org.hibernate.cfg.HbmBinder - Mapped property: Page ID -> pageid
DEBUG: org.hibernate.cfg.HbmBinder - Mapped property: title -> title
Similarly, the database is clearly accessed / locked while tomcat is loading, so something is happening in there! But once it's loaded and I try to query it or inspect it, no tables exist.
Question: Why aren't my tables being created / what have I done wrong?
The property you used is wrong, it should be 'hibernate.hbm2ddl.auto' instead of 'hibernate.hbmToDdlAuto'... However instead of that you can also set the schemaUpdate property of the LocalSessionFactoryBean.
<beans:bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
p:dataSource-ref="dataSourceEmbedded">
<beans:property name="mappingLocations">
<beans:list>
<beans:value>classpath:path/to/schemas/Page.hbm.xml</beans:value>
<beans:value>classpath:path/to/schemas/Navigation.hbm.xml</beans:value>
</beans:list>
</beans:property>
<beans:property name="schemaUpdate" value="true" />
<beans:property name="hibernateProperties">
<beans:value>
hibernate.show_sql=true
hibernate.dialect=${hibernate.dialect}
</beans:value>
</beans:property>
</beans:bean>
Related answer/info: Hibernate hbm2ddl.auto possible values and what they do?
Correct property name is hibernate.hbm2ddl.auto

Spring Framework Localization always reads from en (English) file

I have followed the tutorial below to set up localization for my web app.
http://viralpatel.net/blogs/spring-3-mvc-internationalization-i18n-localization-tutorial-example/
I have three properties files: messages_en_properties, messages_es.properties, and messages_zh_CN.properties
Each file has the following line:
loging.name=(Username translated to the corresponding language)
In my .jsp file I set my table data to display the username using the following line:
<td><spring:message code = "login.name" text = "Default Text"/></td>
This works, but it only will ever read from my English properties file. I have tried setting the locale manually in the .jsp file to zh_CN and es but I still receive the English file values. I have even tried setting the locale to a country for a file I do not have and it still displays the text from the English file, and not the default text. I am positive the locale is actually being changed since the browser will ask if I would like the page translated.
Here is the part of my code that sets up the localeChangeInterceptor.
<beans:bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang" />
</beans:bean>
<beans:bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<beans:property name="interceptors">
<beans:ref bean="localeChangeInterceptor" />
</beans:property>
</beans:bean>
Also tried changing to the following...
<mvc:interceptors>
<beans:bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<beans:property name="defaultLocale" value="en" />
</beans:bean>
<beans:bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
</beans:bean>
Any help would be greatly appreciated.
Surround
> <bean id="localeChangeInterceptor"
> class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
> <property name="paramName" value="lang" /> </bean>
with <mvc:interceptors>
as
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" >
<property name="paramName" value="lang" />
</bean>
</mvc:interceptors>

Spring security SessionRegistry and bean based configuration woes

I'm using Spring Security 3.0.5 and trying to get a count of currently logged in users. My scenario is Pre-Authenticated and using bean based configuration as opposed to <http> namespace based configuration (in which case this appears to be trivial.
My config file is as follows:
<beans:bean id="springSecurityFilterChain"
class="org.springframework.security.web.FilterChainProxy">
<filter-chain-map path-type="ant">
<filter-chain pattern="/**/resources/**" filters="none" />
<filter-chain pattern="/**/logout/**" filters="none" />
<filter-chain pattern="/service/**" filters="none" />
<filter-chain pattern="/**"
filters="sif,concurrencyFilter,shibbolethFilter,smf,logoutFilter,etf,fsi" />
</filter-chain-map>
</beans:bean>
<beans:bean id="sif"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter" />
<beans:bean id="scr"
class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />
<beans:bean id="smf"
class="org.springframework.security.web.session.SessionManagementFilter">
<beans:constructor-arg name="securityContextRepository"
ref="scr" />
<beans:property name="sessionAuthenticationStrategy"
ref="sas" />
</beans:bean>
<beans:bean id="shibbolethFilter"
class="PreAuthenticatedShibbolethAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="exceptionIfHeaderMissing" value="true" />
<beans:property name="continueFilterChainOnUnsuccessfulAuthentication"
value="true" />
<beans:property name="developmentMode" value="true" />
<beans:property name="authenticationSuccessHandler"
ref="customAuthenticationSuccessHandlerBean" />
</beans:bean>
<beans:bean id="sas"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry"
ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1" />
</beans:bean>
<beans:bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/session-expired.html" />
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider ref='preauthAuthProvider' />
</authentication-manager>
<beans:bean id="preauthAuthProvider"
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<beans:property name="preAuthenticatedUserDetailsService">
<beans:bean id="userDetailsServiceWrapper"
class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<beans:property name="userDetailsService" ref="userDetailsService" />
</beans:bean>
</beans:property>
</beans:bean>
<beans:bean id="logoutHandlerBean"
class="LogoutSuccessHandlerImpl" />
<beans:bean id="userDetailsService"
class="CustomJdbcDaoImpl">
<beans:property name="dataSource" ref="projectDS" />
<beans:property name="enableGroups" value="true" />
<beans:property name="enableAuthorities" value="false" />
</beans:bean>
In my controller I have the following code:
#Resource(name="sessionRegistry")
private SessionRegistry sessionReg;
private void doTest() {
List<Object> principals = sessionReg.getAllPrincipals();
for (Object o : principals) {
List<SessionInformation> siList = sessionReg.getAllSessions(o,
true);
for (SessionInformation si : siList) {
logger.error(si.getSessionId() + " " + si.getPrincipal());
}
}
}
The list principals is always empty. I feel the PreAuthenticatedShibbolethAuthenticationFilter filter which extends AbstractPreAuthenticatedProcessingFilter should get a ref to ConcurrentSessionControlStrategy, however, there is no such property which could be set.
What am I missing?
SecurityContextPersistenceFilter requires a SecurityContextRespository
<bean id="sif" class="org.springframework.security.web.context.SecurityContextPersistenceFilter" >
<property name="securityContextRepository" ref="scr" />
</bean>

Resources