我有一个Spring Webflow应用程序,该应用程序具有启动项,该项设置了许多与该应用程序的当前用户相关的上下文变量-它们的ID,其应用程序角色等。一项启动方法调用失败,引发以下错误
org.springframework.expression.spel.SpelEvaluationExpression EL1004E:在com.sun.proxy。$ Proxy61类型上找不到方法调用userisAuthorized(java.lang.String,null)
org.springframework.webflow.execution ActionExecutionException:执行[AnnotatedAction @ 18864e3f targetAction = [EvaluateAction @ 197b16ad expression = userService.userisAuthorized(flowScope.UserUid,flowScope.isRoleBased),resultExpression = flowScope.userAuthorized,属性= map [ [empty]]状态为'requestAccess'流的状态为'null'-操作执行属性为'map [[empty]]'
然而,真正的问题是:应用程序实际上确实为除一个特定用户外的所有用户成功地在userService bean上成功调用了userisAuthorized方法。
进行一些动态调试,并参考这个有用的SO帖子Listing Aspect-proxied beans in Spring,我已经能够确定自动接线确实找到了userService。但是它以com.sun.proxy。$ Proxy6 3 而不是$ Proxy6 1 的形式加载到应用程序上下文中。
由于错误似乎与调用时登录的用户有关,所以我猜测在实际的userService之前,上下文中可能还会注入其他代理,这可能与Spring安全配置有关,Spring是由于某种原因,它与userService bean的实际代理混淆了。但是我无法终生弄清楚为什么会发生这种情况-应用程序中的任何地方都没有其他类具有isuserAuthorized方法,并且无论如何Spring安全配置无论如何都不会扫描服务包。>
安全配置
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- Enable auto-wiring -->
<context:annotation-config/>
<!-- Scan for auto-wiring classes in spring saml packages --> <=== package that have security proxies do NOT include service
<context:component-scan base-package="org.trinityhealth.sarequest.security"/>
<context:component-scan base-package="org.trinityhealth.sarequest.dao" />
<context:component-scan base-package="org.trinityhealth.sarequest.model" />
webflow配置
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<on-start>
<evaluate expression="systemAccessService.populateUserInformation(flowScope.accessRequest)" />
<evaluate expression="externalContext.globalSessionMap.userUid" result="flowScope.userUid"/>
<evaluate expression="externalContext.globalSessionMap.isRoleBased" result="flowScope.isRoleBased"/>
<evaluate expression="externalContext.globalSessionMap.userRhmId" result="flowScope.userRhmId"/>
<evaluate expression="userService.userisAuthorized(flowScope.userUid, flowScope.isRoleBased)" result="flowScope.userAuthorized"/> <=== the failing method call
<evaluate expression="userService.readRoleFromSecurityContext()" result="flowScope.loggedInUserRole"/>
<set name="conversationScope.hideSteps" value="'N'" />
</on-start>
.
.
.
服务bean接口
package org.trinityhealth.sarequest.service; <=== not in security, dao, or model package
.
. various import statements
.
public interface UserService {
.
. bunch of method definitions, none named userisAuthorized or having a (String,char) signature
.
public boolean userisAuthorized(String thisUserId, char isRoleBased);
}
.
.
.
带有注释的服务bean实现
package org.trinityhealth.sarequest.service; <=== not in security, dao, or model package
.
. various import statements
.
@Service("userService")
public class UserServiceImpl implements UserService {
.
. bunch of implemented Methods, none named userisAuthorized or having a (String,char) signature
.
@Override
@Transactional
public boolean userisAuthorized(String thisUserId, char isRoleBased) {
.
. implementation of userisAuthorized, which works if on-start expresssion selects correct bean
.
}
}