Featured Posts

ExtJS, Spring MVC 3 and Hibernate 3.5: CRUD DataGrid... This tutorial will walk through how to implement a CRUD (Create, Read, Update, Delete) DataGrid using ExtJS, Spring MVC 3 and Hibernate 3.5. What do we usually want to...

Readmore

ExtJS plugin: PagingToolbarResizer Well, this is my first ExtJS plugin. Though it is not an advanced plugin, I'm very happy and it is a big accomplishment for me! The problem: ExtJS PagingToolbar Component...

Readmore

Hibernate 3 Annotations Tutorial This tutorial will walk through how to implement a hello world project using Hibernate Annotations and MySQL database. Requirements Download and unzip Hibernate Core...

Readmore

My DeveloperWorks: What's life like for a female Java... Just wanted to share with you my interview on Valerie's My developerWorks blog: Interview with Loiane Groner, Java developer in Brazil. I'm very happy, because this interview...

Readmore

Getting started with ExtJS in your J2EE project This tutorial will walk through how to get an Ext JS installation up and running quickly in your java (J2EE) project. Level: Basic This is the screenshot of this tutorial: First,...

Readmore

Loiane Groner Rss

Integrating Spring Security with ExtJS Login Page

Posted on : 01-02-2010 | By : Loiane | In : ExtJS, Spring, Spring Security, Uncategorized

13

This tutorial will walk through how to configure ExtJS Login form (Ajax login form) instead of default Spring Security login.jsp.

Instead of using login.jsp from spring security, why do not use an ajax login form?

And How to integrate the ExtJS Login Form with Spring Security?

You did try to do it, the user is successfully authenticated, but the user is not redirected to the application main page. How to fix this situation? How to make it work?

It does not matter if you set the default-target-url in applicationContext-security.xml, or set a redirect URL on server side. It will not work this way.

The issue is that ExtJS make Ajax calls, and no redirect will work on server side. You have to redirect it on the client side, which is the ExtJS/javascript code.

First, you need to create the login form. You can use the javascript code provided by ExtJS and you can modify it to work with spring security.

If you take a look at the login.jsp, you will see three key points:

  1. URL / form action: j_spring_security_check
  2. Username input name: j_username
  3. Password input name: j_password

That is what you need to customize to make ExtJS Login form works! But do not be too comfortable, there are some issues you need to fix to make it work perfectly.

Take a look how login.js looks like (after customization):

Ext.onReady(function(){
	Ext.QuickTips.init();

	// Create a variable to hold our EXT Form Panel.

	// Assign various config options as seen.
	var login = new Ext.FormPanel({
		labelWidth:80,
		url:'j_spring_security_check',
		frame:true,
		title:'Please Login',

		defaultType:'textfield',
		width:300,
		height:150,
		monitorValid:true,
		// Specific attributes for the text fields for username / password.
		// The "name" attribute defines the name of variables sent to the server.

		items:[{
			fieldLabel:'Username',
			name:'j_username',
			allowBlank:false
		},{
			fieldLabel:'Password',

			name:'j_password',
			inputType:'password',
			allowBlank:false
		}],

		// All the magic happens after the user clicks the button
		buttons:[{

			text:'Login',
			formBind: true,
			// Function that fires when user clicks the button
			handler:function(){
			login.getForm().submit({

				method:'POST',

				// Functions that fire (success or failure) when the server responds.
				// The server would actually respond with valid JSON,
				// something like: response.write "{ success: true}" or

				// response.write "{ success: false, errors: { reason: 'Login failed. Try again.' }}"
				// depending on the logic contained within your server script.
				// If a success occurs, the user is notified with an alert messagebox,

				// and when they click "OK", they are redirected to whatever page
				// you define as redirect.

				success:function(){
				Ext.Msg.alert('Status', 'Login Successful!', function(btn, text){

					if (btn == 'ok'){
						window.location = 'main.action';
					}
				});

			},

			// Failure function, see comment above re: success and failure.
			// You can see here, if login fails, it throws a messagebox
			// at the user telling him / her as much.

			failure:function(form, action){
				if(action.failureType == 'server'){
					obj = Ext.util.JSON.decode(action.response.responseText);

					Ext.Msg.alert('Login Failed!', obj.errors.reason);
				}else{
					Ext.Msg.alert('Warning!', 'Authentication server is unreachable : ' + action.response.responseText);

				}
				login.getForm().reset();
			}

			});
		}
		}]
	});

	login.render('login');

});

If you make these changes and try to execute the application with a basic applicationContext-security.xml file, the user will be successfully authenticated, but is not going to be redirected.

What are we missing then?

You need to customize AuthenticationProcessingFilter class for spring security to perform actions on login.

The “onSuccessfulAuthentication” and “onUnsuccessfulAuthentication” methods need to return some JSON content. If user is successfully authenticated, then redirect to main page, otherwise, the application will show an error message.

This is MyAuthenticationProcessingFilter class:

package com.loiane.security;

