// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= 在 Java EE 中构建安全企业 Bean
:jbake-type: tutorial
:jbake-tags: tutorials 
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: 在 Java EE 中构建安全企业 Bean - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, 在 Java EE 中构建安全企业 Bean

通过 NetBeans IDE 中的 Java EE 规范支持，您可以充分利用许多 Java EE 功能来简化应用程序开发。Java EE 5 规范的一个重大改进是采用了标注。使用标注，您可以消除在对应用程序进行编码时所使用的许多模板代码，并最大限度地减少部署应用程序时所需的配置量。

通过使用标注而得到极大简化的一个领域是企业 Bean 的开发和配置。使用标注，您可以指定以前在部署描述符文件中所指定的许多配置属性，从而使很多部署描述符文件变得不再必需。尽管应用程序可能仍然需要一些部署描述符文件（如  ``web.xml`` ），但 IDE 的多视图部署描述符编辑器大大简化了对这些文件的编辑。

通过使用标注，现在构建安全的企业 Bean 要简单得多。您可以使用安全标注直接在源代码中配置授权，而无需在  ``ejb-jar.xml``  部署描述符中配置企业 Bean 安全性。Java EE 5 企业应用程序不需要  ``ejb-jar.xml``  或  ``application.xml`` 。

有关 Java EE 规范的一些特性的概述，请参见 link:javaee-intro.html[+Java EE 技术简介+]。有关标注规范的详细信息，请参见 link:http://jcp.org/en/jsr/detail?id=250[+JSR 250：Java 平台的常用标注+]。


image::images/netbeans-stamp-80-74-73.png[title="此页上的内容适用于 NetBeans IDE 7.2、7.3、7.4 和 8.0"]


*要学习本教程，您需要具备以下软件和资源。*

|===
|软件或资源 |要求的版本 

|link:https://netbeans.org/downloads/index.html[+NetBeans IDE+] |7.2、7.3、7.4、8.0、Java EE 版本 

|link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[+Java 开发工具包 (JDK)+] |版本 7 或 8 

|GlassFish Server |3.1.x、4.x 
|===

在学习本教程之前，您需要在 IDE 中注册 GlassFish Server 的本地实例。如果您安装了 "Java EE" 版本的 IDE，则应已安装并注册应用服务器。如果在 IDE 中未注册该应用服务器，请选择 "Tools"（工具）> "Servers"（服务器），以在服务器管理器中注册它。您不能将企业应用程序部署到 Tomcat Web 服务器。

*先决条件*

本文档假定您具备以下技术的一些基本知识或编程经验：

* Java 编程
* NetBeans IDE


== 在应用服务器上创建安全组

在本示例中，您仅希望  ``bank_users``  组的用户访问企业 Bean。您将在应用服务器  ``file``  安全领域的  ``bank_users``  组中创建  ``manager``  用户。

1. 启动应用服务器，方法是：在 "Services"（服务）窗口中右键单击应用服务器的节点，然后选择 "Start"（启动）。
2. 右键单击应用服务器节点，然后选择 "View Domain Admin Console"（查看域管理控制台），以便在浏览器中打开 GlassFish Server 管理控制台。
3. 展开左导航栏中 "Configurations"（配置）节点下方的 *server-config* 节点。
4. 单击 *"Security"（安全性）> "Realms"（领域）> "file"*，以打开 "Edit Realm"（编辑领域）框架。
image::images/console-file-realm.png[title="在应用服务器的管理控制台中选择文件领域节点"]
5. 单击 "Edit Realm"（编辑领域）面板顶部的 "Manage Users"（管理用户）按钮，打开 "File Users"（文件用户）面板。
image::images/console-edit-realm.png[title="应用服务器的管理控制台中的 "Edit Realm"（编辑领域）面板代码"]
6. 单击 "File Users"（文件用户）面板中 "File Users"（文件用户）表顶部的 "New"（新建）按钮。
7. 在 "New File Realm User"（新建文件领域用户）窗体中输入以下数据。单击 "OK"（确定）。
|===

|名称 |值 

|用户 ID |manager 

|组列表 |bank_users 

|Password |password 
|===

该窗体应与下图类似。

image::images/console-new-user.png[title="应用服务器的管理控制台中的 "New File Realm User"（新建文件领域用户）面板"]

在单击 "OK"（确定）后，该服务器将创建用户，并打开 "File Users"（文件用户）面板。您将会看到，现在有一个名为  ``manager``  的用户。

image::images/console-file-users.png[title="管理控制台中包含用户列表的 "File Users"（文件用户）面板"]

创建用户之后，将创建企业应用程序，以检查该用户是否能够查看数据。


