首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2EE开发 >

SpringSecurity3 与 Extjs遇到的有关问题

2013-02-28 
SpringSecurity3 与 Extjs遇到的问题最近学习SpringSecurity3搭建了一个开发框架,应用的技术有Spring,Spri

SpringSecurity3 与 Extjs遇到的问题
最近学习SpringSecurity3搭建了一个开发框架,应用的技术有Spring,Spring MVC,Spring Security,myBatis,FreeMarker。
在做登录实现的时候Extjs前端报错:SpringSecurity3 与 Extjs遇到的有关问题
从错误信息来看,很明显错误原因是服务端返回了一个jsp页面,而不是json串导致。
我的登录的思路是:login.jsp提交请求,验证通过的时候跳转至index.jsp页面。毕竟才疏学浅,先请教高人指点一下实现思路,和造成extjs报错的原因,小弟先谢谢各位了

spring Security3配置文件:

<?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: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/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd ">

<beans:description>SpringSecurity安全配置</beans:description>

<!--HTTP 安全配置 

-->
<http auto-config="true" >
<intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/images/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/js/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/toLoginPage" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/toIndexPage" access="ROLE_USER,ROLE_ADMIN"/>
<intercept-url pattern="/admin/**" access="ROLE_ADMIN"/>
<intercept-url pattern="/**" access="ROLE_USER"/>
<form-login login-page="/toLoginPage" authentication-failure-url="/toLoginPage?error=1"/>
<!-- 尝试访问没有权限的页面时跳转的页面 -->
<access-denied-handler error-page="/common/403.jsp"/>
<!--logout logout-success-url="/login.jsp"/-->
<session-management>
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
</session-management>
<!-- 增加一个filter,这点与Acegi是不一样的,不能修改默认的filter了,这个filter位于FILTER_SECURITY_INTERCEPTOR之前 -->
<custom-filter ref="customFilter" before="FILTER_SECURITY_INTERCEPTOR"/>
</http>
<!-- 一个自定义的filter,必须包含authenticationManager,accessDecisionManager,securityMetadataSource三个属性 -->
<!-- 我们的所有控制将在这三个类中实现,解释详见具体配置 -->
<beans:bean id="customFilter" class="com.firefly.tire.security.interceptor.CustomFilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="accessDecisionManager" ref="accessDecisionManagerBean" />
<beans:property name="securityMetadataSource" ref="securityMetadataSource" />
</beans:bean>
<!-- 验证配置,认证管理器,实现用户认证的入口,主要实现UserDetailsService接口即可 -->
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsService">
<!--password-encoder hash="md5">
<salt-source user-property="username"/>
</password-encoder-->
</authentication-provider>
</authentication-manager>
<!-- 项目实现的用户查询服务,将用户信息查询出来 -->
<beans:bean id="userDetailsService" class="com.firefly.tire.security.support.CustomUserDetailService" />
<!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 -->
<beans:bean id="accessDecisionManagerBean" class="com.firefly.tire.security.support.CustomAccessDecisionManager" />
<!-- 资源元数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色访问 -->


<beans:bean id="securityMetadataSource" class="com.firefly.tire.security.support.CustomInvocationSecurityMetadataSourceService" >
<!--beans:property name="sysAuthorityService" ref="sysAuthorityService"/ -->
<!-- beans:property name="sysResourceService" ref="sysResourceService"/ -->
</beans:bean>
<!--beans:bean id="sysAuthorityService" class="com.firefly.tire.security.service.impl"></beans:bean -->

<!-- 定义国际化 -->
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource" >
<beans:property name="basename" value="classpath:org/springframework/security/messages_zh_CN"></beans:property>
</beans:bean>
</beans:beans>



login.js

