
Esse tutorial irá abordar como configurar o form de login da biblioteca ExtJS (Ajax) ao invés de utilizar a página de login (login.jsp) padrão do Spring Security..
Em vez de usar a página de login do Spring Security, por que não usar um form feito com Ajax?
E como integrar a página de login do ExtJS com o framework Spring Security?
Ok, você já tentou fazer isso, o usuário foi autenticado com sucesso, mas o usuário não é redirecionado para a página principal da aplicação. Como consertar isso?
Não importa de você setou a opção default-target-url no arquivo applicationContext-security.xml, ou setou uma URL para redirecionamento no lado do servidor. Não vai funcionar.
O problema é que o ExtJS faz uma chamada/request Ajax, e nenhum redirecionamento irá funcionar no lado servidor (spring). Você deve fazer esse redirecionamento no lado cliente, que é no código ExtJS/javascript.
Primeiro, você precisa crier o form do login. Você pode utilizar o código de exemplo disponibilizado pelo ExtJS: http://www.extjs.com/learn/Tutorial:Basic_Login e customizá-lo/modificá-lo para funcinoar com o Spring Security.
Se der uma olhada no arquivo login.jsp (padrão do Spring Security), você irá perceber três pontos chaves do form:
- URL / form action: j_spring_security_check
- Username input name: j_username
- Password input name: j_password
É isso que precisa customizar no login do ExtJS para fazê-lo funcinar com o Spring Security. Mas não pense que é assim tão fácil, ainda tem um pequeno detalhe que precisa consertar para funcionar perfeitamente.
O login.js irá ficar assim após as moficações:
01 | Ext.onReady(function(){ |
07 | var login = new Ext.FormPanel({ |
09 | url:'j_spring_security_check', |
13 | defaultType:'textfield', |
21 | fieldLabel:'Username', |
25 | fieldLabel:'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'); |
O que está faltando?
É necessário customizar a classe AuthenticationProcessingFilter para o Spring Security executar a ação no login.
Os métodos “onSuccessfulAuthentication” e “onUnsuccessfulAuthentication” precisam retornar algum conteúdo JSON. Se o usuário for autenticado com sucesso, então redireciona-o para a página principal da aplicação, senão, a aplicação irá mostrar uma mensagem de erro.
Essa é a classe MyAuthenticationProcessingFilter customizada:
01 | package com.loiane.security; |
03 | import java.io.IOException; |
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.' }}"); |
E o arquivo applicationContext-security.xml ficará assim:
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> |
Agora irá logar normalmente com o form de login do ExtJS.
Fiz uma pequena aplicação de exemplo. Se desejar, pode fazer o download do meu repositório no GitHub: http://github.com/loiane/spring-security-extjs-login
Fonte: http://www.loiane.com/2010/02/integrando-spring-security-com-a-pagina-de-login-do-extjs/