0

这是一个复杂的问题,所以我会尽可能清楚地解释它。我有三个OSGi捆绑包A,B部署CApache Karaf. 我还有一个安全捆绑包,这些A捆绑包使用它BC

每个A,BCbundles 都包含以下内容:

<osgi:reference id="basicAuthHandlerFactory" interface="com.groupgti.security.handler.basicauth.BasicAuthHandlerFactory"/>

<bean id="securityHandler" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" ref="basicAuthHandlerFactory"/>
    <property name="targetMethod" value="createSecurityHandler"/>
    <property name="arguments">
        <list>
            <value type="java.lang.String">A.realm</value> <!-- The realm is depending on a bundle, A.realm, B.realm, C.realm -->
        </list>
    </property>
</bean>

Spring从安全包中获取安全处理程序的代码片段。安全包中的此处理程序作为OSGi服务公开并在安全包中创建,如下所示:

<bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler" scope="prototype">
    <property name="authenticator">
        <bean class="org.eclipse.jetty.security.authentication.BasicAuthenticator"/>
    </property>
    <property name="constraintMappings">
        <list>
            <ref bean="constraintMapping"/>
        </list>
    </property>
    <property name="strict" value="false"/>
    <property name="identityService" ref="identityService"/>
</bean>

<bean id="basicAuthSecurityHandler" class="com.groupgti.security.handler.basicauth.BasicAuthFactoryHandlerImpl"/>
<osgi:service ref="basicAuthSecurityHandler" interface="com.groupgti.security.handler.basicauth.BasicAuthHandlerFactory"/>

BasicAuthFactoryHandlerImpl#createSecurityHandler(String realm)用于为每个捆绑包创建不同的安全处理程序实例。如上面的代码所示,当createSecurityHandler方法被调用时,领域由包传递。Spring MethodInvokingFactoryBean

securityHandler Springbean 有一个原型,在这种scope情况下,每次调用该方法时,都会getBean返回一个新创建的对象。

我为安全处理程序设置的领域是这样的:

public class BasicAuthFactoryHandlerImpl implements BeanFactoryAware, BasicAuthHandlerFactory {

    private static final Logger LOGGER = LoggerFactory.getLogger(BasicAuthFactoryHandlerImpl.class);

    private BeanFactory factory;

    @Override
    public ConstraintSecurityHandler createSecurityHandler(String realm) {
        ConstraintSecurityHandler handler = (ConstraintSecurityHandler) factory.getBean("securityHandler");
        handler.setUserRealm(realm);
        LOGGER.debug("Security handler created. Got realm: {}", realm);
        return handler;
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.factory = beanFactory;
    }
}

创建每个捆绑包的处理程序,一切都很好。但问题是所有捆绑包的领域在某种程度上与从第一个启动捆绑包传递的领域相同。我确信我Spring在不同捆绑包中的每个配置中传递了不同的领域,但领域总是来自第一个启动的捆绑包并且它无法正常工作。

有人知道问题出在哪里吗?

4

3 回答 3

0

问题是您从 beanFactory 获得了单个“securityHandler”。所以只有一个共享实例。在 createSecurityHandler 中,您应该创建一个新对象并返回它。

于 2012-09-22T07:15:02.807 回答
0

我能够弄清楚为什么同一个实例在应用程序之间共享的问题。我所有的 bundle和A,都使用了这个:BC

<httpj:engine-factory bus="cxf">
    <httpj:engine port="8020">
        <httpj:threadingParameters minThreads="5" maxThreads="15"/>
        <httpj:handlers>
            <ref bean="securityHandler"/>
            <ref bean="ipFilteringHandler"/>
        </httpj:handlers>
        <httpj:sessionSupport>true</httpj:sessionSupport>
    </httpj:engine>
</httpj:engine-factory>

创建安全处理程序并为所有这些处理程序Jetty使用相同的端口8020。而且它无法处理同一端口上的不同处理程序。如果我将端口更改为完全不同,则一切正常。但这不是我的解决方案。解决方案是让所有捆绑软件都使用一个领域。

于 2012-09-24T08:21:14.670 回答
0

AFAIR 这里的问题更多地是spring进行代理的方式。因为代理是针对服务参考而不是服务完成的。您可能需要正确配置它以使用正确的代理。

我认为以下内容可能会有所帮助:

ServiceReference nativeReference = ((ServiceReferenceProxy)serviceReference).getTargetServiceReference() 
于 2012-09-24T08:38:56.773 回答