是否可以在 JAX-WS Web 服务上使用 @RolesAllowed
注释?如果可以,如何使用?
我在 glassfish 3.1.1 上有一个使用基本身份验证的 Web 服务,但使用 @RolesAllowed
表达的限制将被忽略。角色信息应该可用,因为我可以像这样访问它:
@Resource
WebServiceContext wsContext;
if (wsContext.isUserInRole("READ"))
log.info("Role: READ");
我获得了预期的角色,但所有方法仍然可以访问,即使 @RolesAllowed
设置为不同的角色。 @DenyAll
也不起作用。
如果不支持这些注释,是否可以使用部署描述符来根据用户角色管理对 Web 服务方法的访问?
编辑:
This JAVA EE 6 教程的一部分描述了 @RolesAllowed
注释的用法。上面写着
For Java EE components, you define security roles using the @DeclareRoles and @RolesAllowed metadata annotations.
本教程的第一部分中未将 Web 服务列为 Java EE 组件,因此看起来不支持安全注释。
编辑2 继 Izan 的帖子之后,我再次尝试。这是我所做的:
@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 感谢 Izan 和无数次尝试后我终于成功了。
如前所述,要点是通过添加 @Stateless
注释从普通 Web 服务切换到 EJB Web 服务。这允许使用安全注释。
此更改还需要更改部署描述符。虽然原始 Web 服务需要 glassfish-web.xml
来设置角色,但之后还需要 glassfish-ejb-jar.xml
。
最佳答案
也许这是一个非常愚蠢的问题,但是您的 Web 服务是 EJB 吗?如 Security Annotations and Authorization in GlassFish and the Java EE 5 SDK 中所述
The annotations @PermitAll, @DenyAll and @RolesAllowed are defined for specifying permissions of EJB business method
我将这些注释与来自无状态 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 文件包。同样,在答案中发布的同一篇文章中,有一个使用部署描述符章节指出
For EJB web service endpoints with
@RolesAllowed
, you need to specify the type of authentication to use by specifying the and elements in sun-ejb-jar.xml. For username-password authentication, set the element to BASIC, as shown in the following example. This step is required only for EJB web service endpoints, and is not required for EJBs.
由于您正在定义 EJB Web 服务端点,因此我认为您应该将此描述符放入 EAR 中。快速浏览一下那篇文章,它很好地描述了您正在遵循的过程:-)
关于web-services - JAX-WS Web 服务和 @rolesAllowed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9080299/