我可以在 Apache CXF 上实现的 RESTful 资源上使用 @RolesAllowed 吗? [英] Can I use @RolesAllowed on RESTful Resources implemented on Apache CXF?

查看:27
本文介绍了我可以在 Apache CXF 上实现的 RESTful 资源上使用 @RolesAllowed 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


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

首先,我解释一下导致这个问题的背景.
我正在从事一些项目,其中开发人员必须将一些 Web 系统的一部分重新制作为 RESTful WEB APIs.本系统具有由 Spring 和 <代码>休眠.而其作为 UI 的客户端应用程序是由 ActionScript 通过FLEX 框架.
现在我正在研究通过阅读一些文档或开发一些原型来将我们现有的系统设计和改造为 RESTful APIs 的正确方法.所以,我们暂时决定使用 Apache-CXF ver.2.7.4 作为 JAX-RS 实现,TOMCAT ver.7 作为 Web 应用程序容器.

然后,我现在正在为用户授权的方式而苦苦挣扎.如您所知,我的意思是'Authorization'这个词作为一些控制机制,它限制某些用户根据用户的滚动访问功能,例如ROLE_ADMINROLL_EMPLOYEE 等等.而我们的团队想要使用 @RolesAllowed 注释来约束用户访问 REST 资源类中的一些 RESTful 方法.
通过调查,我知道如果我们使用 Jersey 作为 JAX-RS impl 和 TOMCAT,我们可以使用 @RolesAllowed 注解,因为 Jersey 框架提供了

First of all, I explain the context causing this question.
I'm working at some projects in which developers have to remake one part of the some web systems into RESTful WEB Apis.This present system has server system built by Spring and Hibernate. And its client application as UI is developed by ActionScript through FLEX framework.
Now I'm surveying the proper way to design and remake our present system into RESTful APIs through reading some documents or develop some prototypes.So, we temporarily decided to use Apache-CXF ver.2.7.4 as JAX-RS implementation and TOMCAT ver.7 as Web applications container.

Then, I am struggling for the way of user authorizations now. As you know, I mean the word 'Authorization' as some control mechanism that constrain some users to access functions according to user's roll like ROLE_ADMIN, ROLL_EMPLOYEE and so on.And our team wants to use @RolesAllowed annotation to constrain user to access some RESTful methods in REST resource classes.
Through surveying, I knew that we can use @RolesAllowed annotation if we use Jersey as JAX-RS imple and TOMCAT, because Jersey framework provides

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

com.sun.jersey.api.container.filter.RolesAllowedResourceFilterFactory
for developers to activate @RolesAllowed annotation by adding following lines in web.xml

<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.

as init-param of jersey's ServletContainer.

但是我们的团队已经决定将 Apache CXF 作为 JAX-RS 实现.我已经调查了 CXF 站点中 Web 文档的安全和授权部分.但我无法获得解决方案或如何在 RESTful 资源方法上使用 @RolesAllowed.

But our team has decided Apache CXF as JAX-RS imple.I've already surveyed the security and authorization parts of web documents in CXF site. But I couldn’t get solutions or how to use @RolesAllowed on RESTful resource methods.

所以,如果您知道要求或如何在 Apache CXFTOMCAT 上实现的 RESTful 资源上使用 @RolesAllowed,请教我,请.或者,如果您可以明确得出结论,我们不能在 Apache CXFTOMCAT 的框架选择中使用 @RolesAllowed,请教我该结论的背景知识.

So If you know the requirements or how to use @RolesAllowed on RESTful resource implemented on Apache CXF and TOMCAT, teach me that, please.Or if you can definitively conclude that we can't use @RolesAllowed in frameworks choice of Apache CXF and TOMCAT, please teach me the background knowledge of that conclusion.

另外,我想我可以在 JBOSS 上的 CXF REST 资源中使用 @RolesAllowed 作为应用服务器,而不是在 TOMCAT.这个假设是真的吗?很抱歉我没有尝试使用 JBOSS 代替 TOMCAT.

Additionally, I suppose that I can use @RolesAllowed in REST resource by CXF on JBOSS as app server, not on TOMCAT. Is this assumption true ? I'm sorry that I've not made a trial to use JBOSS instead of TOMCAT.

