Accessing proper resource bundle in Spring Framework - spring

I am trying to access a resource bundle using Spring framework (WebFlow). A messages.properties file and accordingly messages_ar_AE.properties file are kept in the classpath from where the Spring Framework access the resource bundle.
The code in invoked from a xhtml file using the JSTL resourceBundle attribute.
<myCustom:includedInSetValidator set="5.0, 5.0.1, 5.1"
validationMessage="#{resourceBundle['jboss.version.error']}" />
But irrespective of locale, the "#{resourceBundle['jboss.version.error']}" always fetches the default text, i.e; from English;
As I learned from some forums I got an hint that I need to handle this using LocaleChangeInterceptor or some other predefined classes. Once the Spring Locale is set, the proper resource bundle will be loaded by default, and hence solving my problem.
I need a way to change the Spring Framework Locale programatically to set the Locale. How do I achieve this programatically ?
Thanks.

Reached the solution for the problem.
Continuing from my question, when Spring Framework encounters a JSTL expression like "#{resourceBundle['jboss.version.error']}" by default it looks for message.properties file in the classpath, unless a resource bundle is defined explicitly.
When trying to fetch the proper resource bundle, the framework looks at the at the locale it is set to. As the locale of Spring Framework was not set in my case, it was not fetching me the expected resource bundle. Out of available options i chose Spring LocaleResolver
I modified existing JSF Custom ViewHandler in my application, where I added code to set the locale of Spring Framework.
public Locale calculateLocale(FacesContext arg0) {
HttpServletRequest request = (HttpServletRequest)arg0.getExternalContext().getRequest();
HttpServletResponse response = (HttpServletResponse)arg0.getExternalContext().getResponse();
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
localeResolver.setLocale(request, response, **setYourLocaleHere**);
}
The story just doesn't end here, setting the locale in locale resolver this way would throw the error:
Cannot change HTTP accept header – use a different locale resolution strategy
Refer Cannot change HTTP accept header error
To overcome this, one should include
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="en" />
</bean>
in the Spring configuration file.
And now the desired locale of the Spring Framework is set.
There could possibly a better solution than what I did. One can also suggest their solutions if any.
Thanks.

You could do this multiple ways as outlined here in the doc.

Related

fallback messege file in spring boot is always "en"

I configured my web application as indicated in https://www.baeldung.com/spring-boot-internationalization#localeresolver
with setting Locale.ITALIAN as default locale for LocaleResolver bean.
I have two message files:
message.properties with italian messages
message_en.properties with messages in english
However, labels defined in messages_en.properties, when exists. For example with setting locale via lang=es request parameter, messages in english are shown.
The expected behaviour, if I understand, should be that if lang=en, message_en.properties should be used, where as for all other languages messages in message.properties should be used.
Suggestions?
If you use the latest version of Spring Boot (2.5.3 at the moment), the tutorial isn't as up-to-date. For example, with the latest Spring you must do additional, but simple config to override LocaleResolver bean.
Depending of your implementation, you may need to add in the application.properties file the line spring.messages.fallback-to-system-locale=false or if you overridden the "messageSource" bean, you must set messageSource.setFallbackToSystemLocale(false); in your own bean.
This way the app should work as expected, with all languages except EN using message.properties.

Session cookie custom path

I have an spring boot application and want to deploy it to wildfly12. What I'm trying to achieve is that to set a custom path for JSESSIONID cookie. But after all, my efforts haven't had any results.
I have tried to use this property in my application.properties file:
server.servlet.session.cookie.path=/
When I run the application with the embedded tomcat, everything works fine; But when I deploy my app to wildfly, regardless of the value of that property, it always sets the cookie path to the "context-path" of the application.
I have also tried to use this property also:
server.servlet.context-path=/
but no success so far!
There is also this tag inside the standalone.xml file:
<session-cookie http-only="true" secure="true"/>
but it seems that it has nothing to do with the cookie path, as it doesn't have any property regarding that.
The configuration you are doing is for the embedded server of spring boot application.
Embedded server settings present in application properties (can be check here the section # EMBEDDED SERVER CONFIGURATION and the namespace server.servlet.session.cookie.*).
To modify cookie related configuration on external servers, you have to create CookieSerializer bean which can be used to customize cookie configuration. e.g.
#Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("JSESSIONID");
serializer.setCookiePath("/");
serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
return serializer;
}
You can refer spring guide for more information.

Vulnerability warning with XStreamMarshaller

