
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/