最好的问候.

推荐答案

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

Yes, this can be done. I'll assume that you (like me) did not want to use Spring Security as part of the solution (to handle authentication and authorization) since there is seem to be plenty of resources on how to enable the JSR-250 annotations with Spring Security.

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

My solution began with a simple JAX-RS project built from the CXF-supplied Archetype Project org.apache.cxf.archetype:cxf-jaxrs-service:2.7.5 (lastest GAV @ time of writing).

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

This gives you a basic HelloWorld class with supporting config files.

需要进行一些修改.

首先,在pom.xml中添加如下依赖:

First, add the following dependencies to the 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 提供.

Why? Because Tomcat is not a full J2EE Container, it does not support all JSR-250 Annotations (of which @RolesAllowed is one). Further, although CXF recognizes and will work with @RolesAllowed, it does not bundle an implementation, expecting it to be provided by either a J2EE container or the inclusion of the api as above.

servlet-api 被列出是因为我在编译时需要它以用于我添加到 HellowWorld.java 的方法(见下文).

The servlet-api is listed because I needed it @ compile time for a method I add to HellowWorld.java (see below).

二、修改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 注释.

The SecureAnnotationsInterceptor is what will scan the helloWorldService and enforce the @RolesAllowed annotations.

请注意,helloWorldService 必须从 <jaxrs:serviceBeans> 节中取出,以便可以在此处和 authorizationInterceptor<中引用它/代码>.

Note that the helloWorldService had to be pulled out of the <jaxrs:serviceBeans> stanza so it could be referenced both there and in the authorizationInterceptor.

第三,将一些角色和用户添加到 tomcat-users.xml 或替代(例如 JDBC Realm 等)我这样做了:

Third, add some roles and users to tomcat-users.xml or alternative (eg. JDBC Realm, etc.) I did this:

<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"/>

这会创建 2 个用户,每个用户都有一个共享角色 (hello-user) 以及他们自己的不同角色.

This creates 2 users who each have a shared role (hello-user) plus their own distinct role.

四、在web.xml中加入以下内容,开启BASIC认证:

Fourth, add the following to web.xml to enable BASIC authentication:

<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/* 下的所有内容都需要角色 hello-user.这不是必需的,但请注意,我确实在省略某些节、通配符和角色时遇到了一些问题......所以在这里小心试验.

With this, I decided to require the role hello-user for everything under /hello/*. That's not essential, but beware that I did have some issues omitting some of the stanzas, wildcards and roles... so experiment with care here.

第五(也是最后),标记 HelloWorld.java 类:

Fifthly (and finally), mark up the HelloWorld.java class:

@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 足够聪明来处理这个问题.

I added the last method (getClichedMessage()) to show that both users can access the method because they have the hello-user role with which the class is annotated. The SecureAnnotationsInterceptor is smart enough to handle that.

就是这样.在我看来,这是仅使用 Tomcat、CXF 和 BASIC authenitcation 的 STTCPW.CXF + @RolesAllowed 的关键是 SecureAnnotationsInterceptor.

That's all. Seems to me, this is the STTCPW using just Tomcat, CXF and BASIC authenitcation. The key for the CXF + @RolesAllowed is the SecureAnnotationsInterceptor.

更新:我应该承认 将 Jersey REST 示例转换为 ApacheCXF 特别有用,特别是指出 SecureAnnotationsInterceptor 与 @RolesAllowed 的连接在其他地方没有很好的记录.

Update: I should acknowledge that Converting Jersey REST Examples to Apache CXF was particularly helpful, especially for pointing out the SecureAnnotationsInterceptor whose connection to @RolesAllowed is not well documented elsewhere.

更新 2:Jersey-CXF 博客条目似乎没有迁移到 gmazza 的新博客.但是,我使用的示例在 github.它包含一个 带有 SecureAnnotationsInterceptor 定义带有 @RolesAllowed 注释的bean

Update 2: The Jersey-CXF blog entry doesn't seem be migrated to gmazza's new blog. However, the example I used is on github. It contains a config file with SecureAnnotationsInterceptor definition and a bean with @RolesAllowed annotation

这篇关于我可以在 Apache CXF 上实现的 RESTful 资源上使用 @RolesAllowed 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