技术开发 频道

j2ee安全应用

  从j2ee1.3开始便提供了对ejb的方法进行授权的安全服务,这种授权服务由ejb容器实现。当调用者调用ejb的方法时,ejb容器用调用者的身份来查找授予此调用者的访问权限条目,如果调用者调用的方法属于授权条目,那么ejb容器调用方法。否则,ejb容器拒绝调用此方法,并向调用者返回拒绝访问异常。可以对远程方法和home接口方法进行授权。本例中我们将对一个远程方法和一个home接口方法进行授权。

  1 首先创建一个session bean CountEjb
  2
  3   远程接口 Count.java
  4
  5   import javax.ejb.*;
  6
  7   import java.rmi.RemoteException;
  8
  9   public interface Count extends EJBObject {
10
11   /**
12
13   * 远程方法count
14
15   */
16
17   public int count() throws RemoteException;
18
19   }
20
21   Home接口 CountHome.java
22
23   import javax.ejb.*;
24
25   import java.rmi.RemoteException;
26
27   /**
28
29   * This is the home interface for CountBean.
30
31   * One create() method is in this Home Interface, which
32
33   * corresponds to the ejbCreate() method in the CountBean file.
34
35   */
36
37   public interface CountHome extends EJBHome {
38
39   /*
40
41   * This method creates the EJB Object.
42
43   *
44
45   * @param val Value to initialize counter to
46
47   *
48
49   * @return The newly created EJB Object.
50
51   */
52
53   Count create(int val) throws RemoteException, CreateException;
54
55   }
56
57   实现类 CountBean.java
58
59   import javax.ejb.*;
60
61   import java.security.Principal;
62
63   /**
64
65   public class CountBean implements SessionBean {
66
67   // The current counter is our conversational state.
68
69   public int val;
70
71   private SessionContext sessionCtx;
72
73   //
74
75   // 远程商业方法实现
76
77   public int count() {
78
79   System.out.println("count()");
80
81   return ++val;
82
83   }
84
85   //
86
87   // home接口Create方法的实现
88
89   //
90
91   public void ejbCreate(int val) throws CreateException {
92
93   this.val = val;
94
95   System.out.println("ejbCreate()");
96
97   }
98
99   public void ejbRemove() {
100
101   System.out.println("ejbRemove()");
102
103   }
104
105   public void ejbActivate() {
106
107   System.out.println("ejbActivate()");
108
109   }
110
111   public void ejbPassivate() {
112
113   System.out.println("ejbPassivate()");
114
115   }
116
117   public void setSessionContext(SessionContext ctx) {
118
119   sessionCtx=ctx;
120
121   }
122
123   }
124
125   客户端程序 CountClient.java
126
127   import javax.ejb.*;
128
129   import javax.naming.*;
130
131   import java.util.Properties;
132
133   /**
134
135   * This class is a simple example of client code.
136
137   */
138
139   public class CountClient {
140
141   public static void main(String[] args) {
142
143   try {
144
145   InitialContext ctx = new InitialContext();
146
147   CountHome home = (CountHome)
148
149   javax.rmi.PortableRemoteObject.narrow(
150
151   ctx.lookup("java:comp/env/CountHome"), CountHome.class);
152
153   int countVal = 0;
154
155   Count count=null;
156
157   /*
158
159   创建并执行远程方法
160
161   */
162
163   System.out.println("Instantiating beans...");
164
165   count = home.create(countVal);
166
167   countVal = count.count();
168
169   System.out.println(countVal);
170
171   /*
172
173   remove Count对象
174
175   */
176
177   count.remove();
178
179   } catch (Exception e) {
180
181   System.out.println(e.getMessage());
182
183   e.printStackTrace();
184
185   }
186
187   }
188
189   }
190
191

  这个ejb包括一个远程商业方法count(),我们将将此方法授权给某个安全角色。此外还将home接口的Create()方法授权给安全角色。

  步骤1

  编译以上源程序并用j2sdkee1.3.1的组装发布工具(deploytool.bat)进行组装(如图12)。

  图12

 

  步骤2:配置安全角色

  在对方法进行授权前,必须创建将被授权的安全角色。创建安全角色的步骤前边已经介绍过了,此处不再重复。本例中我们创建名为admin的安全角色。

  步骤3:方法授权

  方法授权的过程是确定那些安全角色可以访问特定方法的过程。方法授权一般是应用程序组装或应用程序部署者的责任。他们根据企业特定的需求创建不同的安全角色,并授予这些安全角色特定的访问权限。

  用鼠标选中CountBean,在右端的窗口选择Security属性页(如图13),在Security Identity选项中选择Use Caller ID,这意味着ejb容器将用方法调用者的身份来验证方法调用权限。 Run As Specified Role选项将在"传播调用者身份标识的例子"进行介绍。由于在前面创建了admin安全角色,因此你可以看到Method Permissions栏中出现admin列。首先对远程方法count()进行授权。选择Remote选项,并在count()方法的Availability列中选择Sel Roles,然后选中count()方法的admin列。到此为止我们已对远程方法count()进行了授权。接下来对home接口的create()方法进行授权。在Show栏中选择Remote Home,剩下的步骤与count()方法授权相同。我们已经将count()方法和create()方法授权给了admin安全角色。但安全角色这是一个逻辑的集合,并不代表具体的用户或用户组,因此结下来我们要做的就是将安全角色与实际的用户映射起来。

  步骤4:角色映射

  首先我们需要在我们的j2ee环境中创建一个用户,用户起名为Tony,密码为1。

  图13

  这里我们使用用户名和密码的方式进行身份验证。我们在default Realm中创建此用户。可以使用命令行方式:"realmtool -add Tony 1 eng"。详细的使用方法参见j2sdk1.3.1文档的工具部分。接下来映射安全角色到用户。选中ejb应用CountEjb,在右边窗口中选择Security属性页(如图14),点击Edit Roles按钮,选择安全角色admin。再点击Add按钮选择Tony用户。这样已经将安全角色admin和用户Tony映射起来了。

  步骤5:部署应用

  部署应用到本地机,右键点击ejb应用CountEjb,选择弹出菜单的deploy项,按要求配置各项。

  步骤6:创建客户端

  创建客户端将客户端程序的主类和其他辅助类打包。创建端将客的过程比较简单,这里就不作描述了。

  步骤7:运行程序

  现在可以运行客户端程序来验证方法的授权了。通过命令runclient.bat -client客户端jar包文件名 -name 主类名来执行客户端程序。客户端程序的容器将显示一个对话框来提示用户输入用户名和密码(如图15),填写用户名和密码,按OK。

  图15

  若用户名或密码与授权的方法不符,则会抛出没有权限异常(如图16)。

  图16

  Countejb的部署描述文件ejb.xml

