Web services JAX-WS Web服务和@rolesAllowed

Web services JAX-WS Web服务和@rolesAllowed,web-services,security,jakarta-ee,glassfish,authorization,Web Services,Security,Jakarta Ee,Glassfish,Authorization,可以在JAX-WS Web服务上使用@RolesAllowed注释吗?如果可以,如何使用 我在glassfish 3.1.1上有一个使用基本身份验证的Web服务,但是使用@RolesAllowed表示的限制被忽略。角色信息应该是可用的,因为我可以这样访问它: @Resource WebServiceContext wsContext; if (wsContext.isUserInRole("READ")) log.info("Role: READ"); <?xml version="1

可以在JAX-WS Web服务上使用
@RolesAllowed
注释吗?如果可以,如何使用

我在glassfish 3.1.1上有一个使用基本身份验证的Web服务,但是使用
@RolesAllowed
表示的限制被忽略。角色信息应该是可用的,因为我可以这样访问它:

@Resource
WebServiceContext wsContext;

if (wsContext.isUserInRole("READ"))
log.info("Role: READ");
<?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>
<security-role-mapping>
   <role-name>READ</role-name>
   <group-name>READ</group-name>
</security-role-mapping>
我获得了预期的角色,但仍然可以访问所有方法,即使
@RolesAllowed
设置为不同的角色
@DenyAll
也不起作用

如果不支持这些注释,是否可以使用部署描述符根据用户角色管理对webservice方法的访问

编辑: JavaEE6教程的一部分介绍了
@RolesAllowed
注释的用法。上面写着

对于JavaEE组件,可以使用@DeclareRoles和@RolesAllowed元数据注释定义安全角色

在本教程的第一部分中,Web服务没有作为JavaEE组件列出,因此看起来不支持安全注释

Edit2 在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
工作正常。但使用角色仍然不起作用,因为用户现在没有得到身份验证。他们在审核日志中显示为
匿名
,访问被拒绝

我的
web.xml
如下所示:

@Resource
WebServiceContext wsContext;

if (wsContext.isUserInRole("READ"))
log.info("Role: READ");
<?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>
<security-role-mapping>
   <role-name>READ</role-name>
   <group-name>READ</group-name>
</security-role-mapping>
编辑3 多亏了伊桑和无数次的尝试,我终于成功了

如前所述,要点是通过添加
@无状态
注释,从普通web服务切换到EJB web服务。这允许使用安全注释


此更改还需要更改部署描述符。虽然最初的web服务需要
glassfishweb.xml
来设置角色,但之后需要
glassfishejbjar.xml

也许这是一个相当愚蠢的问题,但是您的Web服务是EJB吗?如中所述

注释@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-EJB-jar.xml中指定和元素来指定要使用的身份验证类型。对于用户名密码身份验证,将元素设置为BASIC,如下例所示。此步骤仅对EJBWeb服务端点是必需的,而对EJB不是必需的


因为您正在定义一个EJBWeb服务端点,所以我认为您应该把这个描述符放在耳朵里。快看一下那篇文章,它很好地描述了你正在遵循的过程:-)

最初的问题很老,但我仍在留下评论,以防像我这样的人偶然发现它。从EJB3.1开始,EJB可以打包在WAR模块中,但在保护它们时,需要使用EJB部署描述符。规范中不清楚的是,ejb不能在web.xml中声明为servlet,否则应用程序将无法启动

这是一篇关于在WAR模块中打包EJB以及在EJB JAR模块中打包的区别的优秀文章:

抱歉,也许可以将此作为编辑而不是答案发布。我认为将其作为评论发布是最合适的,尽管在您获得50个代表之前,这是不合适的possible@Izan我想不会,尽管这是我的第一个JavaEE项目,而且我对术语不太熟悉。也许举个例子可以澄清这个问题。我现在只使用
@Webservice
注释。我试图将它与
@Stateless
结合起来,但后来我无法使用Https访问web服务。@awoodland感谢您提供的信息!我也这么认为,因为这不是一个真正的答案,但正如你所说,我不能。我已经扩展了答案,但我不知道我是否也应该在评论中这样做……扩展成答案肯定是一条路要走。看起来它也解决了这个问题。
@Stateless
如何影响
@RolesAllowed
的工作?我知道有必要添加它,但我对JavaEE不够熟悉,无法理解为什么需要它?