弹簧安全 3.1 +JSF 2.0 。 ManagedBeans 中注释方法的问题?

Posted

技术标签:

【中文标题】弹簧安全 3.1 +JSF 2.0 。 ManagedBeans 中注释方法的问题?【英文标题】:Spring security 3.1 +JSF 2.0 . problem with annotating methods in ManagedBeans? 【发布时间】:2011-11-21 02:43:36 【问题描述】:

Hy。我想做的是将 Spring 安全性与 Jsf+spring IOC +hibernate 应用程序集成在一起。我已经设法设置登录页面并过滤其他一些页面。到目前为止一切都很好,但是当我尝试将 @Secured 或 @PreAuthorize 注释放在 managedBeans 内部的方法上(在 Dao 内部的注释确实有效),我意识到它们绝对什么都不做。我读过我需要 FORCE 类代理。 Spring使用基于代理的aop,托管bean实现了一个接口,因此使用jdk动态代理而不是类代理。所以我在我的配置文件中这样做了:

 <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"**    
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd         
http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<aop:aspectj-autoproxy proxy-target-class="true"/>
 //the rest of the beans
 </beans>

applicationContext-security Xml 如下所示:

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

 <!-- - Sample namespace-based configuration - - $Id: applicationContext-security.xml 
3019 2008-05-01 17:51:48Z luke_t $ -->

 <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.1.xsd">

<global-method-security secured-annotations="enabled"  jsr250-annotations="enabled"/>

<http pattern="/css/**" security="none" />
<http pattern="/pages/login.xhtml" security="none" />

<http auto-config='false'>
    <intercept-url pattern="/pages/customer/**" access='ROLE_SITE_ADMIN' />
    <intercept-url pattern="/pages/department/overhead*" access='ROLE_SITE_ADMIN' />
    <intercept-url pattern="/**"
        access='ROLE_SITE_ADMIN,ROLE_PROJECT_MANAGER,ROLE_DEPARTMENT_MANAGER,ROLE_ACCOUNTING' />
    <form-login login-page="/pages/login.xhtml"
        default-target-url='/pages/reports.xhtml' always-use-default-target='true'
        authentication-failure-handler-ref="userLoginService" />
    <logout invalidate-session="true" logout-success-url="/pages/login.xhtml"/>
</http>

<authentication-manager>
    <authentication-provider user-service-ref='userLoginService'>
        <password-encoder hash="md5" />
    </authentication-provider>
</authentication-manager>

<beans:bean id="userLoginService" class="com.evozon.demo.bean.SecureLoginService">
    <beans:property name="defaultFailureUrl" value="/pages/login.xhtml" />
    <beans:property name="userDao" ref="userDao" />
    <beans:property name="loginReportDao" ref="loginReportDao" />
</beans:bean>
 </beans:beans>

谁能告诉我为什么注释在托管 bean 中不起作用,以及如何解决这个问题?例如:

    @PreAuthorize("ROLE_PROJECT_MANAGER")
public void aproveVacation(Vacation vacation) ...

谢谢

【问题讨论】:

【参考方案1】:

问题已经解决了。解决方法是将Managed beans 转换为Spring beans。方法如下: web.xml 不需要 jsf 侦听器,只需要 sprin 侦听器:

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

应用程序上下文首先需要此配置才能工作:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd         
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">


<context:component-scan base-package="com.company.demo.bean" />
<context:annotation-config />
<aop:config proxy-target-class="true" />
//other configs
</beans>     

请注意,前两个需要为spring beans(用于组件)定义基础包并且bean被注释。第三个配置需要强制类代理,here is why you need that。 好的。一旦我们知道我们将注释从 jsf managedBeans 更改为 Spring 组件:

@ManagedBean
@SessionScoped
public class UserLoginBean 

@ManagedProperty(name = "userDao", value = "#userDao")
private UserDao userDao; 
   

到:

@Component
@Scope("session")
@Qualifier("userLoginBean")
public class UserLoginBean  

@Autowired
private UserDao userDao;
     

就是这样。如果你已经有了这个配置并且不能工作,你应该在你的 applicationContext.xml 中设置&lt;aop:config proxy-target-class="true" /&gt;

【讨论】:

以上是关于弹簧安全 3.1 +JSF 2.0 。 ManagedBeans 中注释方法的问题?的主要内容,如果未能解决你的问题,请参考以下文章

JSF Managed Beans 不使用 spring 安全过滤器

JSF 2.0;我的脸;仅使用 POST 提交表单

JSF 2.0 web.xml 错误页面状态码

我们可以集成 JSF 2.0 + Spring 4.2.X + Spring Security 4.2.X [重复]

JSF 语言环境:浏览器定义的语言似乎被忽略了

将新组件动态添加到 JSF 组件树时重复 id