import java.io.IOException;
import java.io.Writer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.ui.webapp.AuthenticationProcessingFilter;

public class MyAuthenticationProcessingFilter extends AuthenticationProcessingFilter {

	protected void onSuccessfulAuthentication(HttpServletRequest request,
			HttpServletResponse response, Authentication authResult)
	throws IOException {
		super.onSuccessfulAuthentication(request, response, authResult);

		HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response);

		Writer out = responseWrapper.getWriter();

		String targetUrl = determineTargetUrl( request );
		out.write("{success:true, targetUrl : \'" + targetUrl + "\'}");
		out.close();

	}

	protected void onUnsuccessfulAuthentication( HttpServletRequest request,
			HttpServletResponse response, AuthenticationException failed )
	throws IOException {

		HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response);

		Writer out = responseWrapper.getWriter();

		out.write("{ success: false, errors: { reason: 'Login failed. Try again.' }}");
		out.close();

	}

}

And this is how applicationContext-security.xml looks like:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:security="http://www.springframework.org/schema/security"
	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-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">

	<security:global-method-security />

	<security:http auto-config="false" entry-point-ref="authenticationProcessingFilterEntryPoint">
		<security:intercept-url pattern="/index.jsp" filters="none" />
		<security:intercept-url pattern="/*.action" access="ROLE_USER" />
	</security:http>

	<bean id="authenticationProcessingFilter" class="com.loiane.security.MyAuthenticationProcessingFilter">
		<security:custom-filter position="AUTHENTICATION_PROCESSING_FILTER" />
		<property name="defaultTargetUrl" value="/main.html" />
		<property name="authenticationManager" ref="authenticationManager" />
	</bean>

	<security:authentication-manager alias="authenticationManager" />

	<bean id="authenticationProcessingFilterEntryPoint"
		class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
		<property name="loginFormUrl" value="/index.jsp" />
		<property name="forceHttps" value="false" />
	</bean>

    <!--
    Usernames/Passwords are
        rod/koala
        dianne/emu
        scott/wombat
        peter/opal
    These passwords are from spring security app example
    -->
    <security:authentication-provider>
        <security:password-encoder hash="md5"/>
        <security:user-service>
            <security:user name="rod" password="a564de63c2d0da68cf47586ee05984d7" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
            <security:user name="dianne" password="65d15fe9156f9c4bbffd98085992a44e" authorities="ROLE_USER,ROLE_TELLER" />
            <security:user name="scott" password="2b58af6dddbd072ed27ffc86725d7d3a" authorities="ROLE_USER" />
            <security:user name="peter" password="22b5c9accc6e1ba628cedc63a72d57f8" authorities="ROLE_USER" />
	    </security:user-service>
	</security:authentication-provider>
</beans>

Now you can login using ExtJS login form.

I coded a sample application for this example. If you like it, you can download it from my GitHub: http://github.com/loiane/spring-security-extjs-login

Happy coding!

Comments (13)

a perfect mix, this tools (framework spring + extjs) is a interesting experience to work.
thanks a good tutorial

thanks, (bow)

Its working..cool :)
Anyway how if I use username and password taken from database?

Any solutions?

Hi,
I wrote another tutorial about spring security and you can take a look how to do it: http://loianegroner.com/2010/01/tutorial-getting-started-with-spring-security/
Thanks!

Hi, I’ve got a situation, my security xml isn’t configured like yours ‘cuz has it was created in another project where the client side wasn’t ext js.
Would you help me
thanks

Hi,

Well, I’m not an expert on it, but sure, I can help you.

Thanks for visiting

Nice tutorial and very helpful!

I tried it and it works well, just have several questions though:
1. My login page is login.html, my main page is main.html, how can I make it redirect to login.html even if I type “http://…/main.html” in browser? Now I still can access main.html without login.

2. The username and password can be seen from firebug when click login button. Is there any way to make it safe and invisible?

3. If I use my own ajax call to handle authentication, for example, use “url: ‘myAuthen.ajax’ instead of url:’j_spring_security_check’ in login.js file, does it make sense to use Spring security? How could I integrate that?

Thanks for answer Loiane, but I’m already solve the problem. The thing is that I was using a preconfigured security module over spring, I adapted to my needs, but the thing was around you were talking at the beginning of your article, when the user logged in the system, redirection fails. But I put at the javascript in the success function part this:
location.href = ‘home.htm’; //Main page request
and problem solved
Thanks very much
PS: Your article was very useful to me. Thanks again

Muito obrigado, você viu como implementar a permissão para inserir, alterar, excluir?.
Você tem algum exemplo sobre isso?

Muito obrigado mais uma vez, Yamina

Thanks, for your tutorial. it helps me alot to understand how to mix ajax and spring together.

Hi Loiane,

I use Spring Security3.x with ExtJS, and I find that much changes from 2.x. Your code can’t be use driectly,
do you have any idea?

Thanks for a great tutorial and source code.
It was a great help on a project I’m working on.

where is this suppose to point to – j_spring_security_check ?

Write a comment