Change session cookie name in Grails 3.0 - session

In Grails 2.x you can change the name of the session cookie in the web.xml with
<session-config>
<cookie-config>
<name>JSESSIONID_XYZ</name>
</cookie-config>
</session-config>
In Grails 3.0 there is by default no web.xml (but can be created manually). Is there any other way to change the name of the session cookie?
Update: I tried to create a web.xml but it didn't work

ServletContextInitializer can be used to register a bean, in which you can configure the Cookie name with
#Override
void onStartup(ServletContext servletContext) throws ServletException {
servletContext.getSessionCookieConfig().setName(sessionCookieName);
}
I preffed this solution because it also works during development with run-app, which is acutally what i need.

It works when deployed as a war, but not with run-app. Add this to src/main/webapp/WEB-INF/web.xml:
<?xml version='1.0' encoding='UTF-8'?>
<web-app version='3.0'
xmlns='http://java.sun.com/xml/ns/javaee'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd'>
<session-config>
<cookie-config>
<name>JSESSIONID_XYZ</name>
</cookie-config>
</session-config>
</web-app>
and deploy the war to Tomcat or another container and it will use the config settings from web.xml along with the programmatic servlet/filter/etc. registrations.

Related

Spring Security + Primefaces - can't handle viewexpiredeception

I have problems with spring security and primefaces configuration. For my project, I needed the ability to log in, and it was decided to add spring security. Before I added the spring security, it was like this: if the user opens the page and is idle for half an hour, then the session dies, buttons on the page stop working and I get viewexpiredexception in the IDE's console when an button is pressed. Then I changed the web.xml and faces-config.xml files:
web.xml:
<!-- File(s) appended to a request for a URL that is not mapped to a web component -->
<welcome-file-list>
<welcome-file>mypage.xhtml</welcome-file>
</welcome-file-list>
<error-page>
<exception-type>
javax.faces.application.ViewExpiredException
</exception-type>
<location>/login.xhtml</location> <!-- type whatever suits your environment and requirements -->
</error-page>
<!-- Define the JSF servlet (manages the request processing life cycle for JavaServer Faces) -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map following files to the JSF servlet -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class>
</listener>
faces-config.xml
<application>
<el-resolver>
org.primefaces.application.exceptionhandler.PrimeExceptionHandlerELResolver
</el-resolver>
</application>
<factory>
<exception-handler-factory>
org.primefaces.application.exceptionhandler.PrimeExceptionHandlerFactory
</exception-handler-factory>
</factory>
After that, if the session dies and the user presses any button, he will receive a message stating that the session has died and will be redirected to the page.
Problem: After I added spring security, it all stopped working. After half an hour of inactivity, the buttons stop working as before when I didn’t have the handler for viewexpiredexception, but there are no exceptions in the console and no redirecting, the user must refresh page himself. Here is my configuration:
SecurityConfig.java
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/javax.faces.resource/**")
.permitAll().anyRequest().authenticated();
// login
http.formLogin().loginPage("/login.xhtml").permitAll()
.failureUrl("/login.xhtml?error=true");
http.sessionManagement()
.maximumSessions(1)
.expiredUrl("/login.xhtml")
.and()
.invalidSessionUrl("/login.xhtml");
// logout
http.logout().logoutSuccessUrl("/login.xhtml");
// not needed as JSF 2.2 is implicitly protected against CSRF
http.csrf().disable();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("john.doe")
.password("{noop}1234").roles("USER").and()
.withUser("jane.doe").password("{noop}5678").roles("ADMIN");
}
}
I could not find how to solve my problem.

How to set cookie name in a Spring Boot application running in a standalone Tomcat?

I tried different ways to set a customized cookie name. But none is working in my configuration.
I have a Spring Boot application which is running in a standalone Tomcat.
I tried to set the cookie name in the SpringBootApplication class which is derived from SpringBootServletInitializer:
#Value("${session.cookie.name}")
private String sessionCookieName;
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.getSessionCookieConfig().setName(sessionCookieName);
super.onStartup(servletContext);
}
Also I tried to define a bean as DefaultCookieSerializer:
#Value("${session.cookie.name}")
private String sessionCookieName;
#Bean
public DefaultCookieSerializer defaultCookieSerializer(){
DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
defaultCookieSerializer.setCookieName(sessionCookieName);
return defaultCookieSerializer;
}
But nothing is working so far, I always get the default JSESSONID instead of my configured session.cookie.name
Are there any other ways to customize the cookie name?
I tried the TomcatContextCustomizer as suggested. But I think it does not work, when you deploy your application as a WAR-File because it is just for the embedded tomcat.
I resolved the issue by adding a web.xml. In the folder src/main/webapp/WEB-INF. I'm not really satisfied with this solution, because I don't want a web.xml in my spring boot application. But it works...
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
metadata-complete="true">
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<name>CUSTOM_SESSION_ID</name>
<http-only>true</http-only>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
</web-app>
If there are any better solutions let me know
In the spring boot application. You can rename the JESSIONID by setting your custom name in application.properties file as below:
server.servlet.session.cookie.name=Your_custome_name
It works fine for me.

spring rest project with client side in angular js - how to approach the rest service with ajax

So I have a spring rest project that includes client side app.
I can run the service on a local tomcat and get responses querying "http://:8080/books" for example.
I can set app an apache server and go to "http://" to see my client app (the apache htdocs dir points to the project client app dir).
What I can't manage to do is send ajax rest queries to the service.
I'm using angular js so it looks like:
$http.get("http://:8080/books").success(...).error(...);
and it always enters the error callback method.
In the debugger/network tab I see that the request status is "canceled". Looking at the request's details I see next to the "Request headers" title the message: "CAUTION: Provisional headers are shown".
Here is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Library Application</display-name>
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.library.application</param-value>
</context-param>
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>prod</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>BooksServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.library.service.config.ControllerConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>BooksServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
My project structure is:
src
main
java
resources
webapp
resources
WEB-INF
test
Is it because the origin is different (mainly the port)?
Should I add some code to my web.xml to serve the client through tomcat? If so how?
thanks.
I guess you have a problem with cross-domain requests(yes, different port is another domain for the browser and it will cancel the request for security purposes if server will not include cross-domain headers). Try to add this headers to your REST response:
responseHeaders.add("Access-Control-Allow-Origin", "*");
if you need cookies you might need this as well:
responseHeaders.add("Access-Control-Allow-Credentials", "true");
in the second case you have to set an origin, '*' will not work in this case
more info here
Angular http uses relative urls.
For example using : www.stackoverflow.com
And
$http.get('/api/search?'
would call : www.stackoverflow.com/api/search
You can tests your rest api using your browser for gets requests, and one of the many plugins for post/put/delete.
(they are jsut made up urls btw)
Found it.
Thanks for all the answers, I was looking for the spring solution.
+1 JohnnyAW for your answer.
In my controller config class I've extended WebMvcConfigurerAdapter and overridden an addResourceHandlers method pointing to my client web app dir:
#Configuration
#EnableWebMvc
#ComponentScan("com.library.service")
public class ControllerConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
Note that it works because configuration is annotated with #EnableWebMvc.

WSServletContainerInitializer and SpringBeanAutowiringSupport

I have some integration issues regarding the mentioned classes but only with "too new" tomcat versions.
The base setup:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="FooService" version="2.5" metadata-complete="true">
<display-name>FooService</display-name>
<servlet>
<servlet-name>jax-ws</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
</web-app>
FooServiceImpl:
#WebService(serviceName = ServiceInfo.SERVICENAME, targetNamespace = ServiceInfo.TARGETNAMESPACE, endpointInterface = "bar.FooService")
#HandlerChain(file = "/handler-chain.xml")
public class FooServiceImpl extends SpringBeanAutowiringSupport implements FooService {
#Autowired
private Bar bar;
<< some methods using the injected bar singleton >>
JAX-WS dependency: compile 'com.sun.xml.ws:jaxws-rt:2.2.7'
Spring version: 3.1.2.RELEASE
With Tomcat 7.0.22 I don't have the problem. The declared webapp version in the web.xml is 2.5. Tomcat 7.0.22 doesn't process the WSServletContainerInitializer. So as declared in web.xml, ContextLoaderListener is initialized first, so an instance of Bar will be available in the WebApplicationContext. Then WSServletContextListener instantiates FooServiceImpl, aoutowiring works and everybody is happy.
But... My colleague tried it with Tomcat 7.0.30 and the autowiring didn't work (7.0.32 gives the same problem, currently this is the newest). It really couldn't work, because the new Tomcat version has processed WSServletContainerInitializer, not taking into account the 2.5 webapp version (and metadata-complete="true").
I've found a possible solution. I commented out the body of the web.xml, changed webapp version to 3.0 and created a WebapplicationInitializer:
public class MyInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
ContextLoader loader = new ContextLoader();
loader.initWebApplicationContext(servletContext);
}
}
This worked perfectly for me. But not for my colleague... If he tried to run the app, WSServletContainerInitializer fired first which created exactly the same wiring problem as above.
Obviously we can "hack" the problem getting rid of SpringBeanAutowiringSupport and inject Bar manually from a getter or a web method, or any similar way. But SpringBeanAutowiringSupport would be much clearer, so we would like to use it if there's a good solution for the above problems.
UPDATE: this causes the problems: https://issues.apache.org/bugzilla/show_bug.cgi?id=53619
for me the solution was to invoke the following when the autowired reference is null
processInjectionBasedOnCurrentContext(this);
I hope it helps for all.

How to configure for session cookie as http-only

to set http-only I used this in web.xml
<session-config>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
</session-config>
but it is not setting http-only.
can any one suggest, what may be the problem. and how to set it.
Thanks.
Which container are you using and in which version?
pay attention since true can be used in web.xml only since servlet 3.0

Resources