== 为远程接口创建 Java 类库

在本练习中，将创建一个简单的 Java 类库项目，其中包含会话 Bean 的远程接口。然后，将编译的类库 JAR 添加到 EJB 模块以及用于调用会话 Bean 的应用程序客户端的类路径中。

1. 选择 "File"（文件）> "New Project"（新建项目），然后在 "Java" 类别中选择 "Java Class Library"（Java 类库）。单击 "Next"（下一步）。
2. 键入 SecureRemoteInterface 作为项目名称。
3. 指定项目的位置。单击 "Finish"（完成）。

在下一部分中，将在企业应用程序中创建一个会话 Bean。该会话 Bean 可通过远程接口进行访问。在创建会话 Bean 时，IDE 将自动创建类库中的远程接口，并将类库 JAR 添加到企业应用程序的类路径中。


== 创建和保护企业应用程序

企业应用程序中将包含一个简单的会话 Bean，该会话 Bean 可通过类库项目中的远程接口进行访问。


=== 创建企业应用程序项目

在本练习中，将创建一个包含 EJB 模块的企业应用程序。

1. 选择 "File"（文件）> "New Project"（新建项目）（Ctrl-Shift-N 组合键；在 Mac 上为 ⌘-Shift-N 组合键），然后从 "Java EE" 类别中选择 "Enterprise Application"（企业应用程序）模板。单击 "Next"（下一步）。
2. 键入 *Secure* 作为项目名称，并设置项目位置。
3. 取消选中 "Use Dedicated Folder"（使用专用文件夹）选项（如果该选项处于选中状态）。

在本教程中，我们将项目库复制到一个专门的文件夹中，因为需要与其他用户或项目共享库。

单击 "Next"（下一步）。
4. 将服务器设置为 "GlassFish"，并将 Java EE 版本设置为 "Java EE 6"。
5. 选中 "Create EJB Module"（创建 EJB 模块），并取消选中 "Create Web Application Module"（创建 Web 应用程序模块）。单击 "Finish"（完成）。
image::images/new-entapp-wizard.png[title="应用服务器的管理控制台中的 "New File Realm User"（新建文件领域用户）面板"] 


=== 确保会话 Bean 中的方法安全

在本练习中，将在 EJB 模块项目中创建一个会话 Bean。该会话 Bean 没有任何特殊的功能。它仅仅返回一个余额样例。您将创建一个  ``getStatus``  方法，并通过使用  ``@RolesAllowed``  标注对其进行标注以保护该方法 Bean，然后指定可以访问该方法的安全角色。此安全角色由应用程序使用，它与服务器上的用户和组不同。此后，将在配置部署描述符时将此安全角色映射到用户和组。

安全标注可以分别应用于类中的每个方法，也可以应用于整个类。在此简单练习中，将使用  ``@RolesAllowed``  标注方法，但 Java EE 规范还定义了其他可用在企业 Bean 中的安全标注。

1. 在 "Projects"（项目）窗口中，右键单击 EJB 模块的节点 (Secure-ejb)，然后选择 "New"（新建）> "Session Bean"（会话 Bean）。
2. 键入 *AccountStatus* 作为 Bean 名称，并键入 *bean* 作为包。
3. 选中 "Remote in project"（以远程方式位于项目中）作为接口类型。
4. 在下拉列表中选择 "SecureRemoteInterface"。单击 "Finish"（完成）。
image::images/new-sessionbean-wizard.png[title="新建会话 Bean 向导中选中了远程接口"]

单击 "Finish"（完成），此时 IDE 将创建  ``AccountStatus``  类并在源代码编辑器中打开该文件。

IDE 还将在 SecureRemoteInterface 类库项目中为  ``bean``  包中的 Bean 创建  ``AccountStatusRemote``  远程接口，并将 SecureRemoteInterface 类库 JAR 添加到了 EJB 模块项目的类路径中。

image::images/projects-window-bean.png[title="显示类路径上的会话 Bean 和类库的 "Projects"（项目）窗口"]

如果打开 EJB 模块的 "Properties"（属性）对话框的 "Libraries"（库）类别，则会看到 JAR 已添加到编译时库中。

5. 在源代码编辑器中，将以下字段声明（以粗体显示）添加到  ``AccountStatus``  中：

[source,java]
----

