在Karaf中使用Spring Security处理JAX-RS捆绑包

22
我有一个使用JAX-RS处理一些REST服务的OSGi bundle。这个bundle在Karaf中运行,使用Apache CXF。我需要对某些路径/方法组合应用基本的http身份验证。我一直在尝试使用Spring Security,而新的3.1版本似乎可以做到这一点,但是我一直在尝试在OSGi中让它正常工作。
只是为了测试,我创建了一个非常简单的beans.xml文件:
<beans>
    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-extension-http.xml"/>
    <import resource="classpath:META-INF/cxf/osgi/cxf-extension-osgi.xml"/>

    <jaxrs:server id="serverTest" address="/test">
        <jaxrs:serviceBeans>
            <ref bean="tstSvr"/>
        </jaxrs:serviceBeans>
    </jaxrs:server>

    <bean id="tstSvr" class="com.demo.Test"/>

    <security:http auto-config="true">
        <security:intercept-url pattern="/admin/**" access="ROLE_ADMIN" method="PUT" />
        <security:intercept-url pattern="/**" access="ROLE_USER" />
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="user" password="pass" authorities="ROLE_USER"/>
                <security:user name="admin" password="pass" authorities="ROLE_ADMIN"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

现在,有趣的部分来了...从我读过的所有内容中,我需要一个web.xml才能让这些工作。例如我尝试使用的这个示例:
<web-app>
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

使用这两个文件的组合没有起作用。当我说“没有起作用”时,我的意思是什么都没有发生。没有错误消息,没有异常,捆绑功能就像在尝试添加Spring安全性之前一样运行。我认为问题在于捆绑包需要成为WAR或WAB才能加载web.xml。这正确吗?

更重要的是,有没有一种方法可以在没有web.xml的情况下让Spring工作?

我正在假设我需要将捆绑包保留为捆绑包,以便CXF加载它,因此我不能完全确定是否是这种情况。

感谢您提供的任何帮助!

更新: 经过大量搜索,我发现一个论坛帖子提到在清单中添加Web-FilterMappings:springSecurityFilterChain; url-patterns:="/*"而不是使用web.xml。但是,似乎仍然需要使用WAB而不是普通捆绑包。我已经在我的清单中添加了该行,但没有效果。看来我的问题正在变成:如何在CXF中使用WAB?

更新2: 因为这个问题还不够长...我决定尝试使用Spring Security注释而不是intercept-url,只是想看看会发生什么。当我尝试访问受保护的路径时,我得到了这个有趣的堆栈跟踪:

Caused by: org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:323)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:196)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)[46:org.springframework.aop:3.0.5.RELEASE]

Spring的网站称,这是您第一次尝试匿名连接到安全服务时发生的情况,并且第二次不会再发生。对我来说,每次都会发生。从异常中看,似乎我的清单条目已被拾取,也许问题与我想象的不同。有人有关于为什么会发生这种情况的想法吗?我是否忽略了beans.xml中的某个条目以使基本HTTP身份验证工作?


这并不能回答你的问题,但它可能会帮助你得到一些想法 https://dev59.com/73I-5IYBdhLWcg3wYXL8 - Zoidberg
你尝试过没有OSGI方面的纯CXF / Spring Security吗?如果我们能够确定问题是与CXF / Spring还是与OSGI有关,那将非常有用。 - user404345
1个回答

6
首先,您需要清楚了解Spring和web.xml的作用。
Web.xml是配置Servlet容器的标准文件,通常是应用服务器(如Jboss、Glassifsh、Jetty、Tomcat)。
beans.xml是Spring应用程序上下文的配置文件,如果没有使用任何名称空间进行配置,则表示Karaf使用Spring oob。
如果要在没有容器的情况下使用Servlets进行Http操作,我想您需要注册一个HttpService,请参见:http://karaf.apache.org/manual/latest-2.2.x/users-guide/http.html 当映射方法中找不到安全上下文中的Authentication bean时,会发生异常。您没有在映射中定义任何匿名访问权限,这可能是失败的原因。
基本上,要么定义AnonymousAuthenticationFilter,要么在http配置中使用permitAll定义URL模式。否则,在匿名连接的第一次尝试中,您将继续收到该异常。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接