GWT version- 2.1
Spring Security 3.0.4
To integrate GWT with Spring security, just look at Spring security on its own. Another advantage of pulling the login page out of GWT framework is that the load time of initial page becomes much smaller. This also helps in DOS kind of attacks.
To integrate Spring first pull the required jars into maven. Here I am assuming the Spring is available in your environment otherwise you will have to pull extra jars for Spring core and others dependency
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${spring.version}</version> </dependency>
Now put a login page in your web app root, which looks like as follows. Note that the form should be posted on /j_spring_security_check and the username name should be j_username and password should be j_password
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Lalit Bhatt</title>
<link rel="shortcut icon" type="image/x-icon" href="resources/favicon.ico">
</head>
<body>
<form method="post" action="/j_spring_security_check">
<label for="j_username">Username:</label>
<input type="text" name="j_username" />
<br />
<label for="j_password">Password:</label>
<input type="password" name="j_password" />
<br />
<input type="submit" value="Login" />
</form>
</body>
</html>
Put the Spring application context for security configuration at a suitable location, may be inside META-INF under webapps. A typical context file would look like
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
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.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<!-- HTTP security configurations -->
<http auto-config='true'>
<intercept-url pattern="/login.html" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/resources/favicon.ico" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<logout logout-success-url="/login.html" />
<form-login login-page="/login.html" default-target-url="/index.gwt.html"
always-use-default-target="true" />
<session-management invalid-session-url="/login.html"
session-authentication-error-url="/login.html"
session-fixation-protection="newSession">
<concurrency-control max-sessions="1"
error-if-maximum-exceeded="false" />
</session-management>
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource" />
</authentication-provider>
</authentication-manager>
</beans:beans>
This is a very very basic context XML. It assumes everything as per defaults. It assumes that you have the user table and authorities table as per the need of spring security. Any difference would need a customization of Spring security which again has nothing to do with GWT.
The final thing is to register the configurations in web.xml, to start the Spring container and to hook the security filters in place
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/application*.xml</param-value>
</context-param>
<!-- Creates the Spring Container -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>If everything is fallen in place, then accessing the application will take you to login page first.
Handling session time out
This is quite tricky as when session time out happens, the GWT rpc call returns back the login page. The one way that I found non intrusive to handle is to first make an adapter to AsyncCallback and all the instantiations of AsyncCallback should happen using the adapter. This is a good way to handle all the failures in a common place.
public abstract class AsyncCallbackAdapter<T> implements AsyncCallback<T> {
@Override
public void onFailure(Throwable caught) {
if (caught instanceof InvocationException) {
InvocationException ie = (InvocationException) caught;
if(ie.getMessage().contains("j_spring_security_check"))
{
Window.alert("Session is timed out. Please login again");
Window.open(GWT.getHostPageBaseURL() + "login.jsp", "_self", null);
return;
}
}
//Do other error handling here
}
}
Comments
Thanks a lot
that 's the best solution I could find over the web!
how to create signout page using gwt
i need a signout forn using gwt application. provide me the functionality , methods,objects.
too many redirects
My GWT app works fine with the default spring login page but when i create the login.html and redirect there using applicationcontext.xml...i see too many redirects.Can you please provide any help..
too many redirects
Make sure your login page can be accessed without authentication. Something like
Handling session time out
Hi,
You're suggestions has been quite useful.
However in this snippet
ie.getMessage().contains("j_spring_security_check");
{
Window.alert("Session is timed out. Please login again");
Window.open(GWT.getHostPageBaseURL() + "login.jsp", "_self", null);
return;
}
you have a typo, you're missing an if, should be:
if (ie.getMessage().contains("j_spring_security_check"))
{
Window.alert("Session is timed out. Please login again");
Window.open(GWT.getHostPageBaseURL() + "login.jsp", "_self", null);
return;
}
Best regards,
Konrad Ciborowski
Kraków, Poland
Thanks
Thanks Konrad for pointing out the mistake. I have rectified the post.
A good many vlaubales you've given me.
A good many vlaubales you've given me.
Add new comment