我的问题是
“我可以在CXF上实现的RESTful资源上使用@RolesAllowed吗?”。
首先,我解释导致这个问题的背景
我正在开发一些项目,其中开发人员必须将某些Web系统的一部分重新编译为RESTful
WEB Apis。此现有系统具有由Spring
和Hibernate
构建的服务器系统。它的客户端应用程序作为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。
最好的问候。
答案 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>
,以便可以在authorizationInterceptor
和tomcat-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
definition和bean with @RolesAllowed
annotation