上周研究了一下Acegi安全框架在SSH中的应用,一开始就因为Acegi配置文件的加载方式困惑了几天,到底是加在以插件的形式在struts配置文件struts-config.xml里声明还是在部署描述符web.xml里声明?最后得出答案,在web.xml里声明。正如Acegi宣称的那样,它将低耦合地与你已有应用系统做无缝结合。下面就它的初级应用做个介绍。
其中,需要用到的jar包有: acegi-security-1.0.3.jar acegi-security-cas-1.0.3.jar commons-codec-1.3.jar 1. 首先是部署描述符web.xml <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<!-- 容器启动参数 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-acegi-security.xml</param-value>
</context-param>
<!-- 字符编码过滤器 -->
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>com.xps.util.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Acegi过滤器 -->
<filter>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>org.acegisecurity.util.FilterChainProxy</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- struts控制器初始化配置 -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>3</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 用于Acegi的context装载的监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 系统默认主页 -->
<welcome-file-list>
<welcome-file>/jsp/index.jsp</welcome-file>
</welcome-file-list>
</web-app> 红色部分是应用Acegi需要添加的,首先context-param将Acegi的配置文件作为容器启动参数装载进去,而FilterToBeanProxy正如它名字表示的一样,是一个过滤器代理,它负责将不同的资源对应到各个过滤器中去,ContextLoaderListener用于context装载情况的监听。 2. 其次是比较复杂的Acegi配置文件applicationContext-acegi-security.xml。 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 为Acegi数据库验证准备的数据源配置 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/xgame</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>123456</value>
</property>
</bean>
<!-- 过滤器链代理 -->
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,logoutFilter,
authenticationProcessingFilter,securityContextHolderAwareRequestFilter,
rememberMeProcessingFilter,anonymousProcessingFilter,
exceptionTranslationFilter,filterInvocationInterceptor
</value>
</property>
</bean>
<!-- 会话的context整合过滤器 -->
<bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/>
<!-- 注销过滤器 -->
<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/jsp/index.jsp"/> <!-- URL redirected to after logout -->
<constructor-arg>
<list>
<ref bean="rememberMeServices"/>
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>
<!-- 认证处理过滤器 -->
<bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/jsp/login.jsp"/>
<property name="defaultTargetUrl" value="/login.do"/>
<property name="filterProcessesUrl" value="/j_acegi_security_check"/>
<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>
<bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>
<!-- Cookie登录的过滤器 -->
<bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>
<!-- 匿名登录处理的过滤器 -->
<bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
<property name="key" value="changeThis"/>
<property name="userAttribute" value="anonymousUser,AUTH_ANONYMOUS"/>
</bean>
<!-- 异常处理过滤器 -->
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/jsp/login.jsp"/>
<property name="forceHttps" value="false"/>
</bean>
</property>
<property name="accessDeniedHandler">
<bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
<property name="errorPage" value="/jsp/noGrant.jsp"/>
</bean>
</property>
</bean>
<!-- 过滤拦截器 -->
<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref local="httpRequestAccessDecisionManager"/></property>
<property name="objectDefinitionSource">
<value>
PATTERN_TYPE_APACHE_ANT
<!-- 所有用户的权限 -->
/searchUser.do=AUTH_USER,AUTH_ROOT,AUTH_RELEASER,AUTH_AUDITOR
/updateInformation.do=AUTH_USER,AUTH_ROOT,AUTH_RELEASER,AUTH_AUDITOR
<!-- 普通用户的权限 -->
/preOrderAd.do=AUTH_USER
/orderAd.do=AUTH_USER
/myAdList.do=AUTH_USER
/findReOrderAd.do=AUTH_USER
/ReOrder.do=AUTH_USER
<!--==== 超级管理员的权限 ====-->
<!-- 审核员的权限 -->
/noaudit.do=AUTH_AUDITOR,AUTH_ROOT
/allAuditAdNoPass.do=AUTH_AUDITOR,AUTH_ROOT
/auditedAd.do=AUTH_AUDITOR
/audited.do=AUTH_AUDITOR,AUTH_ROOT
/notify.do=AUTH_AUDITOR,AUTH_ROOT
/editAuditedEmail.do=AUTH_AUDITOR,AUTH_ROOT
<!-- 发布员的权限 -->
/unpaymentOrderList.do=AUTH_RELEASER,AUTH_ROOT
/paymentOrderList.do=AUTH_RELEASER,AUTH_ROOT
<!-- 超级管理员的权限 -->
/manageAdpos.do=AUTH_ROOT
/manageUser.do=AUTH_ROOT
/addNewAdpos.do=AUTH_ROOT
</value>
</property>
</bean>
<!-- 请求获取仲裁管理器 -->
<bean id="httpRequestAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
</list>
</property>
</bean>
<!-- Cookie服务器 -->
<bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="jdbcDaoImpl"/>
<property name="key" value="changeThis"/>
</bean>
<!-- 认证管理器 -->
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/>
<bean class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key" value="changeThis"/>
</bean>
<bean class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="changeThis"/>
</bean>
</list>
</property>
</bean>
<!-- 进行简单的基于数据库的身份验证 -->
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="jdbcDaoImpl"/>
<property name="userCache">
<bean class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
</property>
<property name="cacheName" value="userCache"/>
</bean>
</property>
</bean>
</property>
</bean>
<!-- 用户名密码匹配验证并返回UserDetails -->
<bean id="jdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
<property name="usersByUsernameQuery">
<value>select username, password, enabled from user where username = ? and enabled = 1</value>
</property>
<property name="authoritiesByUsernameQuery">
<value>
select u.username, a.authority
from user u, authorities a, user_auth ua
where u.id=ua.user_id and a.id=ua.auth_id and u.username=?
</value>
</property>
</bean>
<!-- 登录日志监听器,只用于记录日志,(可选) -->
<bean id="loggerListener" class="org.acegisecurity.event.authentication.LoggerListener"/>
<!-- 权限投票器,主要用于权限前缀的设定 -->
<bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter">
<property name="rolePrefix" value="AUTH_"/>
</bean>
</beans>
一般在用户登录以后需要用session来记录用户信息以便需要的地方调用,因此你可以在登录成功以后转向LoginAction,在这个Action里面你可以将用户名存在seesion里,然后再mapping到显示登录成功的页面,代码如下:
package com.xps.controller.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.userdetails.UserDetails;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class LoginAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
String username = null;
//从Acegi的Context中获取用户信息
Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(obj instanceof UserDetails){
username = ((UserDetails)obj).getUsername();
}else{
username = obj.toString();
}
HttpSession session = request.getSession(true);
session.setAttribute("username", username);
return mapping.findForward("success");
}
}
上面Acegi配置文件红色部分根据自己的需要修改。对于Acegi配置文件的说明,已经有很多朋友讲得比较清楚了,我也就不用多赘述,在下篇文章中蓝色字体是引用一位网友的(它用的Acegi版本是acegi-security-0.8.3.jar,所以有些包可能有不同),如果上面没看懂的可以结合下边的解释理解。注:蓝色字段为引用部分,由于internet上转载太多,未能找到原出处,请见谅
在applicationContext-acegi-security.xml中
FILTER CHAIN
FilterChainProxy会按顺序来调用这些filter,使这些filter能享用Spring ioc的功能, CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON定义了url比较前先转为小写, PATTERN_TYPE_APACHE_ANT定义了使用Apache ant的匹配模式
基础认证
1) authenticationManager
起到认证管理的作用,它将验证的功能委托给多个Provider,并通过遍历Providers, 以保证获取不同来源的身份认证,若某个Provider能成功确认当前用户的身份,authenticate()方法会返回一个完整的包含用户授权信息的Authentication对象,否则会抛出一个AuthenticationException。
Acegi提供了不同的AuthenticationProvider的实现,如:
DaoAuthenticationProvider 从数据库中读取用户信息验证身份
AnonymousAuthenticationProvider 匿名用户身份认证
RememberMeAuthenticationProvider 已存cookie中的用户信息身份认证
AuthByAdapterProvider 使用容器的适配器验证身份
CasAuthenticationProvider 根据Yale中心认证服务验证身份, 用于实现单点登陆
JaasAuthenticationProvider 从JASS登陆配置中获取用户信息验证身份
RemoteAuthenticationProvider 根据远程服务验证用户身份
RunAsImplAuthenticationProvider 对身份已被管理器替换的用户进行验证
X509AuthenticationProvider 从X509认证中获取用户信息验证身份
TestingAuthenticationProvider 单元测试时使用
每个认证者会对自己指定的证明信息进行认证,如DaoAuthenticationProvider仅对UsernamePasswordAuthenticationToken这个证明信息进行认证。
2) daoAuthenticationProvider
进行简单的基于数据库的身份验证。DaoAuthenticationProvider获取数据库中的账号密码并进行匹配,若成功则在通过用户身份的同时返回一个包含授权信息的Authentication对象,否则身份验证失败,抛出一个AuthenticatiionException。
3) passwordEncoder
使用加密器对用户输入的明文进行加密。Acegi提供了三种加密器:
PlaintextPasswordEncoder—默认,不加密,返回明文.
ShaPasswordEncoder—哈希算法(SHA)加密
Md5PasswordEncoder—消息摘要(MD5)加密
4) jdbcDaoImpl
用于在数据中获取用户信息。 acegi提供了用户及授权的表结构,但是您也可以自己来实现。通过usersByUsernameQuery这个SQL得到你的(用户ID,密码,状态信息);通过authoritiesByUsernameQuery这个SQL得到你的(用户ID,授权信息)
5) userCache & resourceCache
缓存用户和资源相对应的权限信息。每当请求一个受保护资源时,daoAuthenticationProvider就会被调用以获取用户授权信息。如果每次都从数据库获取的话,那代价很高,对于不常改变的用户和资源信息来说,最好是把相关授权信息缓存起来。(详见 2.6.3 资源权限定义扩展 )
userCache提供了两种实现: NullUserCache和EhCacheBasedUserCache, NullUserCache实际上就是不进行任何缓存,EhCacheBasedUserCache是使用Ehcache来实现缓功能。
6) basicProcessingFilter
用于处理HTTP头的认证信息,如从Spring远程协议(如Hessian和Burlap)或普通的浏览器如IE,Navigator的HTTP头中获取用户信息,将他们转交给通过authenticationManager属性装配的认证管理器。如果认证成功,会将一个Authentication对象放到会话中,否则,如果认证失败,会将控制转交给认证入口点(通过authenticationEntryPoint属性装配)
7) basicProcessingFilterEntryPoint
通过向浏览器发送一个HTTP401(未授权)消息,提示用户登录。
处理基于HTTP的授权过程,在当验证过程出现异常后的"去向",通常实现转向、在response里加入error信息等功能。
8) authenticationProcessingFilterEntryPoint
当抛出AccessDeniedException时,将用户重定向到登录界面。属性loginFormUrl配置了一个登录表单的URL,当需要用户登录时,authenticationProcessingFilterEntryPoint会将用户重定向到该URL
HTTP安全请求
1) httpSessionContextIntegrationFilter
每次request前 HttpSessionContextIntegrationFilter从Session中获取Authentication对象,在request完后, 又把Authentication对象保存到Session中供下次request使用,此filter必须其他Acegi filter前使用,使之能跨越多个请求。
2) httpRequestAccessDecisionManager
经过投票机制来决定是否可以访问某一资源(URL或方法)。allowIfAllAbstainDecisions为false时如果有一个或以上的decisionVoters投票通过,则授权通过。可选的决策机制有ConsensusBased和UnanimousBased
3) roleVoter
必须是以rolePrefix设定的value开头的权限才能进行投票,如AUTH_ , ROLE_
4)exceptionTranslationFilter
异常转换过滤器,主要是处理AccessDeniedException和AuthenticationException,将给每个异常找到合适的"去向"
5) authenticationProcessingFilter
和servlet spec差不多,处理登陆请求.当身份验证成功时,AuthenticationProcessingFilter会在会话中放置一个Authentication对象,并且重定向到登录成功页面
authenticationFailureUrl定义登陆失败时转向的页面
defaultTargetUrl定义登陆成功时转向的页面
filterProcessesUrl定义登陆请求的页面
rememberMeServices用于在验证成功后添加cookie信息
6) filterInvocationInterceptor
在执行转向url前检查objectDefinitionSource中设定的用户权限信息。首先,objectDefinitionSource中定义了访问URL需要的属性信息(这里的属性信息仅仅是标志,告诉accessDecisionManager要用哪些voter来投票)。然后,authenticationManager掉用自己的provider来对用户的认证信息进行校验。最后,有投票者根据用户持有认证和访问url需要的属性,调用自己的voter来投票,决定是否允许访问。
7) filterDefinitionSource
自定义DBFilterInvocationDefinitionSource从数据库和cache中读取保护资源及其需要的访问权限信息
方法调用安全控制
1) methodSecurityInterceptor
在执行方法前进行拦截,检查用户权限信息
2) methodDefinitionSource
自定义MethodDefinitionSource从cache中读取权限
<bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
<property name="objectDefinitionSource" ref="methodDefinitionSource"/>
</bean>
<bean id="methodDefinitionSource" class="org.springside.modules.security.service.acegi.DBMethodDefinitionSource">
<property name="acegiCacheManager" ref="acegiCacheManager"/>
</bean>
3. 最后是登录页面login.jsp
<html>
<head>
<title>用户登录</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body topmargin="0">
<form action="j_acegi_security_check" method="POST">
<table>
<tr><td>用户名:</td><td><input type='text' name='j_username'></td></tr>
<tr><td>密码:</td><td><input type='password' name='j_password'></td></tr>
<tr>
<td><input name="submit" type="submit" value="登录"></td>
<td><input name="reset" type="reset" value="重置"></td>
</tr>
</table>
</form>
</body>
</html>
红色部分必须用Acegi固定的命名,如果要注销,只需要加上<a href="j_acegi_logout">注销</a>,如果还需要将登录信息记录到cookie中,可以用<input type="checkbox" name="_acegi_security_remember_me">Don't ask for my password for two weeks,这样用户就在两周内不用登录也能访问到系统了。
后记,其实Acegi在认证授权方面功能是非常强大的,这无愧于它的复杂配置- -!我只是用它做了一点初级的应用,对于一些高级功能(比如方法级的访问控制等),以后用到了再研究。
分享到:
相关推荐
SSH(Struts+Spring+Hibernate)是Java企业级应用开发中常见的技术栈,它提供了强大的模型-视图-控制器(MVC)架构支持,以及持久层和业务层的优秀解决方案。本教程通过构建一个简单的电子公告板示例,揭示了SSH组合...
"Struts+Spring+Hibernate" 是一种经典的Java Web开发架构,通常被称为SSH框架。这个登陆系统是基于这三个框架构建的,下面将详细解释每个框架及其在登录系统中的作用。 **Struts** Struts是一个开源的MVC(Model-...
总结,Acegi Security与SSH(Spring、Struts2、Hibernate)的结合提供了一种强大的方式来构建安全的Web应用程序。通过基于角色的权限控制,我们可以有效地管理用户的访问权限,提高系统的整体安全性。虽然Acegi ...
通过SSH整合,开发者可以充分利用每个框架的优点,如Struts2的MVC能力、Spring的管理和事务处理、以及Hibernate的数据持久化。这样的整合有助于提高开发效率,降低维护成本,使得Java Web应用更加健壮和可扩展。在...
这篇文档将探讨如何使用Acegi,以及SSH(Struts 2、Spring、Hibernate)栈搭建一个安全的RBAC系统。 首先,我们需要下载相关的软件和库,如Java 5、Tomcat 5.5.26、Struts 2.0.11、Spring 2.5.1、Hibernate 3.2以及...
Struts2、Spring2和Hibernate3是经典的Java企业级开发框架组合,通常称为SSH框架。这个项目是一个基于SSH的登录实现,使用Oracle数据库,并且仅依赖一张由Hibernate配置自动生成的表。对于初学者来说,这是一个很好...
Struts2、Spring和Hibernate是Java Web开发中的三大框架,它们的整合应用极大地提升了开发效率和项目的可维护性。这个整合方案通常被称为SSH(Struts2、Spring、Hibernate)集成,是过去许多企业级项目中首选的技术...
Struts2、Spring和Hibernate是Java企业级开发中三大核心框架,它们的整合应用被称为SSH(Struts2-Spring-Hibernate)集成。本教程旨在帮助开发者理解如何在Eclipse环境中搭建一个基于SSH的完整应用程序。 Struts2是...
在本文中,我们将深入探讨一个基于Struts2、Spring4和Hibernate5的权限管理系统——"crm_ssh"项目。这个项目展示了如何将这三个流行的技术栈整合在一起,为业务逻辑提供一个强大的支持平台。 **Struts2** 是一个...
在IT行业中,SSH(Spring、Struts和Hibernate)是一个经典的Java Web开发框架组合,用于构建高效、可维护的Web应用程序。这个"使用spring+struts+hibernate实现的登录"示例是一个基础教程,适合初学者理解这三大框架...
在安全方面集成Spring的安全框架Acegi和最流行的Ajax技术。与其他框架相比,它提供了各种Web系统开发过程中都需要开发的一些功能,如登陆、用户密码加密,用户管理、根据不同的用户可以展现不同的菜单,同时还带有...
以上就是关于"SSH集成Spring+hibernate+security 用户管理"项目的主要知识点,涵盖了Spring框架的依赖注入、Hibernate的ORM、Spring Security的权限控制,以及如何在实际项目中综合运用这些技术。这样的系统设计有助...
当这两个框架结合使用时,通常被称为“SSH”(Struts2、Spring、Hibernate)集成框架,可以提供强大的功能和灵活性,以构建高效、可维护的企业级应用。 Struts2框架: 1. **Action和结果**:Struts2的核心是Action...
Struts2、Hibernate和Spring是Java Web开发中的三大框架,它们各自在不同的层面上解决了Web应用中的问题。Struts2负责MVC(Model-View-Controller)架构的实现,提供强大的动作控制和拦截器机制;Hibernate是对象...
SSH指的是Spring、Struts和Hibernate三个开源框架的首字母缩写,而Acegi则是Spring Security的前身,负责处理应用的安全访问控制。在本系统中,这些技术被融合在一起,提供了一个高效、安全的Web应用解决方案。 ...
Struts2.3.7、Spring3.2和Hibernate4.1.8是经典的Java Web开发框架组合,常被称为SSH框架。这个组合为开发者提供了强大的MVC(模型-视图-控制器)架构支持,数据库持久化处理以及依赖注入功能。下面我们将详细探讨这...
本文将详细介绍如何利用Acegi安全框架(现称为Spring Security)结合SSH(Struts + Spring + Hibernate)技术栈来实现一个动态的角色权限管理系统。 #### Acegi安全框架简介 Acegi安全框架,后更名为Spring ...
在“SSH集成Spring+Hibernate+Security UMS用户管理”项目中,我们将深入探讨如何利用这些技术来构建一个完整的用户管理系统,包括用户的身份验证、授权和权限控制。 首先,Spring作为整个应用的核心,负责管理Bean...
SSH代表Spring、Struts和Hibernate,这三大框架分别是应用层的IoC容器、MVC框架和持久层ORM解决方案。DWR则是Dynamic Web Rendering的缩写,它允许在浏览器端直接调用服务器端的Java方法,实现富客户端应用。 ...
Struts、Spring 和 Hibernate 是 Java 开发中三大主流框架,它们常常被联合使用,被称为 SSH(Struts-Spring-Hibernate)集成框架。这个"宠物医院例子"是一个基于 SSH 框架的实战项目,旨在帮助开发者理解如何在实际...