使用spring security 2.0 和extjs 3.0实现web登录

使用spring security 2.0 和extjs 3.0实现web登录

1开发环境说明

本例使用MyEclipse 6.5作为开发工具,jdk1.5作为编译工具,tomcat6.0作为web运行服务器。

2开发步骤

2.1搭建web项目

关于搭建web项目相关的文档网上有很多,在此略过。搭建成功后项目结构如下图

使用spring security 2.0 和extjs 3.0实现web登录

项目依赖的jar包如下图

使用spring security 2.0 和extjs 3.0实现web登录

2.2编辑登录页面

2.2.1 index.jsp源码

本项目中把index.jsp作为登录页面。代码如下:

<%@ taglib prefix='c' uri='http://Java.sun.com/jstl/core_rt' %>

<%@ page import="org.springframework.security.ui.AbstractProcessingFilter" %>

<%@ page import="org.springframework.security.ui.webapp.AuthenticationProcessingFilter" %>

<%@ page import="org.springframework.security.AuthenticationException" %>

<c:set var="ctx" value="${pageContext.request.contextPath}"/>

<%

String path = request.getContextPath();

String basePath = request.getScheme() + "://"

+ request.getServerName() + ":" + request.getServerPort()

+ path + "/";

String strLocale = request.getParameter("locale");

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<title>Spring Security + ExtJS Login</title>

<!-- Ext JS files -->

<link rel="stylesheet" type="text/css" href="${ctx}/ext-3.0.0/resources/css/ext-all.css"/>

<script src="${ctx}/ext-3.0.0/adapter/ext/ext-base.js"></script>

<script src="${ctx}/ext-3.0.0/ext-all.js"></script>

<!-- login form -->

<script src="${ctx}/js/login.js"></script>

</head>

<body>

<br><br><br><br><br>

<center>

<div id="login"></div>

</center>

</body>

</html>

2.2.2 index.jsp源码说明

在Index.jsp文件中,代码“<link rel="stylesheet" type="text/css" href="${ctx}/ext-3.0.0/resources/css/ext-all.css" />”是引用extjs的样式。代码“<script src="${ctx}/ext-3.0.0/adapter/ext/ext-base.js"></script>”是加载extjs基本包。

代码“<script src="${ctx}/ext-3.0.0/ext-all.js"></script>”是加载extjs核心包。

代码“<script src="${ctx}/js/login.js"></script>”extjs登录表单。关于login.js的内容,将会在后面小节中介绍。

2.2.3 login.js源码

login.js文件中定义的就是extjs登录表单。代码如下:

