Spring security Spring安全和OSGi

Spring security Spring安全和OSGi,spring-security,osgi,eclipse-virgo,Spring Security,Osgi,Eclipse Virgo,我试图在Virgo 3.6.0.M03上使用Spring Security 3.1.3创建一个简单的示例。 该示例由3个捆绑包组成: 安全捆绑包配置和发布AuthenticationManager <security:authentication-manager id="authenticationManager"> <security:authentication-provider> <security:user-service>

我试图在Virgo 3.6.0.M03上使用Spring Security 3.1.3创建一个简单的示例。 该示例由3个捆绑包组成:

  • 安全捆绑包配置和发布AuthenticationManager

    <security:authentication-manager id="authenticationManager">
       <security:authentication-provider>
          <security:user-service>
             <security:user name="Rigas" password="password" authorities="ROLE_MEMBER"/>
          </security:user-service>
       </security:authentication-provider>
    </security:authentication-manager>
    <service id="authenticationManagerOsgi" ref="authenticationManager" interface="org.springframework.security.authentication.AuthenticationManager"/>
    
    
    
  • helloSecurity捆绑包发布安全的helloWorld方法。它引用AuthenticationManager并将其注入全局方法安全性中

    <security:global-method-security secured-annotations="enabled" authentication-manager-ref="authenticationManager"/>
    <reference id="authenticationManager" availability="mandatory" interface="org.springframework.security.authentication.AuthenticationManager"/>
    <service id="helloSpringSecurityOsgi" ref="helloSpringSecurity" interface="net.ansible.examples.hellospringsecurity.HelloSpringSecurity" />
    
    
    
  • helloSecurityConsumer捆绑包引用HelloSecurityIF并调用安全的helloWorld方法

    <reference id="helloSpringSecurity" availability="mandatory" interface="net.ansible.examples.hellospringsecurity.HelloSpringSecurity"/>
    
    
    
绑定和连接工作正常,但一旦helloSecurityConsumer调用安全方法,就会引发以下异常:

Failed to call secure method org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'authenticationManager' must be of type [org.springframework.security.authentication.ProviderManager], but was actually of type [$Proxy94]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:360)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.security.config.method.GlobalMethodSecurityBeanDefinitionParser$AuthenticationManagerDelegator.authenticate(GlobalMethodSecurityBeanDefinitionParser.java:386)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.authenticateIfRequired(AbstractSecurityInterceptor.java:316)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:202)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:60)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
at net.ansible.examples.hellospringsecurity.impl.HelloSpringSecurityImpl$$EnhancerByCGLIB$$99e49c75.sayHello(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319)
at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.doInvoke(ServiceInvoker.java:56)
at org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.invoke(ServiceInvoker.java:60)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.eclipse.gemini.blueprint.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy95.sayHello(Unknown Source)
at net.ansible.examples.hellospringsecurityconsumer.impl.HelloSpringSecurityConsumerImpl$MyRunnable.run(HelloSpringSecurityConsumerImpl.java:50)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
调用安全方法org.springframework.beans.factory.BeanNotOfRequiredTypeException失败:名为“authenticationManager”的Bean必须是[org.springframework.security.authentication.ProviderManager]类型,但实际上是[$Proxy94]类型
位于org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:360)
位于org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
位于org.springframework.security.config.method.GlobalMethodSecurityBeanDefinitionParser$AuthenticationManagerDelegator.authenticate(GlobalMethodSecurityBeanDefinitionParser.java:386)
位于org.springframework.security.access.intercept.AbstractSecurityInterceptor.AuthenticateFrequeired(AbstractSecurityInterceptor.java:316)
位于org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:202)
位于org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:60)
位于org.springframework.aop.framework.ReflectiveMethodInvocation.procedue(ReflectiveMethodInvocation.java:172)
位于org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
在net.ansible.examples.hellospringsecurity.impl.HelloSpringSecurityImpl$$enhancerbyglib$$99e49c75.sayHello()上
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(未知源)
在sun.reflect.DelegatingMethodAccessorImpl.invoke处(未知源)
位于java.lang.reflect.Method.invoke(未知源)
位于org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319)
在org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.doInvoke(ServiceInvoker.java:56)上
位于org.eclipse.gemini.blueprint.service.importer.support.internal.aop.ServiceInvoker.invoke(ServiceInvoker.java:60)
位于org.springframework.aop.framework.ReflectiveMethodInvocation.procedue(ReflectiveMethodInvocation.java:172)
位于org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
位于org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
位于org.springframework.aop.framework.ReflectiveMethodInvocation.procedue(ReflectiveMethodInvocation.java:172)
位于org.eclipse.gemini.blueprint.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:57)
位于org.springframework.aop.framework.ReflectiveMethodInvocation.procedue(ReflectiveMethodInvocation.java:172)
位于org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
位于org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
位于org.springframework.aop.framework.ReflectiveMethodInvocation.procedue(ReflectiveMethodInvocation.java:172)
位于org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
售价$Proxy95.sayHello(未知来源)
在net.ansible.examples.hellospringsecurityconsumer.impl.HelloSpringSecurityConsumerImpl$MyRunnable.run(HelloSpringSecurityConsumerImpl.java:50)
位于java.util.concurrent.Executors$RunnableAdapter.call(未知源)
位于java.util.concurrent.FutureTask$Sync.innerRunAndReset(未知源)
位于java.util.concurrent.FutureTask.runAndReset(未知源)
位于java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(未知源)
位于java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(未知源)
位于java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(未知源)
位于java.util.concurrent.ThreadPoolExecutor$Worker.runTask(未知源)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(未知源)
位于java.lang.Thread.run(未知源)
GlobalMethodSecurityBeanDefinitionParser试图使用引用的AuthenticationManager,但在将OSGi引用周围的代理转换为ProviderManager时出现问题。 调试表明该代理(JDKDDynamicAOPProxy)确实是ProviderManager类周围的代理,并且具有所有相关接口。
是否有一个工作配置来实现我要做的事情?

这在我看来像个bug。引发错误的文件的第386行是

delegate = beanFactory.getBean(authMgrBean, ProviderManager.class);
它向bean工厂请求具有具体实现的bean
ProviderManager
,但它应该只请求具有接口
AuthenticationManager
的bean,如:

delegate = beanFactory.getBean(authMgrBean, AuthenticationManager.class);
你可能想在这张票上加价


顺便说一句:我们还将authenticationManager导出为OSGI服务,并在其他捆绑包中使用它,效果非常好。

我刚刚记得不久前我打开了一个bug报告,其中有一个类似的问题:()。我们还遇到了一个问题,需要ProviderManager实例,而不仅仅是AuthenticationManager实现。因此,代码中可能还有其他地方使用ProviderManager而不是AuthenticationManager。你是对的。修补GlobalMethodSecurityBeanDefinitionParser可以使一切正常工作。