public class AccountStatus implements AccountStatusRemote {
    *private String amount = "250";*
----
6. 在源代码编辑器中，右键单击类，并选择 "Insert Code"（插入代码）（Alt-Insert 组合键；在 Mac 上为 Ctrl-I 组合键），然后选择 "Add Business Method"（添加 Business 方法），以打开 "Add Business Method"（添加 Business 方法）对话框。
7. 键入 *getStatus* 作为方法名称，并将返回类型设置为  ``String`` 。

IDE 将自动在远程接口中公开此业务方法。

8. 在源代码编辑器中，将以下代码行（以粗体显示）添加到  ``getStatus``  方法中。

[source,java]
----

public String getStatus() {
*    return "The account contains $" + amount;*
}
----
9. 键入以下内容（以粗体显示）来标注  ``getStatus``  方法。*@RolesAllowed({"USERS"})*

[source,java]
----

public String getStatus() {
----

此标注表示只有安全角色为  ``USERS``  的用户才能访问  ``getStatus``  方法。

10. 在编辑器中右键单击并选择 "Fix Imports"（修复导入）（Alt-Shift-I 组合键；在 Mac 中为 ⌘-Shift-I 组合键），然后保存您的更改。确保  ``javax.annotation.security.RolesAllowed``  已添加到该文件中。


=== 配置部署描述符

Java EE 企业应用程序通常不需要部署描述符文件，如  ``ejb-jar.xml`` 。如果展开 Secure-ejb 或 Secure 企业应用程序下面的 "Configuration Files"（配置文件）节点，则会看到没有部署描述符。您可以使用标注指定很多已在  ``ejb-jar.xml``  中配置的属性。在本示例中，您通过在会话 Bean 中使用  ``@RolesAllowed``  标注为 EJB 方法指定了安全角色。

不过，在为应用程序配置安全性时，仍然需要在部署描述符中指定一些属性。在本示例中，您需要将企业应用程序中使用的安全角色 ( ``USERS`` ) 映射到在应用服务器上配置的用户和组。您已在应用服务器上创建了  ``bank_users``  组，现在需要将该组映射到企业应用程序中的安全角色  ``USERS`` 。为此，可以编辑企业应用程序的  ``glassfish-application.xml``  部署描述符。

因为企业应用程序不需要部署描述符便可运行，所以 IDE 默认情况下不创建部署描述符。因此，首先需要创建部署描述符文件，然后在多视图编辑器中编辑该文件，以配置安全角色映射。

1. 右键单击 "Secure" 企业应用程序项目，然后选择 "New"（新建）> "Other"（其他），以打开新建文件向导。

此外，也可以从主菜单中选择 "File"（文件）> "New File"（新建文件），以打开新建文件向导。在这种情况下，请确保在 "Project"（项目）下拉列表中选择了 "Secure" 项目。

2. 选择 "GlassFish" 类别，然后再选择 "GlassFish Descriptor"（GlassFish 描述符）文件类型。单击 "Next"（下一步）。
image::images/new-gf-descriptor.png[title="新建文件向导中的 GlassFish 描述符文件类型"]
3. 接受该向导中的默认值，然后单击 "Finish"（完成）。

单击 "Finish"（完成），此时 IDE 将创建  ``glassfish-application.xml``  并在多视图编辑器中打开该文件。

如果在 "Projects"（项目）窗口中展开 "Secure" 企业应用程序项目节点，则可以看到描述符文件在 "Configuration Files"（配置文件）节点的下方创建。

image::images/glassfish-application-descriptor.png[title="多视图编辑器中的 "Security"（安全）标签"]
4. 在多视图编辑器的 "Security"（安全）标签中，单击 "Add Security Role Mapping"（添加安全角色映射），然后在 "Security Role Name"（安全角色名称）中键入 *USERS*。
5. 单击 "Add Group"（添加组），然后在对话框的 "Group Name"（组名称）中键入 *bank_users*。单击 "OK"（确定）。

编辑器现在应如下所示。

image::images/security-tab-descriptor.png[title="多视图编辑器中的 "Security"（安全）标签"]
6. 保存所做的更改。

通过单击多视图编辑器中的 "XML" 标签，可以在 XML 视图中查看部署描述符文件。您可以看到该部署描述符文件现在包含以下代码：


[source,xml]
----

<glassfish-application>
  <security-role-mapping>
    <role-name>USERS</role-name>
    <group-name>bank_users</group-name>
  </security-role-mapping>
</glassfish-application>
----

 ``getStatus``  方法现在是安全的，只有在服务器上指定的  ``bank_users``  组中的用户才能访问该方法。

现在，您需要一种安全设置测试方法。最简单的方法是，创建一个基本应用程序客户端，以提示用户输入用户名和口令。


== 创建应用程序客户端

在本部分中，将创建一个简单的应用程序客户端，以访问  ``AccountStatus``  会话 Bean。您可以在代码中使用  ``@EJB``  标注，以便通过远程接口调用 Bean。IDE 会将包含该接口的类库 JAR 自动添加到应用程序客户端的类路径中。

1. 选择 "File"（文件）> "New Project"（新建项目），然后在 "Java EE" 类别中选择 "Enterprise Application Client"（企业应用程序客户端）。单击 "Next"（下一步）。
2. 键入 SecureAppClient 作为项目名称。单击 "Next"（下一步）。
3. 在 "Add to Enterprise Application"（添加到企业应用程序）下拉列表中选择 *<None>*。
4. 在 "Server"（服务器）下拉列表中选择 "GlassFish Server"，并选择 "Java EE 6" 或 "Java EE 7" 作为 Java EE 版本。单击 "Finish"（完成）。

单击 "Finish"（完成），此时将在源代码编辑器中打开  ``Main.java`` 。

5. 在源代码编辑器中，右键单击  ``Main.java``  文件，并选择 "Insert Code"（插入代码）（Alt-Insert 组合键；在 Mac 上为 Ctrl-I 组合键），然后选择 "Call Enterprise Bean"（调用企业 Bean）。
6. 在 "Call Enterprise Bean"（调用企业 Bean）对话框中，展开 "Secure-ejb" 节点，然后选择 "AccountStatus"。单击 "OK"（确定）。
image::images/call-enterprise-bean.png[title=""Call Enterprise Bean"（调用企业 Bean）对话框中选中了接口"]

IDE 将在应用程序客户端中添加以下代码，用于查找会话 Bean。


[source,java]
----

@EJB
private static AccountStatusRemote accountStatus;
----

如果在 "Projects"（项目）窗口中展开 "Libraries"（库）节点，则可以看到 IDE 已将 SecureRemoteInterface JAR 添加到了项目类路径中。

7. 通过添加以下代码来修改  ``main``  方法，然后保存所做的更改。

[source,java]
----

public static void main(String[] args) {
    *System.out.println(accountStatus.getStatus());*
}
----

有关应用程序客户端的详细信息，请参见link:entappclient.html[+在 GlassFish Server 上创建和运行应用程序客户端+]。


== 运行应用程序

现在该应用程序已准备就绪。首先，将企业应用程序部署到服务器。部署企业应用程序之后，可以运行应用程序客户端，以测试该企业应用程序中的方法是否安全，以及用户角色映射是否正确。在运行应用程序客户端时，系统将提示您输入  ``bank_users``  组中用户的用户名和口令。

1. 在 "Projects"（项目）窗口中右键单击 "Secure" 企业应用程序项目节点，然后选择 "Deploy"（部署）。

在单击 "Deploy"（部署）后，IDE 将构建 EAR 文件，启动应用服务器（如果没有运行），并将该 EAR 文件部署到该服务器。

2. 在 "Projects"（项目）窗口中右键单击 "SecureAppClient" 项目节点，然后选择 "Run"（运行）。此时将出现一个对话框，提示您输入用户名和口令。
image::images/login-window.png[title="提示输入用户名和口令的登录窗口"]
3. 在对话框中输入用户名 ( ``manager`` ) 和口令 ( ``password`` )，然后单击 "OK"（确定）。"Output"（输出）窗口中将显示以下内容：

[source,java]
----

The account contains 250$
----

这是一个非常基本的示例，用于说明如何使用 Java 标注保护企业 Bean 中的方法。

link:/about/contact_form.html?to=3&subject=Feedback:%20Building%20Secure%20Enterprise%20Beans[+发送有关此教程的反馈意见+]



== 另请参见

有关使用标注和部署描述符来确保企业 Bean 安全的更多信息，请参见以下资源：

* Java EE 7 教程的link:http://docs.oracle.com/javaee/7/tutorial/doc/partsecurity.htm[+安全性+]部分的link:http://docs.oracle.com/javaee/7/tutorial/doc/security-intro003.htm[+确保容器的安全+]和link:http://docs.oracle.com/javaee/7/tutorial/doc/security-advanced008.htm[+使用部署描述符配置安全性+]这两章

有关使用 NetBeans IDE 开发 Java EE 应用程序的更多信息，请参见以下资源：

* link:javaee-intro.html[+Java EE 技术简介+]
* link:javaee-gettingstarted.html[+Java EE 应用程序入门指南+]
* link:../../trails/java-ee.html[+Java EE 和 Java Web 学习资源+]

要发送意见和建议、获得支持以及随时了解 NetBeans IDE Java EE 开发功能的最新开发情况，请link:../../../community/lists/top.html[+加入 nbj2ee 邮件列表+]。

