【问题标题】:Use spring security with cxf on karaf - issue with custom filter在 karaf 上使用带有 cxf 的 spring security - 自定义过滤器的问题
【发布时间】:2013-11-11 09:13:39
【问题描述】:

我目前正在尝试在一个 cxf REST 服务上使用 spring-security(hmac 身份验证和授权),作为一个捆绑包部署在 Karaf 中。 (karaf 2.3、cxf 2.7.6 和 spring security 3.1.4) 我的问题是我总是得到一个

 org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext

每当我尝试找到一种方法时。显然,我无法让过滤器链工作也许链接到这个https://issues.apache.org/jira/browse/DOSGI-183,因为我在我的弹簧安全日志中有这个:

Checking sorted filter chain: [Root bean: class[org.springframework.security.web.context.SecurityContextPersistenceFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 200, <hmacAuthenticationFilter>, order = 800, Root bean: class [org.springframework.security.web.savedrequest.RequestCacheAwareFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1300, Root bean: class [org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1400, Root bean: class [org.springframework.security.web.access.ExceptionTranslationFilter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1900, <org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0>, order = 2000]

无论如何,这是我的代码:

首先我在一个包A中得到了authenticationFilter和authenticationProvider,分别扩展了AbstractAuthenticationProcessingFilter和AbstractUserDetailsAuthenticationProvider。 过滤器被暴露为 osgi:service,authenticationManager 也是围绕提供者构建的

 <security:authentication-manager alias="defaultAuthenticationManager" erase-credentials="true">
    <security:authentication-provider ref="hmacAuthProvider"/>    
</security:authentication-manager>
<osgi:service ref="hmacAuthenticationFilter" interface="com.security.auth.IHmacAuthenticationFilter"/>
<osgi:service ref="defaultAuthenticationManager" interface="org.springframework.security.authentication.AuthenticationManager"/>

这就是逻辑认证和授权逻辑所在。

现在服务: 一个简单的资源

@Path("test")
public class PocRessource {
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("m1")
@PreAuthorize("hasRole('ROLE_M1')")
public String m1() {
    return "calling m - 1";
}

还有spring applicationContext

<beans  --schema goes here --
default-lazy-init="false">
<context:annotation-config />
<context:component-scan base-package="com.security.webservice"/>
<osgi:reference id="hmacAuthenticationFilter" interface="com.security.auth.IHmacAuthenticationFilter"/>
 <osgi:reference id="authenticationManager" interface="org.springframework.security.authentication.AuthenticationManager"/>

<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<bean id="pocRessource" class="com.security.webservice.PocRessource"/>
<bean id="forbiddenEntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<security:global-method-security pre-post-annotations="enabled"/>
<security:http disable-url-rewriting="true" entry-point-ref="forbiddenEntryPoint" use-expressions="true"
    create-session="never" authentication-manager-ref="authenticationManager">
    <security:anonymous enabled="false"/>
    <security:session-management session-fixation-protection="none"/>
    <security:custom-filter ref="hmacAuthenticationFilter" position="FORM_LOGIN_FILTER"/>
    <security:intercept-url pattern="/**" access="isFullyAuthenticated()"/>
</security:http>
<jaxrs:server id="pocsecurityWS" address="/pocs/security">
    <jaxrs:inInterceptors>
         <ref bean="logInbound"/>
     </jaxrs:inInterceptors>
     <jaxrs:outInterceptors>
        <ref bean="logOutbound"/>
     </jaxrs:outInterceptors>
    <jaxrs:serviceBeans>
      <ref bean="pocRessource"/>
    </jaxrs:serviceBeans>
</jaxrs:server>
</beans>

bundle 是通过 maven 生成的

    <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <extensions>true</extensions>
                            <configuration>
                <supportedProjectTypes>
                  <supportedProjectType>jar</supportedProjectType>
                  <supportedProjectType>bundle</supportedProjectType>
                  <supportedProjectType>war</supportedProjectType>
                </supportedProjectTypes>
                <instructions>
                      <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
                      <DynamicImport-Package>*</DynamicImport-Package>
                      <Web-FilterMappings>springSecurityFilterChain;url-patterns:="/*"</Web-FilterMappings> 
                  </instructions>
            </configuration>
        </plugin>

我错过了什么?

谢谢!

【问题讨论】:

    标签: spring-security cxf apache-karaf


    【解决方案1】:

    好的,经过几天的尝试,我设法使用 .... Jersey 做到了这一点!显然,javax.servlet.Filter 方式不是 CXF 的方式。我想我必须把我的逻辑放在 AbstractPhaseInterceptor 中。任何人都可以确认吗?我会尝试实现一个

    对于那些感兴趣的人,这是我所做的:

    • 首先使用WAB(在pom中打包war,然后使用mavne bundle插件。注意将所有依赖项放在“provided”范围内)

      org.apache.felix maven 捆绑插件 真的

              <executions>
                  <execution>
                    <id>bundle-manifest</id>
                    <phase>process-classes</phase>
                    <goals>
                      <goal>manifest</goal>
                    </goals>
                  </execution>
            </executions>
      
              <configuration>
                  <supportedProjectTypes>
                    <supportedProjectType>jar</supportedProjectType>
                    <supportedProjectType>bundle</supportedProjectType>
                    <supportedProjectType>war</supportedProjectType>
                  </supportedProjectTypes>
      
                  <instructions>
                        <Bundle-SymbolicName>${project.groupId}.${project.artifactId} </Bundle-SymbolicName>
                        <Export-Package/>
                       <Import-Package>
                            javax.servlet;version="[2.5,3)",
                            javax.servlet.http;version="[2.5,3)",
                            org.springframework.core,
                            org.springframework.web.context,
                            org.springframework.web.context.request,
                            org.springframework.security.config,
                            org.springframework.osgi.config,
                            org.springframework.context.config,
                            org.springframework.osgi.web.context.support,
                            com.leguide.backoffice.poc.security.auth,
                            org.springframework.aop,
                            org.springframework.aop.framework,
                            *
                       </Import-Package>
                        <DynamicImport-Package>*</DynamicImport-Package>
                        <Bundle-ClassPath>.,WEB-INF/classes</Bundle-ClassPath>
                        <Embed-Directory>WEB-INF/lib</Embed-Directory>
                        <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
                        <Embed-Transitive>true</Embed-Transitive>
                        <Web-ContextPath>/pocsecurity/services</Web-ContextPath>
                        <Webapp-Context>/pocsecurity/services</Webapp-Context>
                        <Web-FilterMappings>springSecurityFilterChain;url-pattern:="/*"</Web-FilterMappings> 
                    </instructions>
              </configuration>
          </plugin>
      
    • 添加一个 web.xml 像:

      <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:META-INF/spring/applicationContext.xml</param-value>
      </context-param>
      <context-param>
          <param-name>contextClass</param-name>
          <param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value>
      </context-param>
      <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      <listener>
          <listener-class>
              org.springframework.web.context.request.RequestContextListener
          </listener-class>
      </listener>
      <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>
      

    在功能 xml 中使用正确的捆绑包(感谢Downloading all Jersey OSGi Bundle dependancies automatically),就是这样!

    我的 karaf 中确实有这些日志:

    2013-11-06 11:39:49,247 | DEBUG | services/pocs/m1 | WelcomeFilesFilter               | vice.internal.WelcomeFilesFilter  128 | 82 - org.ops4j.pax.web.pax-web-runtime - 1.1.14 | Path info: null
    2013-11-06 11:39:49,247 | DEBUG | services/pocs/m1 | ServletHandler                   | rvlet.ServletHandler$CachedChain 1297 | 65 - org.eclipse.jetty.util - 7.6.8.v20121106 | call filter springSecurityFilterChain
     2013-11-06 11:39:49,248 | DEBUG | services/pocs/m1 | HmacAuthenticationFilter         | ctAuthenticationProcessingFilter  189 | 84 - org.springframework.web - 3.2.3.RELEASE | Request is to process authentication
    2013-11-06 11:39:49,255 | DEBUG | services/pocs/m1 | FilterSecurityInterceptor        | cept.AbstractSecurityInterceptor  215 | 110 - org.springframework.security.core - 3.1.4.RELEASE | Authorization successful
    2013-11-06 11:39:49,256 | DEBUG | services/pocs/m1 | SecurityContextPersistenceFilter | SecurityContextPersistenceFilter   97 | 84 - org.springframework.web - 3.2.3.RELEASE | SecurityContextHolder now cleared, as request processing completed
    

    我确实遇到了码头返回 404 的问题,但我猜那是另一回事

    【讨论】:

    • 您能否提供上述解决方案的 applicationContext 详细信息?或者如果您有与所有 3 个文件相关的完整代码,您可以发送链接吗?
    • 抱歉,我没有代码了。它在 karaf 上根本不起作用。我们最终使用 come route 和端点 cxfrs ,在调用 hmac 实现之前使用 netty/jetty 路由。它有点像这样:从 netty -> 如果 hmac ok 然后继续,否则发送 401 。比试图在 karaf 上强制 WAR 更有效
    • 好的,谢谢。我现在能够实现。我稍后会发布解决方案
    猜你喜欢
    • 2018-05-25
    • 2011-07-23
    • 2015-07-10
    • 2011-08-23
    • 2014-07-28
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    相关资源
    最近更新 更多