在Karaf中的JAX-RS包上使用Spring Security

Jon*_*on7 22 java osgi cxf spring-security apache-karaf

我有一个OSGi包,它使用JAX-RS来处理一些REST服务.该捆绑包使用Apache CXF在Karaf中运行.我需要将基本的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>
Run Code Online (Sandbox Code Playgroud)

现在,这里有趣的部分...从我一直在做的所有阅读中,我需要一个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>
Run Code Online (Sandbox Code Playgroud)

使用这两个文件的组合不起作用.并且"没有用",我的意思是什么也没发生.没有错误消息,没有异常,捆绑功能就像我尝试添加spring security之前一样.我假设问题是bundle需要是一个WAR或WAB来加载web.xml.它是否正确?

更重要的是,有没有一种方法可以让没有web.xml的春天工作?

我正在假设我需要将捆绑包作为一个捆绑包供CXF加载它,所以我无法将其转换为WAR或WAB,但我并不完全确定是这种情况.

感谢您的任何帮助,您可以提供!

更新: 在做了一堆额外的谷歌搜索后,我发现了一个论坛帖子,提到添加Web-FilterMappings: springSecurityFilterChain;url-patterns:="/*"到您的清单而不是使用web.xml.但是,您仍然需要使用WAB而不是普通的捆绑包.我已将该行添加到我的清单中以防万一,但它没有任何效果.我的问题似乎转变为:如何在CXF中使用WAB?

更新2: 因为这个问题不够长......我决定尝试使用Spring Security注释而不是拦截 - 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]
Run Code Online (Sandbox Code Playgroud)

Spring网站说,这是在您第一次尝试匿名连接到安全服务时发生的,而且不会再次发生.好吧,它每次都发生在我身上.从例外,它看起来像我在清单项被拾起,也许这个问题比我想象的不同.有没有人想过为什么会这样?我是否遗漏了beans.xml中的一些条目以使基本的http auth工作?

Gep*_*ens 6

首先,您需要清楚地了解spring和web.xml的功能.

  • Web.xml是用于配置servlet容器的标准文件,它通常是一个应用程序服务器,如Jboss,Glassifsh,Jetty,Tomcat ......
  • 您的beans.xml是Spring应用程序上下文的配置文件,因为您没有使用任何命名空间,这意味着Karaf使用spring oob.

如果你想使用servlet做Http,没有容器,我想你必须注册一个HttpService,请参阅:http://karaf.apache.org/manual/latest-2.2.x/users-guide/http. HTML

您的异常发生,因为当它到达映射方法时,SecurityContext中没有Authentication bean.您没有在映射中定义任何匿名访问,也许这就是它失败的原因.

基本上,要么在http配置中定义AnonymousAuthenticationFilter,要么使用permitAll定义URL模式.否则,当您第一次尝试匿名连接同一会话时,您将继续获得该异常.