我的问题是
“我可以在 CXF 上实现的 RESTful 资源上使用 @RolesAllowed 吗?”.
首先,我解释一下引起这个问题的背景。
我正在做一些项目,其中开发人员必须将某些Web系统的一部分重新制作为
RESTful
WEB API。目前的系统具有由Spring
和Hibernate
构建的服务器系统。它的客户端应用程序作为 UI 是由 ActionScript
开发的
FLEX framework
。RESTful APIs
。因此,我们暂时决定使用Apache-CXF ver.2.7.4
作为JAX-RS
实现,TOMCAT ver.7
作为Web应用程序容器。'Authorization'
”这个词是一些控制机制,它限制某些用户根据用户的滚动来访问功能,例如“ROLE_ADMIN
”、“ROLL_EMPLOYEE
”等。而我们的团队希望使用“@RolesAllowed
”注释来约束用户访问 REST
资源类中的一些 RESTful 方法。@RolesAllowed
作为Jersey
imple和TOMCAT,我们可以使用JAX-RS
注解,因为Jersey框架提供了
com.sun.jersey.api.container.filter.RolesAllowedResourceFilterFactory
开发人员可以通过在 web.xml 中添加以下行来激活 @RolesAllowed 注释
<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>
作为 jersey ServletContainer 的 init-param。
但是我们的团队已经决定
Apache CXF
作为JAX-RS实现。我已经调查了CXF站点中Web文档的安全和授权部分。但我无法获得解决方案或如何在 RESTful 资源方法上使用 @RolesAllowed
。
因此,如果您知道在
@RolesAllowed
和 Apache CXF
上实现的 RESTful 资源的要求或如何使用 TOMCAT
,请教我。或者,如果您可以明确得出结论,我们不能在框架中使用 @RolesAllowed
Apache CXF
和TOMCAT
的选择,请教我这个结论的背景知识。
此外,我想我可以通过
@RolesAllowed
在 REST 资源中使用 CXF
作为应用程序服务器,而不是在 JBOSS
上。这个假设是真的吗?很抱歉我没有尝试使用 TOMCAT
来代替 TOMCAT。致以诚挚的问候。
我的解决方案从一个简单的 JAX-RS 项目开始,该项目是根据 CXF 提供的原型项目构建的
JBOSS
(撰写本文时最新的 GAV)。
这为您提供了一个基本的org.apache.cxf.archetype:cxf-jaxrs-service:2.7.5
类以及支持的配置文件。
需要进行一些修改。首先,将以下依赖项添加到
HelloWorld
:
pom.xml
为什么?因为 Tomcat 不是一个完整的 J2EE 容器,所以它不支持所有 JSR-250 注释(
<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>
就是其中之一)。此外,尽管 CXF 识别并可与
@RolesAllowed
一起使用,但它不会捆绑实现,期望它由 J2EE 容器或包含上述 api 提供。列出 @RolesAllowed
是因为我在编译时需要它来添加到
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
或替代方案(例如 JDBC Realm 等)我这样做了:
tomcat-users.xml
这将创建 2 个用户,每个用户都有共享角色 (
<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"/>
) 以及自己独特的角色。
第四,将以下内容添加到hello-user
以启用
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
足够聪明来处理这个问题。仅此而已。在我看来,这是仅使用 Tomcat、CXF 和 BASIC 身份验证的 STTCPW。 CXF + SecureAnnotationsInterceptor
的按键是
@RolesAllowed
。更新:我应该承认,将 Jersey REST 示例转换为 Apache CXF 特别有帮助,特别是指出 SecureAnnotationsInterceptor 与 SecureAnnotationsInterceptor
的连接在其他地方没有得到很好的记录。
:Jersey-CXF博客条目似乎没有迁移到@RolesAllowed
的新博客
。不过,我使用的示例位于 github 上。它包含一个带有
gmazza
定义 的 配置文件和带有
SecureAnnotationsInterceptor
注释 的bean