Ext.onReady(function(){

Ext.QuickTips.init();

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,

items:[{

fieldLabel:'Username',

name:'j_username',

allowBlank:false

},{

fieldLabel:'Password',

name:'j_password',

inputType:'password',

allowBlank:false

}],

buttons:[{

text:'Login',

formBind: true,

handler:function(){

login.getForm().submit({

method:'POST',

success:function(){

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

if (btn == 'ok'){

window.location = 'main.action';

}

});

},

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');

});

2.2.4 index.js源码说明

在index.js中定义了一个login表单,url:'j_spring_security_check'对应spring security的登录验证地址。表单里放了两个输入域'j_username'、'j_password',分别对应用户名和密码。表单中还有一个登录按钮'Login',点击按钮提交到后台执行登录验证。验证成功跳转到'main.action',验证失败则提示失败信息。'main.action'是在spring mvc中定义访问地址。具体见2.3节,配置spring mvc.

2.3配置spring mvc

本项目中的spring mvc用到2个文件,src目录下com.loiane.controller.MainController.java和WEB-INF目录下的spring-security-extjs-login-servlet.xml。

2.3.1 spring-security-extjs-login-servlet.xml源码

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

<beans xmlns="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-2.5.xsd">

<bean name="/*.action" class="com.loiane.controller.MainController">

</bean>

</beans>

2.3.2 spring-security-extjs-login-servlet.xml源码说明

spring-security-extjs-login-servlet.xml用于URL地址映射,把类似"/*.action"的请求地址映射到com.loiane.controller.MainController.java控制器类做进一步处理,文件中有一句代码:“<bean name="/*.action" class="com.loiane.controller.MainController"></bean>”。

2.3.3 com.loiane.controller.MainController.java源码

package com.loiane.controller;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

public class MainController extends MultiActionController  {

public ModelAndView main(HttpServletRequest request,

HttpServletResponse response) throws Exception {

return new ModelAndView("main.jsp");

}

}

2.3.4 com.loiane.controller.MainController.java源码说明

com.loiane.controller.MainController.java继承

org.springframework.web.servlet.mvc.multiaction.MultiActionController.java类,跳转到main.jsp。

2.3.5 main.jsp源码

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

pageEncoding="ISO-8859-1"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Spring Security + ExtJS Login</title>

</head>

<body>

<h1>You are successfully authenticated!</h1>

</body>

</html>

2.4配置spring security

本项目中的spring security用到2个文件,src目录下com.loiane.security.MyAuthenticationProcessingFilter.java和WEB-INF目录下的applicationContext-security.xml。

2.4.1 applicationContext-security.xml源码

<?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

admin/111111

dianne/111111

scott/111111

peter/111111

These passwords are from spring security app example

-->

<security:authentication-provider>

<security:password-encoder hash="md5"/>

<security:user-service>

<security:user name=" admin " password="96e79218965eb72c92a549dd5a330112" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />

<security:user name="dianne" password="96e79218965eb72c92a549dd5a330112" authorities="ROLE_USER,ROLE_TELLER" />

<security:user name="scott" password="96e79218965eb72c92a549dd5a330112" authorities="ROLE_USER" />

<security:user name="peter" password="96e79218965eb72c92a549dd5a330112" authorities="ROLE_USER" />

< /security:user-service>

</security:authentication-provider>

</beans>

2.4.2 applicationContext-security.xml源码说明

在applicationContext-security.xml文件中配置登录权限验证。

<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>

这段配置表示:我们要保护应用程序中的/*.action的URL,只有拥有ROLE_USER角色的用户才能访问。任何角色的用户都可以访问/index.jsp。你可以使用多个<intercept-url>元素为不同URL的集合定义不同的访问需求,它们会被归入一个有序队列中,每次取出最先匹配的一个元素使用。所以你必须把期望使用的匹配条件放到最上边。entry-point-ref="authenticationProcessingFilterEntryPoint"表示定义一个权限验证的入口authenticationProcessingFilterEntryPoint。

<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>

这段配置定义自定义权限处理过滤器com.loiane.security.MyAuthenticationProcessingFilter,defaultTargetUrl指定验证成功或失败后转向的页面,authenticationManager引用权限管理器。

<bean id="authenticationProcessingFilterEntryPoint"      class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">

<property name="loginFormUrl" value="/index.jsp" />

<property name="forceHttps" value="false" />

</bean>

这段配置定义权限验证入口,指定登录页面为/index.jsp,不使用https协议。

<security:authentication-provider>

<security:password-encoder hash="md5"/>

<security:user-service>

<security:user name="admin" password="96e79218965eb72c92a549dd5a330112" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />

<security:user name="dianne" password="96e79218965eb72c92a549dd5a330112" authorities="ROLE_USER,ROLE_TELLER" />

<security:user name="scott" password="96e79218965eb72c92a549dd5a330112" authorities="ROLE_USER" />

<security:user name="peter" password="96e79218965eb72c92a549dd5a330112" authorities="ROLE_USER" />

< /security:user-service>

</security:authentication-provider>

</beans>

这段配置定义了4个用户,密码使用md5加密,admin密码为111111拥有ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER三个角色、dianne密码为111111拥有ROLE_USER,ROLE_TELLER两个角色、scott密码为111111拥有ROLE_USER角色、peter密码为111111拥有ROLE_USER角色。

2.4.3 com.loiane.security.MyAuthenticationProcessingFilter.java源码

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();

}

}

2.4.4 com.loiane.security.MyAuthenticationProcessingFilter.java源码说明

com.loiane.security.MyAuthenticationProcessingFilter.java继承于

org.springframework.security.ui.webapp.AuthenticationProcessingFilter.java类,重写了

onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult)和onUnsuccessfulAuthentication( HttpServletRequest request, HttpServletResponse response, AuthenticationException failed )方法。在onSuccessfulAuthentication()方法中返回验证成功后的跳转地址,在onUnsuccessfulAuthentication()方法中返回验证失败的信息。

2.5配置web.xml

2.5.1 web.xml源码

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

<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>spring-security-extjs-login</display-name>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>

/WEB-INF/spring-security-extjs-login-servlet.xml

/WEB-INF/applicationContext-security.xml

</param-value>

</context-param>

<filter>

<filter-name>springSecurityFilterChain</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

</filter>

<filter-mapping>

<filter-name>springSecurityFilterChain</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<listener>    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<servlet>

<servlet-name>spring-security-extjs-login</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>spring-security-extjs-login</servlet-name>

<url-pattern>*.action</url-pattern>

</servlet-mapping>

<welcome-file-list>

<welcome-file>index.jsp</welcome-file>

</welcome-file-list>

</web-app>

2.5.1 web.xml源码说明

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>

/WEB-INF/spring-security-extjs-login-servlet.xml

/WEB-INF/applicationContext-security.xml

</param-value>

</context-param>

<filter>

这段代码配置spring使用的相关配置文件。/WEB-INF/spring-security-extjs-login-servlet.xml是关于spring mvc的相关配置。/WEB-INF/applicationContext-security.xml是关于登录权限验证相关的配置。

<filter>

<filter-name>springSecurityFilterChain</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

</filter>

<filter-mapping>

<filter-name>springSecurityFilterChain</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

这段代码配置spring过滤链。处理所有URL地址。

<listener>    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

这段代码注册spring监听器。

<servlet>

<servlet-name>spring-security-extjs-login</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>spring-security-extjs-login</servlet-name>

<url-pattern>*.action</url-pattern>

</servlet-mapping>

这段代码注册spring mvc,处理*.action的请求。

2.6运行效果

登录页面

使用spring security 2.0 和extjs 3.0实现web登录

登录页面-验证成功提示

使用spring security 2.0 和extjs 3.0实现web登录

登录页面-验证成功后跳转到main.jsp页面

使用spring security 2.0 和extjs 3.0实现web登录

登录页面-验证失败提示

使用spring security 2.0 和extjs 3.0实现web登录

3参考文档

http://loianegroner.com/2010/02/integrating-spring-security-with-extjs-login-page/#comments

上一篇:进入MFC讲坛的前言(二)


下一篇:[原创] debian 9.3 搭建Jira+Confluence+Bitbucket项目管理工具(二) -- 安装jira 7.5.4