When using a XStreamMarshaller with spring batch, I get the following message:
Security framework of XStream not initialized, XStream is probably vulnerable.
First try: According to the documentation, I've tried to reset all permissions, but I still have the same message. Besides, I have no security error when parsing XML files... So I think that this code just doen't work. Here's a sample of code:
XStreamMarshaller marshaller = new XStreamMarshaller();
marshaller.getXStream().addPermission(NoTypePermission.NONE);
Second try: I have also tried with the setSupportedClasses method, but it doesn't work either (I still get the vulnerability message and not supported classes are still unmarshelled correctly):
XStreamMarshaller marshaller = new XStreamMarshaller();
marshaller.setSupportedClasses(FooBar.class);
How can I set security permissions with XStreamMarshaller?
Note: according to this thread, the Security Framework was introduced with 1.4.7 and it is still not mandatory.... But it will be mandatory for XStream 1.5.0!
Version of XStream used: 1.4.10
Version of Spring Batch used: 4.0.1
For information, I'm using Spring Boot (but I'm not sure it's relevant here)
Solution for the 'First Try':
The reason why it didn't work is that XStreamMarshaller instantiates a xstream object with afterPropertiesSet without checking if one have already been created, so we can't use getXStream() in a #Bean method. To make this work, we can for example set security config while injecting the marshaller in another bean:
#Configuration
public class JobSecurityConfig {
public JobSecurityConfig(XStreamMarshaller marshaller) {
XStream xstream = marshaller.getXStream();
XStream.setupDefaultSecurity(xstream);
xstream.allowTypes(new Class[]{Bar.class});
}
}
Another solution: extend XSreamMarshaller
You can also extend XStreamMarshaller and override only the customizeXStream() method to set security configuration.
#Override
protected void customizeXStream(XStream xstream) {
XStream.setupDefaultSecurity(xstream);
xstream.allowTypes(new Class[]{Bar.class});
}
Why the 'Second Try' doesn't work:
setSupportedClasses is only used on marshalling!!.. StaxEventItemReader doesn't care about supported classes!
Xstream website have provided details about the Security Framework Security Framework.
below method are provided to set Security permissions
XStream.addPermission(TypePermission);
XStream.allowTypes(Class[]);
XStream.allowTypes(String[]);
XStream.allowTypesByRegExp(String[]);
XStream.allowTypesByRegExp(Pattern[]);
XStream.allowTypesByWildcard(String[]);
XStream.allowTypeHierary(Class);
XStream.denyPermission(TypePermission);
XStream.denyTypes(Class[]);
XStream.denyTypes(String[]);
XStream.denyTypesByRegExp(String[]);
XStream.denyTypesByRegExp(Pattern[]);
XStream.denyTypesByWildcard(String[]);
XStream.denyTypeHierary(Class);
You can also refer this Tutorial
I hope this helps
From the official spring docs:
By default, XStream allows for arbitrary classes to be unmarshalled,
which can lead to unsafe Java serialization effects. As such, it is
not recommended to use the XStreamMarshaller to unmarshal XML from
external sources (i.e. the Web), as this can result in security
vulnerabilities.
You're using Spring's abstraction XStreamMarshaller to interface with the XStream library. By default the library can marshall/unmarshall arbitrary classes (including from external web source).
If you are not doing that (working with classes from external web sources) you can simply ignore the message.
If you want to remove the message follow what's recommended in Spring's official doc (linked above) and XStream website (security config example).
It boils down to setting up supported classes to make sure only the registered classes are eligible for unmarshalling.
This property is empty by default, which means - support all classes - hence the warning message you're getting.

Spring StandardServletMultipartResolver

I was wondering where is located the code that automatically create a temporary file when you send a multipart request using StandardServletMultipartResolver?
Can i disable that behavior? I want to decide how its going to be stored and where. I don't want spring to do it for me.
I'm considering creating my own resolver but I cant find information on how to disable spring default behavior.
To quote from API docs StandardServletMultipartResolver does not support temporary file configuration on resolver level rather it is to be done on servlet registration level -
In order to use Servlet 3.0 based multipart parsing, you need to mark the affected servlet with a "multipart-config" section in web.xml, or with a MultipartConfigElement in programmatic servlet registration, or (in case of a custom servlet class) possibly with a MultipartConfig annotation on your servlet class.
Configuration settings such as maximum sizes or storage locations need to be applied at that servlet registration level; Servlet 3.0 does not allow for them to be set at the MultipartResolver level.
So either you can configure it on servlet or switch to CommonsMultipartResolver which has the support to set the temp directory out-of-the-box as it inherits it from CommonsFileUploadSupport.setUploadTempDir (see respective docs here and here)

Multiple Locale Resolver in Spring.

Is it possible to have multiple locale resolver inside spring ?
I want to have multiple Locale Resolver inside my application like :
CookieLocaleResolver for user permanent language.
Http request Based LocaleResolver for just seeing a particular
page in another language.
Don't see problem to write your own LocaleResolver and register it as bean with name DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME.
The logic of resolveLocale implementation may be really based on the request, when you can determine to use CookieLocaleResolver or provide someother locale from request attributes

Resources