acegi升级为spring security2.0后配置有很大不同,按照老的配置方式需要更改很多包路径,以及属性名,这需要在源代码中查找,如果配置好是没有问题的。新的配置是基于老的方式并进行了简化,就直接给出我的配置作为参考:
新的配置方式:
<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.4.xsd">
<security:http auto-config="true" access-denied-page="/login.faces">
<security:intercept-url pattern="/jsp/*/yourpath" access="ROLE_COMMISSAR, ROLE_DRAFTOFFICE, ROLE_TRANSACT, ROLE_DRAFTSUPER, ROLE_URGER"/>
<security:intercept-url pattern="/jsp/*/yourpath" access="ROLE_LETTERPUBLIC,ROLE_LETTERTRANSACT,ROLE_LETTERTASTER,ROLE_LETTERPROCESS"/>
<security:intercept-url pattern="/jsp/*/yourpath" access="ROLE_POPULARSUBMIT,ROLE_POPULARPROCESS"/>
<security:intercept-url pattern="/**/*.gif" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:intercept-url pattern="/**/*.gif" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:intercept-url pattern="/**/*.jpg" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:intercept-url pattern="/**/*.css" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:intercept-url pattern="/login.faces" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<security:form-login
default-target-url="/"
always-use-default-target="true"
login-page="/login.faces"
login-processing-url="/j_spring_security_check"
authentication-failure-url="/login.faces"
/>
<security:anonymous key="doesNotMatter" username="anonymousUser"/>
<security:concurrent-session-control
max-sessions="1"
exception-if-maximum-exceeded="false"
expired-url="/login.faces"/>
<security:logout logout-url="/j_spring_security_logout" logout-success-url="/login.faces" />
</security:http>
<security:authentication-provider>
<security:jdbc-user-service
data-source-ref="dataSource"
users-by-username-query="SELECT USER_, PASSWORD_, SIGN_ FROM ORM_USER WHERE USER_= ?"
authorities-by-username-query="select user0_.USER_ as col_0_0_, role2_.VALUE_ as col_1_0_ from ORM_USER user0_ inner join ORM_USER_ROLE roles1_ on user0_.ID_=roles1_.USERID_ inner join ORM_ROLE role2_ on roles1_.ROLEID_=role2_.ID_ where user0_.USER_=?"
cache-ref="userCache"
/>
</security:authentication-provider>
<bean id="userCache" class="org.springframework.security.providers.dao.cache.EhCacheBasedUserCache">
<property name="cache"><ref local="userCacheBackend"/></property>
</bean>
<bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager"> <ref local="cacheManager"/> </property>
<property name="cacheName"> <value>userCache</value> </property>
</bean>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
<!-- This bean is optional; it isn't used by any other bean as it only listens and logs -->
<bean id="loggerListener" class="org.springframework.security.event.authentication.LoggerListener" />
<!-- <bean id="customAuthenticationFilter" class="**.authorization.CustomAuthenticationFilter">
<security:custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/>
</bean> 使用自定义的过滤器,参考spring security中不同的自定义位置名称-->
</beans>
jsf集成:
jsf跳转机制使用的是redirect,所以登录的信息就不能很好的传递给acegi,根据myfaces wiki提供的方式:创建登录使用的loginBean,注意不要使用seam的@Name注册为seam组件,直接使用jsf的managed-bean机制注册成backingbean
public String login() throws IOException, ServletException
{
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
RequestDispatcher dispatcher = ((ServletRequest) context.getRequest())
.getRequestDispatcher("/j_spring_security_check");
dispatcher.forward((ServletRequest) context.getRequest(),
(ServletResponse) context.getResponse());
FacesContext.getCurrentInstance().responseComplete();
// It's OK to return null here because Faces is just going to exit.
logger.debug("=================================================" +
((HttpServletRequest)context.getRequest()).getSession().getId());
HttpSession session = ((HttpServletRequest)context.getRequest()).getSession();
// session.setAttribute(LOGIN_PROCESS, new Boolean(true));
//这是调整seam的集成部分
ContextControl.instance().begin(session);
//createAuthData(session, user);
return null;
}
public String logout() throws IOException, ServletException
{
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
RequestDispatcher dispatcher = ((ServletRequest) context.getRequest())
.getRequestDispatcher("/j_spring_security_logout");
dispatcher.forward((ServletRequest) context.getRequest(),
(ServletResponse) context.getResponse());
FacesContext.getCurrentInstance().responseComplete();
// It's OK to return null here because Faces is just going to exit.
logger.debug("=================================================" +
((HttpServletRequest)context.getRequest()).getSession().getId());
HttpSession session = ((HttpServletRequest)context.getRequest()).getSession();
//这是调整seam的集成部分
ContextControl.instance().begin(session);
return null;
}
jsf页面的做法
<t:inputText id="j_username" forceId="true" styleClass="form1" size="20" value="#{loginBean.userName}"></t:inputText>
<t:inputSecret id="j_password" forceId="true" styleClass="form1" size="20" value="#{loginBean.password}"
<h:commandButton value="登录" action="#{loginBean.login}"></h:commandButton>
seam的集成:
因为在登录过程中,acegi注销掉了上一个session,创建了一个新的session,那么SeamListener这个session监听器就会执行sessionDestroyed和sessionCreated,但是seam并不认为你是真正销毁了所有的上下文包括request和application,我认为这是seam为了在页面过期的环境中使用,因为它的原则是由seam的Seam.invalidateSession()来处理session的销毁(事实上根本就没有销毁session而是给出了销毁的标记,也许这样就可以由它的内部解决所有上下文的管理)。那么就会产生异常,同样在这一次请求中seam的阶段监听也会产生异常,因为Conversation绑定的session仍然是已经过期的session。我的做法很傻,hack了!
一:自定义SeamListener
@Override
public void sessionCreated(HttpSessionEvent event) {
// TODO Auto-generated method stub
super.sessionCreated(event);
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
// TODO Auto-generated method stub
// event.getSession().getAttribute("org.jboss.seam.sessionInvalid");
try {
super.sessionDestroyed(event);
} catch (IllegalStateException e) {
// TODO: handle exception
Seam.invalidateSession();
HttpSession session = event.getSession();
ContextControl.instance().end(session.getServletContext(), new ServletSessionImpl(session));
}
}
二 创建自定义的seam上下文控制类,直接操作各个上下文,对于session销毁和创建手动去清理或者创建其他各上下文实例。因为各个上下文的操作都是protect,所以只有将类建在它的包下了!
package org.jboss.seam.contexts;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.core.ConversationEntries;
import org.jboss.seam.servlet.ServletSessionImpl;
public class ContextControl {
private static final Log log = LogFactory.getLog(ContextControl.class);
private static final ContextControl contextControl = new ContextControl();
public static ContextControl instance() {
return contextControl;
}
public void begin(HttpSession session) {
boolean applicationContextActive = Contexts.isApplicationContextActive();
boolean eventContextActive = Contexts.isEventContextActive();
boolean conversationContextActive = Contexts.isConversationContextActive();
if ( !applicationContextActive )
{
Context tempApplicationContext = new WebApplicationContext(session.getServletContext());
Contexts.applicationContext.set(tempApplicationContext);
}
Context tempEventContext = null;
if ( !eventContextActive )
{
tempEventContext = new MapContext(ScopeType.EVENT);
Contexts.eventContext.set(tempEventContext);
}
Context tempConversationContext = null;
if ( !conversationContextActive )
{
tempConversationContext = new MapContext(ScopeType.CONVERSATION);
Contexts.conversationContext.set(tempConversationContext);
}
Context tempSessionContext = new WebSessionContext(new ServletSessionImpl(session));
Contexts.sessionContext.set(tempSessionContext);
//instantiate all session-scoped @Startup components
for ( String name : Contexts.getApplicationContext().getNames() )
{
Object object = Contexts.getApplicationContext().get(name);
if ( object!=null && (object instanceof Component) )
{
Component component = (Component) object;
if ( component.isStartup() && component.getScope() == ScopeType.SESSION )
{
startup(component);
}
}
}
}
public void end(ServletContext servletContext, ContextAdaptor session) {
Context tempApplicationContext = new WebApplicationContext(servletContext);
Contexts.applicationContext.set(tempApplicationContext);
//this is used just as a place to stick the ConversationManager
Context tempEventContext = new MapContext(ScopeType.EVENT);
Contexts.eventContext.set(tempEventContext);
//this is used (a) for destroying session-scoped components
//and is also used (b) by the ConversationManager
Context tempSessionContext = new WebSessionContext(session);
Contexts.sessionContext.set(tempSessionContext);
Set<String> conversationIds = ConversationEntries.instance().getConversationIds();
log.debug("destroying conversation contexts: " + conversationIds);
for (String conversationId: conversationIds)
{
Lifecycle.destroyConversationContext(session, conversationId);
}
//we need some conversation-scope components for destroying
//the session context...
Context tempConversationContext = new MapContext(ScopeType.CONVERSATION);
Contexts.conversationContext.set(tempConversationContext);
log.debug("destroying session context");
Contexts.destroy(tempSessionContext);
Contexts.sessionContext.set(null);
Contexts.destroy(tempConversationContext);
Contexts.conversationContext.set(null);
Contexts.destroy(tempEventContext);
Contexts.eventContext.set(null);
Contexts.applicationContext.set(null);
}
private static void startup(Component component)
{
if ( component.isStartup() )
{
for ( String dependency: component.getDependencies() )
{
Component dependentComponent = Component.forName(dependency);
if (dependentComponent!=null)
{
startup( dependentComponent );
}
}
}
if ( !component.getScope().getContext().isSet( component.getName() ) )
{
log.info("starting up: " + component.getName());
component.newInstance();
}
}
}
这些只是我的做法!
注意的地方:
websphere 6.1.0.3以上版本默认对于找不到资源的url路径直接过滤到错误页面,这样spring的/j_spring_security_check是访问不到的,需要参考
http://topic.csdn.net/u/20080620/14/9c05c7d7-a6a0-4646-95b2-4bdadcb1002c.html
分享到:
相关推荐
《MyFaces 全集:深入理解myfaces-all.jar.zip》 ...理解MyFaces的核心概念和组件,以及如何有效地集成和使用,对于Java Web开发者来说至关重要。同时,尊重并遵守开源许可证的规定,也是每个开发者应有的责任。
在"Apache MyFaces Scripting.zip"的文件中,你可能会找到示例代码、教程文档,或者用于演示如何在MyFaces中集成和使用脚本的项目。通过深入研究这些内容,你可以进一步了解如何在实际项目中利用MyFaces的脚本功能...
开发者可以根据项目需求选择合适的版本,如MyFaces Core 2.x或3.x。 总结来说,Apache MyFaces Core是构建JavaEE Web应用的强大工具,它为开发者提供了丰富的组件库、灵活的扩展机制以及与其他JavaEE技术的紧密集成...
MyFaces以其灵活性、稳定性和高性能而受到开发者欢迎,可以与许多其他开源项目(如Tomcat、Struts、Hibernate等)无缝集成。 **CHM(Compiled Help Manual)**文件是一种Windows平台下的帮助文档格式,它是HTML文档...
1. **组件库**:Trinidad包含了一套全面的UI组件,如按钮、输入字段、表格、树形结构、对话框等,这些组件都是可重用的,并且具有多种风格和主题,可以根据需求进行定制。 2. **数据模型**:Trinidad支持数据绑定,...
1. **灵活性**:MyFaces提供了更多的定制选项,开发者可以根据需求选择不同的组件库和渲染器。 2. **社区驱动**:MyFaces有一个活跃的开发者社区,这意味着不断有新的特性和改进被引入,问题能得到快速解决。 3. **...
综上所述,`myfaces-core-2.0.1-bin.zip`包含了MyFaces JSF实现的核心组件,开发者可以通过这个压缩包快速地在项目中集成MyFaces,利用其丰富的功能和组件来构建高效、可维护的Web应用程序。在实际开发中,理解...
jar包,官方版本,自测可用
aop.jar spring-beans.jar spring-context.jar spring-core.jar spring-dao.jar spring-hibernate.jar spring-jdbc.jar spring-mock.jar spring-orm.jar spring-remoting.jar spring-...
此外,随着技术的演进,更现代的MyFaces版本如2.x和3.x可能引入了更多功能和性能优化,对于新项目,选择较新的版本可能是更好的选择。 总之,myfaces-all-1.1.1.jar作为MyFaces框架的一个重要组成部分,它在Java ...
1. **JSF教程文档**:这些文档可能详细介绍了JSF的基础知识,如何创建和配置JSF项目,以及如何使用JSF的标签库。 2. **示例代码**:可能会有一些示例应用程序,展示JSF组件的用法,以及如何处理用户事件。 3. **...
jar包,官方版本,自测可用
jar包,官方版本,自测可用
JSF及Myfaces帮助.CHM
一、`org.apache.myfaces.SERIALIZE_STATE_IN_SESSION` 此参数控制MyFaces是否将组件状态存储在会话中。默认值为`true`,意味着组件状态会在每个请求之间序列化并存储在用户的会话中。如果设置为`false`,状态将...
MyFaces是JavaServer Faces(JSF) Web框架 (JSR 127)的一个实现。JavaServer(tm) Faces Web框架是一个新的实现MVC模式的规范.它可以与Struts框架相媲美甚至的一些特性与观念已经超过了Struts.【FacesIDE:Eclipse下的...
**JSF 2.0 源码解析:MyFaces 2.0.4 API + Impl** JavaServer Faces (JSF) 是一个用于构建企业级Web应用的Java框架,它提供了一种组件化的方式来创建用户界面。JSF 2.0是其一个重要版本,引入了许多新特性以提升...
6. **CDI 集成**:MyFaces 可以与 Contexts and Dependency Injection (CDI) 框架集成,提供依赖注入和上下文管理功能。 7. **EL 表达式语言**:JSF 使用统一的 Expression Language (EL) 与模型数据进行交互,...
http://www.ibiblio.org/maven/myfaces/jars/ myfaces-extensions-1.0.9.jar
myfaces+ajax4jsf+spring+jpa+chartCreate 配置备忘 完整eclipse项目源代码