是的,这是可以做到的。我假设您(像我一样)不想使用 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 Annotations(其中@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
或替代(例如JDBC Realm等)我这样做了:
<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
) 以及他们自己的不同角色。
第四,添加以下内容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
足够聪明来处理这个问题。
就这样。在我看来,这是仅使用 Tomcat、CXF 和 BASIC authenitcation 的 STTCPW。CXF + 的关键@RolesAllowed
是SecureAnnotationsInterceptor
.
更新:我应该承认将 Jersey REST 示例转换为 Apache CXF特别有帮助,特别是对于指出 SecureAnnotationsInterceptor 的连接在@RolesAllowed
其他地方没有很好的记录。
更新 2:Jersey-CXF 博客条目似乎没有迁移到gmazza
新博客。但是,我使用的示例在 github 上。它包含一个带有定义的配置文件SecureAnnotationsInterceptor
和一个带有注释的bean@RolesAllowed