JAX-RS を使用していくつかの REST サービスを処理する OSGi バンドルがあります。このバンドルは、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>
さて、ここからが楽しい部分です...これまでのすべての読書から、これを機能させるには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>
これら 2 つのファイルを組み合わせて使用しても機能しませんでした。そして、「うまくいかなかった」とは、何も起こらなかったことを意味します。エラー メッセージも例外もありません。Spring セキュリティを追加する前と同じようにバンドルが機能しました。問題は、web.xml をロードするためにバンドルが WAR または WAB である必要があることだと思います。これは正しいです?
さらに重要なことに、web.xml なしでスプリングを機能させる方法はありますか?
私はバンドルを CXF がロードするためのバンドルとして保持する必要があるという前提で作業しているので、それを WAR または WAB に変換することはできませんが、そうであるかどうかは完全にはわかりません。
ご協力いただきありがとうございます。
更新:
追加のグーグル検索を行った後、web.xml を使用する代わりにマニフェストに追加することについて言及しているフォーラムの投稿を見つけました。Web-FilterMappings: springSecurityFilterChain;url-patterns:="/*"
ただし、通常のバンドルの代わりに WAB を使用する必要があるようです。念のためマニフェストに行を追加しましたが、効果はありません。私の質問は次のようになっているようです: CXF で WAB を使用するにはどうすればよいですか?
更新 2: この質問は十分に長くないため...何が起こるかを確認するためだけに、intercept-url の代わりに Spring Security アノテーションを使用することにしました。セキュリティで保護されたパスにアクセスしようとすると、次の楽しいスタック トレースが表示されます。
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 の Web サイトによると、これはセキュリティで保護されたサービスに初めて匿名で接続しようとしたときに発生し、2 回目は発生しないとのことです。まあ、それは私にとって毎回起こります。例外から、マニフェストのエントリが取得されているように見えますが、問題は思っていたものとは異なる可能性があります。なぜこれが起こっているのか、誰にも考えがありますか?基本的な http 認証を機能させるために、beans.xml にいくつかのエントリがありませんか?