它是实现 spring 安全和 CXF 网络服务的真正方法吗

Is it the true way to implement spring security & CXF webservice

我创建一个网络服务如下:

web.xml

<display-name>MyService</display-name>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/beans.xml,/WEB-INF/spring-security.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

<!-- Spring Security Filter -->
<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>

beans.xml

<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> 

<context:component-scan base-package="com.*" />

<jaxrs:server id="employeeService" address="/employeeservices">
    <jaxrs:providers>
        <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
    </jaxrs:providers>
    <jaxrs:serviceBeans>
        <ref bean="empService" />
    </jaxrs:serviceBeans>
    <jaxrs:extensionMappings>
        <entry key="xml" value="application/xml" />
        <entry key="json" value="application/json" />
    </jaxrs:extensionMappings>
</jaxrs:server>

<bean id="empService" class="com.service.impl.EmployeeServiceImpl"/>
<bean id="employeeDao" class="com.dao.EmployeeDao"/>

spring-security.xml

<http auto-config="true" use-expressions="true" create-session="stateless" >
    <csrf disabled="true"/>
    <http-basic entry-point-ref="restAuthenticationEntryPoint"></http-basic>
    <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
</http>

<beans:bean id="userAuthorService" class="com.auth.UserAuthorService"/>
<beans:bean id="restAuthenticationEntryPoint" class="com.auth.UserBasicAuthenticationEntryPoint">
    <beans:property name="realmName" value="Name Of Your Realm"/>
</beans:bean>

<authentication-manager>
    <authentication-provider user-service-ref="userAuthorService">
         <password-encoder ref="bcryptPasswordEncoder"/>
    </authentication-provider>
</authentication-manager>

<beans:bean id="bcryptPasswordEncoder"
    class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
    <beans:constructor-arg name="strength" value="5" />
</beans:bean>
<beans:bean id="loggerListener" class="org.springframework.security.authentication.event.LoggerListener"/>
  1. 这样配置,是请求流程的流程吗? : 请求 -> Spring 安全(检查身份验证) -> cxf -> 响应。

  2. 在real server上部署这个配置有什么问题吗?使用 cxf 和 spring 时的标准配置是什么?

  3. 当我调用正确的 uri 时:http://localhost:8089/MyService/rest/employeeservices/getemployeedetals?employeeId=004。没关系。 但是调用了错误的uri:http://localhost:8089/MyService/rest/employeeservices/getemployeedetallll?employeeId=004。它抛出异常:

WARNING: No operation matching request path "/MyService/rest/employeeservices/getemployeedetallll" is found, Relative Path: /getemployeedetal, HTTP Method: GET, ContentType: /, Accept: /,. Please enable FINE/TRACE log level for more details. Jun 07, 2016 1:55:17 PM org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper toResponse

WARNING: javax.ws.rs.ClientErrorException at org.apache.cxf.jaxrs.utils.SpecExceptions.toHttpException(SpecExceptions.java:110) at org.apache.cxf.jaxrs.utils.ExceptionUtils.toHttpException(ExceptionUtils.java:149) at org.apache.cxf.jaxrs.utils.JAXRSUtils.findTargetMethod(JAXRSUtils.java:477)

那么我如何在访问控制器之前过滤正确的 uri class。

请帮帮我。谢谢。

By this configuration, is it flow of request process? : request -> Spring security(check authentication) -> cxf -> response.

是的,因为 J2EE 过滤器是围绕 J2EE servlet 执行的(在 euqeust 之前和之后),所以 springSecurityFilterChain 将在 CXFServlet

之前执行

Are there any issues in this configuration when I deploy it in the real sever?

最新版本的 CXF 不需要这样做

<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> 

您也在 CXFServlet /rest/* 中捕获,但在 auth * 中捕获。这是一个问题吗?您是否需要无需身份验证的休息服务?如果我们不知道您系统的上下文,则很难分析问题。详细说明你的疑惑,我可以尽力帮助

what is the standard configuration when using cxf and spring ?

没有任何推荐的配置,因为 CXF 可以与 spring 或独立使用,jax-ws 或 jax-rs,作为服务器或作为客户端,通过 [=37 执行身份验证=] 安全性或与 jax-rs 服务器中的 RequestContextFilter 或 inInterceptor 集成,甚至在 CXF 总线中的全局级别。

如果您谈论的是配置所需的模块以便使用 spring 执行 CXF,那么您拥有所需的模块。

对于身份验证,您可以考虑使用 JWT 令牌而不是 bcrypt 密码。

when i call right uri:http://localhost:8089/MyService/rest/employeeservices/getemployeedetals?employeeId=004. its ok. But call wrong uri: http://localhost:8089/MyService/rest/employeeservices/getemployeedetallll?employeeId=004. It throw exception: WARNING: No operation matching request path

这个警告是正常的。服务器正在响应 http 错误代码 404-Not found,因为 rest/employeeservices/getemployeedetallll

没有可用资源

So how can i filter the right uri before access controller class.

如果找不到路径,CXF 会返回 404 来为您服务。这是正确的行为。你的意思是 CXF uri 过滤器在 spring-security 之前执行?您不能使用此配置,因为身份验证过滤器是以前的。