1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE ejb-jar PUBLIC
3 '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN'
4 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
5 <ejb-jar>
6   <display-name>count</display-name>    
7   <enterprise-beans>
8     <session>                          // CountBean属于session bean
9       <display-name>CountBean</display-name>  //ejb组件的显示名
10       <ejb-name>CountBean</ejb-name>         //ejb组件名
11       <home>CountHome</home>          //Home接口
12       <remote>Count</remote>             //远程接口
13       <ejb-class>CountBean</ejb-class>      //实现类
14       <session-type>Stateful</session-type>   // CountBean属于Stateful Bean
15       <transaction-type>Container</transaction-type>    //CountBean事务类型为容器管理的
16       <security-identity>                           //安全标识
17         <description></description>
18         <use-caller-identity></use-caller-identity>        //CountBean使用调用者的身份标识
19       </security-identity>
20     </session>
21   </enterprise-beans>
22   <assembly-descriptor>                          
23     <security-role>
24       <role-name>admin</role-name>             //定义安全角色admin
25     </security-role>
26     <method-permission>                //将方法count和remove授权给安全角色admin
27       <role-name>admin</role-name>
28       <method>                       //方法定义
29         <ejb-name>CountBean</ejb-name>
30         <method-intf>Remote</method-intf>
31         <method-name>count</method-name>
32         <method-params />
33       </method>
34       <method>
35         <ejb-name>CountBean</ejb-name>
36         <method-intf>Home</method-intf>
37         <method-name>remove</method-name>
38         <method-params>
39           <method-param>java.lang.Object</method-param>
40         </method-params>
41       </method>
42     </method-permission>
43     <method-permission>
44       <unchecked />              //不检查以下方法的授权
45       <method>
46         <ejb-name>CountBean</ejb-name>
47         <method-intf>Remote</method-intf>
48         <method-name>getHandle</method-name>
49         <method-params />
50       </method>
51           .
52           .
53           .
54           .
55       <method>
56         <ejb-name>CountBean</ejb-name>
57         <method-intf>Remote</method-intf>
58         <method-name>getEJBHome</method-name>
59         <method-params />
60       </method>
61     </method-permission>
62     <container-transaction>        // CountBean的事务属性
63       <method>
64         <ejb-name>CountBean</ejb-name>
65         <method-intf>Remote</method-intf>
66         <method-name>count</method-name>
67         <method-params />
68       </method>
69       <trans-attribute>Required</trans-attribute>
70     </container-transaction>
71   </assembly-descriptor>
72 </ejb-jar>
73
  
0
相关文章