我可以在Apache CXF上实现的RESTful资源上使用@RolesAllowed吗?

时间:2013-05-08 05:31:29

标签: rest jersey authorization cxf jax-rs


我的问题是 “我可以在CXF上实现的RESTful资源上使用@RolesAllowed吗?”

首先,我解释导致这个问题的背景 我正在开发一些项目,其中开发人员必须将某些Web系统的一部分重新编译为RESTful WEB Apis。此现有系统具有由SpringHibernate构建的服务器系统。它的客户端应用程序作为UI由ActionScript开发 FLEX framework
现在我正在通过阅读一些文档或开发一些原型来调查设计和重构我们现有系统的正确方法。因此,我们暂时决定使用RESTful APIs作为Apache-CXF ver.2.7.4实现JAX-RS作为Web应用程序容器
然后,我正在努力争取用户授权的方式。 如您所知,我的意思是TOMCAT ver.7这个词作为一些控制机制,限制某些用户根据用户的滚动访问功能,如'Authorization'ROLE_ADMIN等等。我们的团队想要使用ROLL_EMPLOYEE注释,用于约束用户访问@RolesAllowed资源类中的某些RESTful方法 通过调查,我知道如果我们使用REST作为@RolesAllowed实现和TOMCAT,我们可以使用Jersey注释,因为Jersey框架提供了

com.sun.jersey.api.container.filter.RolesAllowedResourceFilterFactory
开发人员通过在web.xml中添加以下行来激活@RolesAllowed注释

JAX-RS

作为jersey的ServletContainer的init-param。

但是我们的团队决定将<init-param> <param-name>com.sun.jersey.spi.container.ResourceFilters</param-name> <param-value> com.sun.jersey.api.container.filter.RolesAllowedResourceFilterFactory </param-value> </init-param> 作为JAX-RS实现。我已经在CXF网站上调查了Web文档的安全和授权部分。但我无法获得解决方案或如何在RESTful资源方法上使用Apache CXF

因此,如果您了解@RolesAllowed@RolesAllowed上实施的RESTful资源的要求或如何使用Apache CXF,请告诉我。或者如果您能明确断定我们可以在TOMCAT@RolesAllowed的框架选择中使用Apache CXF,请告诉我该结论的背景知识。

此外,我认为我可以在TOMCAT @RolesAllowed上的CXF中使用JBOSS作为应用服务器,而不是TOMCAT。这个假设是真的吗?对不起,我没有试用JBOSS代替TOMCAT。

最好的问候。

1 个答案:

答案 0 :(得分:4)

是的,这可以做到。我假设你(像我一样)不想使用Spring Security作为解决方案的一部分(处理身份验证和授权),因为似乎有很多关于如何使用Spring Security启用JSR-250注释的资源。

我的解决方案始于一个简单的JAX-RS项目,该项目是从CXF提供的Archetype项目org.apache.cxf.archetype:cxf-jaxrs-service:2.7.5构建的(最新的GAV @写作时间)。

这为您提供了一个支持配置文件的基本HelloWorld类。

需要进行一些修改。

首先,将以下依赖项添加到pom.xml

<dependency>
  <groupId>javax.annotation</groupId>
  <artifactId>jsr250-api</artifactId>
  <version>1.0</version>
</dependency>
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.0.1</version>
  <scope>provided</scope>
</dependency>   

为什么呢?因为Tomcat不是完整的J2EE容器,所以它不支持所有JSR-250注释(其中@RolesAllowed是一个)。此外,虽然CXF识别并将与@RolesAllowed一起使用,但它不捆绑实现,期望它由J2EE容器提供或包含上述api。

列出了servlet-api因为我需要@编译时间来添加到HellowWorld.java的方法(见下文)。

其次,修改beans.xml如下:

<bean class="my.pkg.HelloWorld" id="helloWorldService"/>

<jaxrs:serviceBeans>
   <ref bean="helloWorldService"/>
</jaxrs:serviceBeans>

<bean id="authorizationInterceptor"
      class="org.apache.cxf.interceptor.security.SecureAnnotationsInterceptor">
  <property name="securedObject" ref="helloWorldService" />
</bean>

SecureAnnotationsInterceptor将扫描helloWorldService并强制执行@RolesAllowed注释。

请注意,必须从helloWorldService节中提取<jaxrs:serviceBeans>,以便可以在authorizationInterceptortomcat-users.xml中引用它。

第三,将一些角色和用户添加到<role rolename="hello-user" /> <role rolename="hello-role1"/> <role rolename="hello-role2" /> <user username="hello1" password="Password1" roles="hello-role1,hello-user"/> <user username="hello2" password="Password1" roles="hello-role2,hello-user"/> 或替代(例如JDBC Realm等)我这样做了:

hello-user

这会创建2个用户,每个用户都有一个共享角色(web.xml)加上他们自己的独特角色。

第四,将以下内容添加到BASIC以启用<security-constraint> <web-resource-collection> <web-resource-name>Hello Services</web-resource-name> <url-pattern>/hello/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>hello-user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>default</realm-name> </login-config> 身份验证:

hello-user

有了这个,我决定为/hello/*下的所有内容要求HelloWorld.java角色。这不是必需的,但要注意我确实有一些问题忽略了一些节,通配符和角色...所以在这里试验一下。

第五(最后),标记@Path("/hello") @RolesAllowed("hello-user") public class HelloWorld { @GET @Path("/echo/{input}") @Produces("text/plain") @RolesAllowed("hello-role1") public String ping(@PathParam("input") String input) { return input; } @POST @Produces("application/json") @Consumes("application/json") @Path("/jsonBean") @RolesAllowed("hello-role2") public Response modifyJson(JsonBean input) { input.setVal2(input.getVal1()); return Response.ok().entity(input).build(); } @GET @Produces("text/plain") @Path("/cliche") public Response getClichedMessage(@Context HttpServletRequest request) { return Response. ok(). entity("Sending \"Hello World\" to user \"" + request.getUserPrincipal().getName() + "\""). build(); } } 类:

getClichedMessage()

我添加了最后一个方法(hello-user)以显示两个用户都可以访问该方法,因为他们具有注释类的SecureAnnotationsInterceptor角色。 @RolesAllowed非常聪明,可以解决这个问题。

这就是全部。在我看来,这是使用Tomcat,CXF和BASIC authenitcation的STTCPW。 CXF + SecureAnnotationsInterceptor的关键是@RolesAllowed

更新:我应该承认Converting Jersey REST Examples to Apache CXF特别有帮助,特别是指出SecureAnnotationsInterceptor,其{{1}}的连接在其他地方没有很好地记录。

更新2 :Jersey-CXF博客条目似乎未迁移到gmazza's new blog。但是,example I used is on github。它包含config file with SecureAnnotationsInterceptor definitionbean with @RolesAllowed annotation