`
hereson2
  • 浏览: 471608 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

安全注释和授权在 GlassFish 和 Java EE 5 SDK 中的应用

阅读更多
By Shing Wai Chan, 7/14/08  

安全性对于企业环境非常重要。在 Java EE 5 / GlassFish 环境中,您可以通过以下几种方式实现安全性:

  • 传输层安全性 (TLS) / 安全套接字层 (SSL) 技术
  • 身份验证 (Authentication) 和授权 (Authorization)
  • 消息层安全性(仅适用于 GlassFish 中的 Web 服务)

本文讨论身份验证和授权。参考资料 [1]、[2] 和 [3] 讨论了如何在客户端和服务器端为 Enterprise JavaBeans 和 Web 服务建立 SSL 环境。Web 服务的消息层安全性将在以后的文章中讨论。

身份验证服务一般通过要求用户输入用户名和密码来实现校验用户身份的目的。在 Java EE 环境中,身份验证是和域(realm)相关联的。域可以通过多种方式存储用户身份信息,包括文件、LDAP 目录、甚至是通过 JDBC 访问的数据库(请参阅 参考资料 [4])。它还可以与 Solaris 可拔插验证模块 (Pluggable Authentication Modules, PAM) 框架一起工作。

授权服务根据所运行的软件和运行该软件的用户的身份来执行访问控制授权操作。每次当用户登录时,应用程序都会为他/她赋予一组权限。

在 Java EE 5 之前,如果您希望在某个应用程序使用授权,则需要在应用程序部署描述符 ejb-jar.xml 或 web.xml 中指定授权信息。Java EE 5 的重要改进之一就是简化了 Java EE 应用程序的开发。从 Java EE 5 开始,开发人员可以在 Java 源文件中指定注释,而无需在部署描述符中加入元数据。注释简化了 Java EE 应用程序的开发,缩短了开发周期,并降低了总体拥有成本。

JSR 250(请参阅 参考资料 [5])定义了 Java 平台中的常用注释。本文将讨论 JSR 250 中定义的安全注释,并演示如何在应用程序中通过它们来实现身份验证和授权,以获得安全性。

 

目录

 

基本定义和示例
注释的无效用法示例
安全注释的继承
使用部署描述符
结束语
参考资料
致谢

 

注释 (Annotation) 是一种特殊的修饰符,可以与其他修饰符共同使用。注释由 @ 符号、注释类型和包含在括号中的元素值对列表组成。

本节讨论 JSR 250 定义的常用安全注释。共有 5 种(请参阅 参考资料 [6]):

  • javax.annotation.security.PermitAll
  • javax.annotation.security.DenyAll
  • javax.annotation.security.RolesAllowed
  • javax.annotation.security.DeclareRoles
  • javax.annotation.security.RunAs

@PermitAll@DenyAll@RolesAllowed 注释是为指定 EJB 业务方法权限而定义的。@DeclareRoles@RunAs 是 TYPE 级注释,用于指定与角色相关的元数据。

对于 Web 模块,您仍然需要在 web.xml 应用程序部署描述符中定义一个 <security-constraint> 来添加授权约束,这与 J2EE 1.4 相类似。在 Java EE 5 环境中,与权限相关的注释仅为 EJB 模块定义。下表总结了这些注释的基本用法。有关详细信息,请参阅 JSR 250 规范(参考资料 [5])。

注释

目标

EJB 或其超类

Servlet 或 Web 库

描述

类型

方法

@PermitAll

X

X

X

 

指示某 EJB 的某个方法或所有业务方法允许被所有用户访问。

@DenyAll

 

X

X

 

指示 EJB 的某个方法不允许被任何用户访问。

@RolesAllowed

X

X

X

 

指示 EJB 的某个方法或所有业务方法允许被角色列表中的用户访问。

@DeclareRoles

X

 

X

X

定义安全检查的角色,供 EJBContext.isCallerInRole、HttpServletRequest.isUserInRole 和 WebServiceContext.isUserInRole 使用。

@RunAs

X

 

X(不适用于非 EJB 超类)

X(仅适用于 Servlet)

指定某个组件的 run-as 角色。

 

注意:

  1. 对于 @PermitAll@DenyAll @RolesAllowed 注释,类级别的注释适用于类,方法级的注释适用于方法。方法级注释覆盖类级注释行为。

    示例:请参考以下代码:

    <!---->
    @Stateless
    @RolesAllowed("javaee")
    public class HelloEJB implements Hello {
    @PermitAll
    public String hello(String msg) {
    return "Hello, " + msg;
    }

    public String bye(String msg) {
    return "Bye, " + msg;
    }
    }
     
    <!---->在该示例中,hello() 方法允许被所有用户访问,bye() 方法允许被 javaee 角色中的用户访问。
  2. @DeclareRoles 注释定义了某个组件将要使用的角色列表。在 Java EE 5 环境中,您可以通过 @javax.annotation.Resource 来查找资源,以及通过调用以下 API 来确认用户是否属于某个角色:

    组件

    检查角色的 API

    EJB

    javax.ejb.EJBContext.isCallerInRole(role)

    Servlet

    javax.servlet.http.HttpServletRequest.isUserInRole(role)

    Web 服务

    javax.xml.ws.WebServiceContext.isUserInRole(role)

  3. 尽管 @PermitAll@DenyAll @RolesAllowed 注释允许实现大部分的授权决策,但仍需要 @DeclareRoles 注释来帮助实现更为复杂的逻辑。

    例如,假设 hello 方法允许被属于角色 A 但同时不属于角色 B 的用户访问,则以下代码片段可以实现此目的:
    <!---->
    @Stateless
    @DeclaresRoles({"A", "B"})
    public class HelloEJB implements Hello {
    @Resource private SessionContext sc;
    public String hello(String msg) {
    if (sc.isCallerInRole("A") && !sc.isCallerInRole("B")) {
    ...
    } else {
    ...
    }
    }
    }
     
    <!---->
  4. 在 Web 模块中,您可以在 Servlet、过滤器和标记库中指定 @DeclareRoles。JSP 页面不支持注释。
  5. 嵌入式 Web 服务调用中的 run-as 或调用者的身份标识和客户身份标识之间的关系是没有定义的。无定义则意味着您不能假定 Web 服务调用中的 run-as 和调用者身份标识作为客户标识传递。
  1. 同一方法中不能同时使用 @DenyAll@PermitAll @RolesAllowed。例如,以下这些用法是无效的:

    <!---->
    @PermitAll
    @DenyAll
    public String hello()
     
    <!---->有关详细信息,请参阅 JSR 250 规范的 2.11 节。
  2. 同一方法中不能使用 @RolesAllowed 注释两次以上。

    例如,以下用法无效并且会导致编译失败:

    <!---->
    @RolesAllowed("javaee")
    @RolesAllowed("j2ee")
    public String hello()
     
    <!---->可以在 @RolesAllowed 注释中提供授权角色列表以实现想要的效果,如下所示:

    <!---->
    @RolesAllowed({"javaee", "j2ee"})
    public String hello()
     
    <!---->

本节讨论安全注释的继承。因为 GlassFish 方法的默认行为是 @PermitAll,因此为便于阅读,以下讨论将省略该注释。

继承的一般规则如下:

  • 对于方法,使用与继承层次结构中选择的方法有关联的注释。
  • 对于 @RunAs 注释,只考虑层次结构叶节点中的注释。
  • 对于 @DeclareRoles 注释,继承附加在继承层次结构中。

下面这个示例演示了这些注释继承规则:

示例:在 EJB 的如下层次结构中:

注释的继承规则:示例 1
单击 此处 查看大图。

 

可以使用以下方法权限:

Hello 方法

HelloBaseEJB 方法权限

HelloEJB 方法权限

hello1()

允许被 manager 角色中的用户访问

允许被所有用户访问

hello2()

允许被 employee 角色中的用户访问

允许被 staff 角色中的用户访问

hello3()

允许被 employee 角色中的用户访问

允许被 staff 角色中的用户访问

 

示例:在 Servlet 的以下层次结构中:

注释的继承规则:示例 2
单击 此处 查看大图。

 

Servlet

定义的角色

RunAs

HelloBaseServlet

employee

engineer

HelloServlet

employee、manager

staff

HelloServlet2

employee

 

注意,HelloServlet2 中没有设置 run-as 角色。

使用注释可以简化应用程序的部署描述符。但是在某些场景中,我们仍然需要或者更喜欢使用部署描述符。本节将描述这些场景。

  1. 对于 @RolesAllowed 的 EJB Web 服务端点,您需要在 sun-ejb-jar.xml 中指定 <login-config> <auth-method> 元素来定义将要使用的身份验证类型。对于用户名密码身份验证,将 <auth-method> 元素设置为 BASIC,如以下示例所示。只有 EJB Web 服务端点需要执行此步骤,EJB 不需要。

    <!---->
    <sun-ejb-jar>
    <enterprise-beans>
    <ejb>
    <ejb-name>HelloEjb</ejb-name>
    <webservice-endpoint>
    <port-component-name>HelloEjb</port-component-name>
    <login-config>
    <auth-method>BASIC</auth-method>
    <realm>default</realm>
    </login-config>
    </webservice-endpoint>
    </ejb>
    </enterprise-beans>
    </sun-ejb-jar>
     
    <!---->
  2. @PermitAll@RolesAllowed @DenyAll 注释在 servlet 中不受支持。当使用 servlet 时,在 web.xml 部署描述符中指定身份验证和授权方式。以下信息必须在 web.xml 中指定:

    • <security-constraint>/<web-resource-collection>
      这些元素指定了受保护 Web 资源的 URL 模式和 HTTP 方法。
    • <security-constraint>/<auth-constraint>
      这些元素指定了允许访问受保护 Web 资源的角色列表。
    • <login-config>
      该元素指定了将要执行的身份验证类型(例如,<auth-method>(BASIC 或 FORM))、将要执行身份验证的域 (<realm-name>),以及(如果是基于表格验证)登录表格和错误页面的位置 (<form-login-config>)。
    • <security-role> 该元素指定了该 Web 应用程序使用的角色列表。该列表必须包含上面提到的 <auth-constraint> 中指定的角色。

      例如,假设您希望保护 index.jsp 页面的 GET 和 POST 方法,只允许 employee 角色访问它们,则需要使用以下 web.xml 配置来实现:

      <!---->
      ...
      <web-app>
      <servlet>
      ...
      </servlet>
      <security-constraint>
      <web-resource-collection>
      <web-resource-name>MySecureResource</web-resource-name>
      <url-pattern>/index.jsp</url-pattern>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
      </web-resource-collection>
      <auth-constraint>
      <role-name>employee<role-name>
      </auth-constraint>
      <user-data-constraint>
      <transport-guarantee>NONE</transport-guarantee>
      </user-data-constraint>
      </security-constraint>
      <login-config>
      <auth-method>BASIC</auth-method>
      <realm-name>default</realm-name>
      <login-config>
      <security-role>
      <role-name>employee</role-name>
      </security-role>
      </web-app>
       
      <!---->
  3. 对 于只有某个角色才具有访问权限的应用程序来说,您需要在应用程序使用的角色与应用服务器定义的组或主体之间建立映射。为了在应用程序所使用的 employee 角色和应用服务器默认域定义的 engineer 组之间建立映射,您仍然需要在运行时部署描述符 sun-application.xml、sun-ejb-jar.xml 或 sun-web.xml 中指定该安全角色映射。

    例如,将以下代码添加到 sun-application.xml 中就可以实现在 engineer 组的所有用户与某个应用程序的 employee 角色之间建立映射。

    <!---->
    <security-role-mapping>
    <role-name>employee</employee>
    <group-name>engineer</group-name>
    </security-role-mapping>
     
    <!---->
  4. 部署描述符覆盖注释行为。

    示例:假设有以下 Enterprise JavaBean:

    <!---->
    @Stateless
    public class HelloEJB implements Hello {
    @PermitAll
    public String hello1(String msg) {
    return "1: Hello, " + msg;
    }

    @RolesAllowed("javaee")
    public String hello2(String msg) {
    return "2: Hello, " + msg;
    }

    @DenyAll
    public String hello3(String msg) {
    return "3: Hello, " + msg;
    }
    }
     
    <!---->

    您可以通过应用程序部署描述符 ejb-jar.xml 来覆盖方法权限:

    <!---->
    <ejb-jar ...>
    <enterprise-beans>
    ...
    </enterprise-beans>
    <assembly-descriptor>
    <security-role>javaee</security-role>
    <method-permission>
    <role-name>javaee</role-name>
    <method>
    <ejb-name>HelloEJB</ejb-name>
    <method-intf>Local</method-intf>
    <method-name>hello1</method-name>
    </method>
    </method-permission>
    <method-permission>
    <unchecked/>
    <method>
    <ejb-name>HelloEJB</ejb-name>
    <method-intf>Local</method-intf>
    <method-name>hello3</method-name>
    </method>
    </method-permission>
    <exclude-list>
    <method>
    <ejb-name>HelloEJB</ejb-name>
    <method-intf>Local</method-intf>
    <method-name>hello2</method-name>
    </method>
    </exclude-list>
    </assembly-descriptor>
    </ejb-jar>
     
    <!---->行为如下:

    方法

    注释

    部署描述文件覆盖

    hello1()

    允许被所有用户访问

    允许被 javaee 角色的用户访问

    hello2()

    允许被 javaee 角色的用户访问

    不允许被任何用户访问

    hello3()

    不允许被任何用户访问

    允许被所有用户访问

  5. 在 GlassFish 中,如果应用程序部署描述文件中没有指定域,则该应用程序将使用默认域。您可以在运行时部署描述符 sun-application.xml 和 sun-ejb-jar.xml 中使用 <realm> 元素或在 web.xml 中使用 <realm-name> 元素来覆盖该设置。
  6. 如果在 GlassFish 中使用 @RunAs 注 释,则需要将 run-as 角色关联到一个主体,如果只关联了一个主体,则该主体将作为 run-as 主体的默认值;如果关联了多个主体,则需要明确设置 run-as 主体。以下示例演示了如何在 sun-ejb-jar.xml 中设置 run-as 主体:

    <!---->
    ...
    <ejb>
    ...
    <principal>
    <name>user1</name>
    </principal>
    ...
    </ejb>
     
    <!---->

    以下示例演示了如何在 sun-web.xml 中设置 run-as 主体:

    <!---->
    ...
    <servlet>
    <servlet-name>myServlet</servlet-name>
    <principal-name>user1</principal-name>
    ...
    </servlet>
    ...
     
    <!---->

总而言之,注释可以通过身份验证和授权为 Java EE 5 环境中的应用程序提供安全性。在 Java EE 5 环境中使用身份验证和授权时,通常需要遵循以下几个步骤:

  1. 创建 Java EE 应用程序。
  2. 使用 Enterprise JavaBeans 安全注释建立授权约束,或者在 Web 模块的 web.xml 文件中添加安全约束。
  3. 在相应的部署描述符中添加身份验证需求 <login-config>
  4. 建立域(如果未使用默认域),或者在应用程序部署描述符中指定 run-as 主体。
  5. <security-role-mapping> 元素添加到运行时部署描述文件中,在应用程序角色和应用服务器组或主体之间建立映射。
  6. 打包和部署应用程序。
  1. How to use Verisign cert in GlassFish and SJSAS 8.x?,Shing Wai Chan 的 Weblog,2005 年 10 月 16 日
  2. Enterprise Java Bean over SSL,Shing Wai Chan 的 Weblog,2006 年 4 月 8 日
  3. Using JAX-WS-Based Web Services with SSL, in Enterprise Java Technologies Tech Tips for May 30, 2006,Shing Wai Chan,2006 年 5 月 27 日
  4. JDBCRealm in GlassFish,Shing Wai Chan 的 Weblog,2006 年 6 月 8 日
  5. JSR 250: Common Annotations for the Java Platform
  6. Java EE 5 SDK API Specifications: Package javax.annotation.security Descripton

感谢 Debbie Carson 和 Rick Palkovic 为本文提出的宝贵建议。


转系:Sun中国技术社区

评论
1 楼 goon 2010-03-15  
请问:在java客户端怎么lookup 带权限的ejb接口?谢谢

相关推荐

    Java EE 5 SDK

    Java EE 5 SDK通常搭配应用服务器一起使用,如GlassFish或JBoss,开发者可以在这些服务器上编写、测试和部署应用程序。应用通常被打包成WAR(Web Archive)或EAR(Enterprise Archive)文件,然后通过应用服务器的...

    Java EE 5 SDK中文版+英文版

    SDK中的两个.chm文件,"JavaEE_CN.chm"和"java-ee-5.chm"很可能是Java EE 5的中文和英文帮助文档,对于开发者来说是宝贵的参考资料。 **Java EE 5的关键特性:** 1. **简化EJB(Enterprise JavaBeans)**:在Java ...

    java_ee_sdk-8u1.zip

    通过学习和使用"java_ee_sdk-8u1.zip"中的资源,开发者可以深入了解Java EE 8的特性和最佳实践,从而构建出高效、可维护的企业级应用。同时,这些资料也是进一步学习和研究Java EE技术栈,如微服务、云原生应用开发...

    java_ee_sdk-8u1-web.zip

    在压缩包中的“glassfish5”文件夹,指的是GlassFish服务器,这是一个开源的应用服务器,它是Java EE规范的参考实现。GlassFish支持Java EE的各种组件,如Web服务、Java Servlets、JSP、EJB、JSF(JavaServer Faces...

    java ee 6 with glassfish 3

    Java EE 6(Java Platform, Enterprise Edition)是Java开发企业级应用的标准框架,它提供了丰富的API和服务,用于构建分布式、多层的企业系统。GlassFish 3是Oracle公司推出的开源应用服务器,是Java EE 6规范的...

    java_ee_sdk-8

    - 解压`java_ee_sdk-8`压缩包,并将`glassfish5`目录添加到系统路径,以便在命令行中使用GlassFish工具。 - 使用NetBeans、Eclipse或IntelliJ IDEA等集成开发环境(IDE)配置Java EE 8和GlassFish服务器,便于开发...

    GlassFish社区奉献的Java EE应用服务器

    本文将详细介绍GlassFish应用服务器及其在Java EE 5.0规范中的角色,旨在帮助开发者更好地理解Java EE应用服务器的核心概念和技术特点。 #### 二、Java EE 5.0概述 Java EE 5.0(Java Platform, Enterprise Edition...

    java_ee_sdk-8u1.zip java ee 8 sdk 解压后重新压缩的

    在"java_ee_sdk-8u1"这个压缩包中,包含了上述所有这些Java EE 8核心组件的实现和相关的工具,如Java Development Kit(JDK)以及用于开发和部署应用程序的GlassFish服务器。这个SDK是开发者进行Java EE 8应用程序...

    java_ee_sdk-5_03-javadocs.rar java_ee_sdk-5_03-javadocs.api

    JSP 2.1在Java EE 5中引入,支持EL(Expression Language)和JSF(JavaServer Faces)的集成。 3. **JPA(Java Persistence API)**:JPA是用于对象关系映射的标准,允许开发者在Java应用中处理数据库数据。它简化...

    Beginning Java EE 6 with GlassFish 3, 2nd Edition

    - **部署示例**: 通过详细的步骤指导读者如何在GlassFish 3上部署Java EE 6应用,并介绍了一些基本的管理和监控操作。 #### 四、实践示例 - **实体到Session Beans**: 书中通过实例演示了如何使用EJB 3.1和JPA 2.0...

    Java EE 5 Development using GlassFish Application Server.part2.rar

    Java EE 5 Development using GlassFish Application Server

    GlassFish 社区奉献的Java EE 应用服务器

    GlassFish 社区奉献的Java EE 应用服务器

    Java EE 6 with GlassFish 3 Application Server

    通过"Java EE 6 with GlassFish 3 Application Server"的学习资料,开发者可以深入了解这些关键特性和实践,从而高效地开发基于Java EE 6的企业级应用程序。这份文档将涵盖上述各个知识点的详细解释、示例代码以及...

    java ee基础使用教程

    Java EE应用运行在Web容器或应用服务器中,如Tomcat、Jetty、GlassFish和WildFly。这些服务器提供运行环境,处理应用的部署、生命周期管理和资源管理。郑阿奇的教程将介绍如何配置和管理这些服务器。 八、安全与...

    Java EE 7 with GlassFish 4 Application Server 2014年英文原版

    本书是英文原版的图书 探讨了GlassFish的安装和配置,然后再移动到的Java EE 7的应用程序的开发,涵盖了所有主要的Java EE 7的API。它着重于超越基础开发部署到GlassFish 4应用程序服务器的Java应用程序。本书涵盖了...

Global site tag (gtag.js) - Google Analytics