是否可以在JAX-WS Web服务上使用@RolesAllowed
注释?如果可以,如何使用?
我在glassfish 3.1.1上有一个使用基本身份验证的Web服务,但使用@RolesAllowed
表达的限制被忽略了。角色信息应该是可用的,因为我可以这样访问它:
@Resource
WebServiceContext wsContext;
if (wsContext.isUserInRole("READ"))
log.info("Role: READ");
我得到了预期的角色,但仍然可以访问所有方法,即使@RolesAllowed
设置为不同的角色。@DenyAll
无法正常工作。
如果不支持这些注释,是否可以使用部署描述符来管理基于用户角色的Web服务方法访问?
编辑:JAVAEE6教程的这一部分介绍了@RolesAllowed
注释的用法。它读取
对于JavaEE组件,可以使用@DeclareRoles和@RolesAllowed元数据注释来定义安全角色。
在本教程的第一部分中,Web服务没有被列为JavaEE组件,因此看起来不支持安全注释。
第2版继伊赞的帖子之后,我又尝试了一次。以下是我所做的:
@Webservice
@DeclareRoles(value = {"READ", "UPDATE", "DELETE"})
public class ServiceImpl implements Service {
@Override
@WebMethod(operationName = "helloWorld")
@RolesAllowed({"NONE"})
public String helloWorld() throws Exception {
return "Hello World!";
}
}
使用这种设置,无论设置了什么角色,每个人都可以访问该方法。用户可以通过身份验证(可以在audit.log中看到),但不会进行任何授权。如上所述,我可以从WebServiceContext
访问该角色(我实际上使用此信息进行手动授权)。
添加@Stateless
注释,让我们使用安全注释。因此@permitAll
的工作符合预期。但使用角色仍然不起作用,因为用户现在还不能通过身份验证。它们在审核日志中显示为ANONYMOUS
,访问被拒绝。
我的web.xml
看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>OneMore</display-name>
<security-constraint>
<display-name>WebServiceSecurity</display-name>
<web-resource-collection>
<web-resource-name>Authorized users only</web-resource-name>
<url-pattern>/service</url-pattern>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>READ</role-name>
<role-name>UPDATE</role-name>
<role-name>DELETE</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<role-name>READ</role-name>
</security-role>
<security-role>
<role-name>UPDATE</role-name>
</security-role>
<security-role>
<role-name>DELETE</role-name>
</security-role>
</web-app>
Glassfish-web.xml
只是将角色名称映射到组名称,如下所示:
<security-role-mapping>
<role-name>READ</role-name>
<group-name>READ</group-name>
</security-role-mapping>
编辑3多亏了伊赞和无数次的尝试,我终于成功了。
如前所述,要点是通过添加@Stateless
注释从普通web服务切换到EJB web服务。这允许使用安全注释。
此更改也需要更改部署描述符。虽然最初的web服务需要glassfish-web.xml
来设置角色,但之后需要glassfish-ejb-jar.xml
。
也许这是一个非常愚蠢的问题,但您的Web服务是EJB吗?如GlassFish和Java EE 5 SDK 中的安全注释和授权所述
注释@PermitAll、@DenyAll和@RolesAllowed是为指定EJB业务方法的权限而定义的
我将这些注释与来自无状态EJB的自底向上的WS一起使用,它们的工作方式就像JBoss中的魅力一样。
编辑1@TPete我会添加一些代码,或多或少地向您展示我正在做的事情。
@Stateless
@WebService()
@WebContext(contextRoot = WSContextRoot.CTX_ROOT,
authMethod = "BASIC")
@EndpointConfig(configName = "Standard WSSecurity Endpoint")
@SecurityDomain(value = "myDeclaredDomain")
@RolesAllowed({ "AUTHORISED" })
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
public class MyWS implements MyInterface {
@Override
public void doSomething(){
//impl
}
}
至于接口
@Remote
@WebService
public interface MyInterface {
@WebMethod(operationName="doSomething")
public void doSomething();
}
WebContext、EndpointConfig和SecurityDomain都是JBoss注释,但我认为GlassFish也有类似的东西,或者有等效的方法。安全域包含在JBoss的部署描述符中,并在JBoss的配置文件的login-config.xml中定义。
编辑2@TPete
我想您需要从Glassfish添加一些EJB部署描述符,Glassfish是EAR中的一个sun-EJB-jar.xml文件包。同样,在答案中发布的同一篇文章中,有一个使用部署描述符章节介绍了
对于具有
@RolesAllowed
的EJB web服务端点,您需要通过在sun-eb-jar.xml中指定和元素来指定要使用的身份验证类型。对于用户名密码身份验证,请将元素设置为BASIC,如下例所示。此步骤仅对EJB web服务端点是必需的,而对EJB不是必需的。
既然您正在定义EJB web服务端点,我认为您应该将这个描述符放在EAR中。快速浏览一下这篇文章,它很好地描述了您正在执行的过程:-)
最初的问题很老了,但我仍然会留下评论,以防像我这样的人偶然发现。从EJB 3.1开始,EJB可能被打包在WAR模块中,但在保护它们时,需要使用EJB部署描述符。规范中不清楚的是,EJB可能不会在web.xml中声明为Servlet,否则应用程序将无法启动。
以下是一篇关于在WAR模块中打包EJB以及与在EJBJAR模块中打包的区别的优秀文章:http://pic.dhe.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=%2Fcom.ibm.websphere.nd.multiplatform.doc%2Finfo%2Fae%2Fae%2Fcejb_ejbinwar.html