Ext.onReady(function(){
    Ext.QuickTips.init();
    var login = new Ext.FormPanel({
       labelWidth:80,
       url:'',
       frame:true,
       title:'河北联众电子ERP登录窗口',
       defaultType:'textfield',
       width:300,
       height:150,
       monitorValid:true,
       
       items:[{
           fieldLabel:'用户名',
           name:'j_username',
           allowBlank:false
       },{
           fieldLabel:'密码',
           name:'j_password',
           inputType:'password',
           allowBlank:false
       }],
       buttons:[{
           text:'登录',
           formBind: true,
           handler:function(){
           login.getForm().submit({
          waitTitle:"请稍后",
          waitMsg:'正在登录...',
              method:'POST', 
              url:'j_spring_security_check',
              success:function(){
              
              },
           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');
});



login.jsp:

<html>
<head>
<#include "common/meta.html"/>
<link rel="stylesheet" type="text/css" href="${ctx}/resources/css/login.css"/>
<script type="text/javascript" src="${ctx}/resources/login.js">
</script>
<title>Insert title here</title>
</head>
<body >
<div id="login"></div>
</body>
</html>


index.jsp:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<#include "common/meta.html"/>
<script type="text/javascript" src="${ctx}/resources/panel.js"></script>
<link rel="stylesheet" type="text/css" href="${ctx}/resources/css/index.css"/>
<title>登录</title>
<meta http-equiv="pragma" content="no-cache" />
</head>
<body>
 <div id="headerDiv">
<div class="header-title"></div>
<div class="header-content">
<ul>
<li>
<div class="header-left">

<div class="show-ann" qtip="公告">
<marquee id="show-ann-marquee" behavior="scroll" direction="left" scrollamount="2" loop="1" onMouseOut="this.start()" onMouseOver="this.stop()">
<ul id="show-ann-ul">
</ul>
</marquee>
</div>
</div>
<div class="header-right">
<div class="header-btn-left"></div>
<ul><li><a href="javascript:" onclick="tire.Index.userResetPwd();" qtip="个人设置">个人设置</a></li><li><a href="javascript:" onclick="tire.Index.logout()">注销</a></li></ul>
<div class="header-btn-right"></div>
</div>
</li>
<li><div id="menuBannerDiv" class="menu-banner"><ul></ul></div></li>
</ul>
</div>
</div>
</body>
</html>

extjs security
[解决办法]
lz,你用extjs做的登陆
login.getForm().submit({
    waitTitle:"请稍后",
    waitMsg:'正在登录...',
    method:'POST', 
    url:'j_spring_security_check',
    ... 
});

这是异步的后台是不能控制页面跳转的,需要后台返回success标志通过js调整才行的。而根据你spring security的配置,登陆失败是返回一个jsp页面,导致Ext.util.JSON.decode(action.response.responseText)解析的不是json字符串报错!



解决办法就是让spring security在验证登陆的时候返回json字符串给extjs,把配置改改:

<!-- 自定义一个认证成功或失败时的Handler -->
<beans:bean id="authenticationHandler" class="com.xxxx.AuthenticationHandler" />
...
<!-- 告诉spring security认证后交给authenticationHandler去处理 -->
<form-login login-page="/login.jsp" 
    authentication-success-handler-ref="authenticationHandler"
    authentication-failure-handler-ref="authenticationHandler" />
...


AuthenticationHandler实现AuthenticationSuccessHandler和AuthenticationFailureHandler接口
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

public class AuthenticationHandler implements AuthenticationSuccessHandler, AuthenticationFailureHandler
{

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication auth) throws IOException, ServletException
    {
        response.getWriter().println("{"success" : true}");
        clearAuthenticationAttributes(request);
    }

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException auth) throws IOException, ServletException
    {
        response.getWriter().println("{"success" : false, "msg" : "权限认证失败!" + auth.getMessage() + ""}");
        System.out.println(auth.getMessage());
    }
    
    /**
     * Removes temporary authentication-related data which may have been stored in the session
     * during the authentication process.
     */
    protected final void clearAuthenticationAttributes(HttpServletRequest request)
    {
        HttpSession session = request.getSession(false);

        if(session == null)
        {
            return;
        }

        session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
    }

}


在extjs登陆事件中:
...
success : function() {
    window.location.href = 'index.html'; //跳转到登陆成功后的页面


}
...

热点排行