转自 http://loianegroner.com/2010/02/integrating-spring-security-with-extjs-login-page/
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:
- URL / form action: j_spring_security_check
- Username input name: j_username
- 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):
01 | Ext.onReady( function (){ |
07 | var login = new Ext.FormPanel({ |
09 | url: 'j_spring_security_check' , |
11 | title: 'Please Login' , |
13 | defaultType: 'textfield' , |
21 | fieldLabel: 'Username' , |
25 | fieldLabel: 'Password' , |
28 | inputType: 'password' , |
39 | login.getForm().submit({ |
55 | Ext.Msg.alert( 'Status' , 'Login Successful!' , function (btn, text){ |
58 | window.location = 'main.action' ; |
68 | failure: function (form, action){ |
69 | if (action.failureType == 'server' ){ |
70 | obj = Ext.util.JSON.decode(action.response.responseText); |
72 | Ext.Msg.alert( 'Login Failed!' , obj.errors.reason); |
74 | Ext.Msg.alert( 'Warning!' , 'Authentication server is unreachable : ' + action.response.responseText); |
77 | login.getForm().reset(); |
85 | 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:
01 | package com.loiane.security; |
03 | import java.io.IOException; |
04 | import java.io.Writer; |
06 | import javax.servlet.http.HttpServletRequest; |
07 | import javax.servlet.http.HttpServletResponse; |
08 | import javax.servlet.http.HttpServletResponseWrapper; |
10 | import org.springframework.security.Authentication; |
11 | import org.springframework.security.AuthenticationException; |
12 | import org.springframework.security.ui.webapp.AuthenticationProcessingFilter; |
14 | public class MyAuthenticationProcessingFilter extends AuthenticationProcessingFilter { |
16 | protected void onSuccessfulAuthentication(HttpServletRequest request, |
17 | HttpServletResponse response, Authentication authResult) |
19 | super .onSuccessfulAuthentication(request, response, authResult); |
21 | HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response); |
23 | Writer out = responseWrapper.getWriter(); |
25 | String targetUrl = determineTargetUrl( request ); |
26 | out.write( "{success:true, targetUrl : \'" + targetUrl + "\'}" ); |
31 | protected void onUnsuccessfulAuthentication( HttpServletRequest request, |
32 | HttpServletResponse response, AuthenticationException failed ) |
35 | HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response); |
37 | Writer out = responseWrapper.getWriter(); |
39 | out.write( "{ success: false, errors: { reason: 'Login failed. Try again.' }}" ); |
And this is how applicationContext-security.xml looks like :
01 | <? xml version = "1.0" encoding = "UTF-8" ?> |
09 | < security:global-method-security /> |
11 | < security:http auto-config = "false" entry-point-ref = "authenticationProcessingFilterEntryPoint" > |
12 | < security:intercept-url pattern = "/index.jsp" filters = "none" /> |
13 | < security:intercept-url pattern = "/*.action" access = "ROLE_USER" /> |
16 | < bean id = "authenticationProcessingFilter" class = "com.loiane.security.MyAuthenticationProcessingFilter" > |
17 | < security:custom-filter position = "AUTHENTICATION_PROCESSING_FILTER" /> |
18 | < property name = "defaultTargetUrl" value = "/main.html" /> |
19 | < property name = "authenticationManager" ref = "authenticationManager" /> |
22 | < security:authentication-manager alias = "authenticationManager" /> |
24 | < bean id = "authenticationProcessingFilterEntryPoint" |
25 | class = "org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint" > |
26 | < property name = "loginFormUrl" value = "/index.jsp" /> |
27 | < property name = "forceHttps" value = "false" /> |
38 | < security:authentication-provider > |
39 | < security:password-encoder hash = "md5" /> |
40 | < security:user-service > |
41 | < security:user name = "rod" password = "a564de63c2d0da68cf47586ee05984d7" authorities = "ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" /> |
42 | < security:user name = "dianne" password = "65d15fe9156f9c4bbffd98085992a44e" authorities = "ROLE_USER,ROLE_TELLER" /> |
43 | < security:user name = "scott" password = "2b58af6dddbd072ed27ffc86725d7d3a" authorities = "ROLE_USER" /> |
44 | < security:user name = "peter" password = "22b5c9accc6e1ba628cedc63a72d57f8" authorities = "ROLE_USER" /> |
45 | </ security:user-service > |
46 | </ security:authentication-provider > |
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!