JAX-WS Web 服务和 @rolesAllowed

发布于 2025-01-01 00:45:58 字数 3362 浏览 3 评论 0 原文

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

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

@Resource
WebServiceContext wsContext;

if (wsContext.isUserInRole("READ"))
log.info("Role: READ");

我获得了预期的角色,但仍然可以访问所有方法,即使 @RolesAllowed 设置为不同的角色。 @DenyAll 也不起作用。

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

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

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

在本教程的第一部分中,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

Is it possible to use @RolesAllowed annotation on a JAX-WS webservice and if so how?

I have a webservice on glassfish 3.1.1 using Basic Authentication but restrictions expressed using @RolesAllowed are ignored. The role information should be available, as I can access it like this:

@Resource
WebServiceContext wsContext;

if (wsContext.isUserInRole("READ"))
log.info("Role: READ");

I get the expected role but still all methods are accessible, even if @RolesAllowed is set to different role. @DenyAll is not working as well.

If these annotations are not supported, is it possible to use deployment descriptors to manage access to webservice methods based on user roles?

Edit:
This part of the JAVA EE 6 tutorial describes the usage of @RolesAllowed annotation. It reads

For Java EE components, you define security roles using the @DeclareRoles and @RolesAllowed metadata annotations.

Web services are not listed as Java EE components in the first part of the tutorial, so it looks like the security annotations are not supported.

Edit2
Following Izan's post, I gave this another try. Here is what I did:

@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!";
  }
}

Using this kind of setup, everybody can access the method, no matter what roles are set. Users get authenticated (can see that in audit.log) but no authorization takes place. As stated above, I can access the role from WebServiceContext (I actually do manual authorization using this info).

Adding @Stateless annotation, let's me use the security annotations. So @permitAll works as expected. But using roles still does not work, as user don't get authenticated now. They show up as ANONYMOUS in audit log and access is denied to them.

My web.xml looks like this:

<?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 just maps role names to group names, like this:

<security-role-mapping>
   <role-name>READ</role-name>
   <group-name>READ</group-name>
</security-role-mapping>

Edit 3
Thanks to Izan and countless tries later I finally got it working.

As said before, the main point was switching from a plain web service to an EJB web service by adding @Stateless annotation. This allows for using the security annotations.

This change required to change the deployment descriptors as well. While the original web service required a glassfish-web.xml for setting up the roles, a glassfish-ejb-jar.xml is required afterwards.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

幻想少年梦 2025-01-08 00:45:58

也许这是一个非常愚蠢的问题,但是您的 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 服务端点,您需要通过指定 元素来指定要使用的身份验证类型。 em>sun-ejb-jar.xml。对于用户名-密码身份验证,请将元素设置为 BASIC,如以下示例所示。仅 EJB Web 服务端点需要此步骤,EJB 不需要。

由于您正在定义 EJB Web 服务端点,因此我认为您应该将此描述符放入 EAR 中。快速浏览一下那篇文章,它很好地描述了您正在遵循的过程:-)

Maybe this is a pretty dumb question, but are your webservices EJBs? As noted in 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

I use those annotations with bottom-up WS from stateless EJBs and they work like a charm in JBoss.


EDIT 1 @TPete
I'll add some code to show you more or less what I'm doing.

@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
    }
}

And as for the interface

@Remote
@WebService
public interface MyInterface {

    @WebMethod(operationName="doSomething")
    public void doSomething(); 
}

WebContext, EndpointConfig and SecurityDomain are JBoss annotation, but I suppose there is something similar for GlassFish, or an equivalent way of doing it. The security domain is included in a deployment descriptor for jboss, and defined in the login-config.xml from the configuration files of JBoss.


EDIT 2 @TPete

I suppose you need to add some EJB deployment descriptors from Glassfish, a sun-ejb-jar.xml file package inside your EAR. Again, from the same article as posted in the answer, there is a Using Deployment Descriptors chapter that states

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.

Since you are defining an EJB web service endpoint, I think you should put this descriptor in you EAR. Have a quick look at that article, it describes quite well the process you are following :-)

娜些时光,永不杰束 2025-01-08 00:45:58

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

这是一篇关于在 WAR 模块中打包 EJB 以及与在 EJB JAR 模块中打包的区别的优秀文章:
http://pic.dhe.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=%2Fcom.ibm.websphere.nd.multiplatform.doc%2Finfo%2Fae%2Fae%2Fcejb_ejbinwar .html

The original question is old but I'm still leaving a comment just in case someone like me stumbles across it. Starting with EJB 3.1, EJBs may be packaged in a WAR module but when it comes to securing them, EJB deployment descriptors need to be used. What is not clear in the spec is that EJBs may not be declared as Servlets in web.xml or else the app will fail to start.

Here's an excellent article about packaging EJBs in WAR modules and the differences with packaging in EJB JAR modules:
http://pic.dhe.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=%2Fcom.ibm.websphere.nd.multiplatform.doc%2Finfo%2Fae%2Fae%2Fcejb_ejbinwar.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文