<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kapok

    垃圾桶,嘿嘿,我藏的這么深你們還能找到啊,真牛!

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      455 隨筆 :: 0 文章 :: 76 評(píng)論 :: 0 Trackbacks
    http://www-128.ibm.com/developerworks/cn/java/l-j2eesecurity2/index.html
    系統(tǒng)架構(gòu)工程師、系統(tǒng)分析員
    2002 年 9 月 02 日
    在本系列文章的第一部分作者介紹了j2ee的安全概念、驗(yàn)證模型和授權(quán)模型,這部分更偏重于理論的介紹。本文的第二部分作者將通過具體的例子向讀者展示如何在開發(fā)中應(yīng)用j2ee提供的安全服務(wù)。本部分的重點(diǎn)在于應(yīng)用與實(shí)踐。

    注釋:本文的目的是介紹如何應(yīng)用j2ee提供的安全服務(wù),而并不針對(duì)特定的產(chǎn)品。因此作者選擇sun的 j2ee參考實(shí)現(xiàn)(j2sdkee)作為演示平臺(tái)。因?yàn)閖2sdkee是完全遵照j2ee規(guī)范開發(fā)的,雖然它不像IBM WebSphere 、BEA WebLogic等j2ee產(chǎn)品那么產(chǎn)品化和商業(yè)化,但它絕對(duì)是學(xué)習(xí)j2ee的理想平臺(tái)。你可以通過 http://java.sun.com/j2ee/獲取sun 的j2ee參考實(shí)現(xiàn)的最新版本。本文選擇的是Sun的j2sdkee1.3.1。

    本文將包括以下內(nèi)容:

    1. 一個(gè)采用HTTP基本的驗(yàn)證的例子
    2. 一個(gè)采用基于表單的驗(yàn)證的例子
    3. 一個(gè)ejb方法授權(quán)的例子
    4. 一個(gè)可編程安全性和傳播調(diào)用者身份標(biāo)識(shí)的例子

    采用HTTP基本的驗(yàn)證的例子

    http基本驗(yàn)證是Web客戶端驗(yàn)證的一種,它和系統(tǒng)的授權(quán)機(jī)制一起控制受保護(hù)資源的訪問。

    步驟:

    1. 創(chuàng)建一個(gè)j2ee應(yīng)用
    在應(yīng)用程序部署工具的File菜單選中New子菜單中的Application菜單項(xiàng)(見圖1)。會(huì)彈出新建應(yīng)用程序?qū)υ捒颉L顚憫?yīng)用程序文件名和應(yīng)用程序顯示名(見圖2)。

    圖1
    圖1

    圖2
    圖2

    2. 創(chuàng)建一個(gè)web組件
    在應(yīng)用程序部署工具的File菜單選中New子菜單中的Web Compent菜單項(xiàng),會(huì)彈出新建web組件向?qū)?duì)話框(見圖3)。選擇Create New WAR File in Application,在下拉框中選擇步驟1創(chuàng)建的應(yīng)用test,在WAR Display Name框中填寫WebAppTest.點(diǎn)擊Content欄中的Eidt按鈕選擇此Web組件包含的文件。在這個(gè)例子中只有一個(gè)webtest.jsp文件。然后點(diǎn)擊Next,進(jìn)入下一個(gè)對(duì)話框(見圖4)。由于我們的web組件是一個(gè)jsp文件,因此在組件類型中選擇JSP。然后一直按Next直到結(jié)束。此時(shí)我們已經(jīng)創(chuàng)建了一個(gè)只包含一個(gè)jsp文件的web組件。接下來是配置安全屬性的步驟。

    圖3
    圖3

    圖4
    圖4

    3. 配置安全屬性
    3.1創(chuàng)建安全角色

    在部署工具的左導(dǎo)航欄中點(diǎn)中步驟2創(chuàng)建的web組件WebAppTest,在右邊的屬性頁中選擇Roles屬性頁(見圖5)。點(diǎn)擊Add按鈕,在Name欄中填寫安全角色名user,Description欄填寫描述信息。安全角色代表具有相同安全權(quán)限用戶的集合。

    圖5
    圖5

    3.2 配置安全策略

    創(chuàng)建了安全角色后,應(yīng)該對(duì)安全角色配置相應(yīng)的安全策略。點(diǎn)擊Security屬性頁(見圖6)。

    圖6
    圖6

    首先選擇你想用的驗(yàn)證方式,從User Authentication Method下拉框中選擇Basic。這意味著你將通過基本的HTTP驗(yàn)證方式驗(yàn)證用戶。下面我們進(jìn)行web資源的授權(quán)。點(diǎn)擊Security Constraint欄中的Add按鈕添加一條安全約束,約束名可以自定。接下來對(duì)創(chuàng)建好的約束添加Web資源。首先在Web Resource Collections中添加資源集合,然后選取資源集合包含的資源。此例中WRCollection資源集合中包含webtest.jsp文件,也可以包含各種屬于這個(gè)web組件的文件。接下來選擇哪些web操作要收到約束,j2sdkee1.3.1中只包含兩種操作(GET和POST),不同的產(chǎn)品支持的操作有所不同,在開發(fā)是應(yīng)結(jié)合具體產(chǎn)品提供的操作來選取。現(xiàn)在應(yīng)該指定安全角色了,點(diǎn)擊Authorized Roles欄中的Edit按鈕,會(huì)彈出安全角色列表對(duì)話框,從中選取已定義的安全角色。本例中選擇user。至此安全策略已經(jīng)配置完畢,下面的步驟是將實(shí)際環(huán)境中的用戶和用戶組映射與安全角色進(jìn)行映射。

    4. 映射
    在左導(dǎo)航欄中選中應(yīng)用程序test在右邊選擇Security屬性頁(見圖7),在Role Name Reference欄中選中user,點(diǎn)擊正下方的Add按鈕,會(huì)彈出用戶和用戶組列表對(duì)話框,從中選擇要映射成安全角色user的用戶或組。此例中我們將用戶j2ee映射為安全角色user。這樣用戶J2ee將具有為安全角色user分配的訪問授權(quán)。

    圖7
    圖7

    5. 部署應(yīng)用
    選中Web Context屬性頁,在Context Root文本框中填寫test,右鍵點(diǎn)擊左導(dǎo)航欄的應(yīng)用test,在彈出菜單中選擇deploy完成應(yīng)用程序的發(fā)布。至此我們完成了第一個(gè)例子的全部步驟。

    部署描述文件

    這個(gè)例子使用了說明性的安全服務(wù),因此我們不需要編寫任何的安全相關(guān)的代碼,而是完全通過配置組件的部署描述文件來實(shí)現(xiàn)的。下面是這個(gè)web組件的部署描述文件。

    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app PUBLIC 
    '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'
    'http://java.sun.com/dtd/web-app_2_3.dtd'>
    <web-app>
      <display-name>WebAppTest</display-name>     //Web組件名稱
      <servlet>
        <servlet-name>webtest</servlet-name>
        <display-name>webtest</display-name>
        <jsp-file>/webtest.jsp</jsp-file>              //組件中包含的jsp文件
      </servlet>
      <session-config>
        <session-timeout>30</session-timeout>
      </session-config>
      <security-constraint>                                //安全約束部分
        <web-resource-collection>                         //受約束的web資源集
          <web-resource-name>WRCollection</web-resource-name>  //資源集名
          <url-pattern>/webtest.jsp</url-pattern>                  //資源的url表達(dá)式
          <http-method>GET</http-method>                     //受約束的資源操作方法
          <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>                                    //對(duì)安全角色授權(quán)
          <role-name>user</role-name>                        //安全角色名
        </auth-constraint>
        <user-data-constraint>
          <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
      </security-constraint>
      <login-config>                                        //驗(yàn)證方式設(shè)置
        <auth-method>BASIC</auth-method>                   //使用基本的HTTP驗(yàn)證方式
        <realm-name></realm-name>
      </login-config>
      <security-role>                                        //定義安全角色
        <description>this is a user</description>                      
        <role-name>user</role-name>
      </security-role>
    </web-app>
    

    從部署描述文件可以知道這是一個(gè)名為WebAppTest的web組件,包含一個(gè)名為webtest.jsp的文件,只有被賦予user安全角色的用戶或用戶組才有權(quán)對(duì)webtest.jsp進(jìn)行GET或POST操作。這里并沒有包含安全角色對(duì)實(shí)際用戶的映射,j2ee部署描述文件的DTD中并沒有定義用于安全角色和實(shí)際用戶的映射的元素,因?yàn)閷?shí)際環(huán)境中有多種不同的用戶系統(tǒng)(如關(guān)系數(shù)據(jù)庫,系統(tǒng)文件形式和LDAP系統(tǒng)等)。因此安全角色和實(shí)際用戶的映射方式是由j2ee產(chǎn)品廠商制定的。

    測(cè)試運(yùn)行結(jié)果

    打開ie,在導(dǎo)航欄輸入http://localhost:8000/test/webtest.jsp回車,會(huì)彈出驗(yàn)證對(duì)話框,要求用戶提供用戶名和密碼(見圖8),輸入用戶名j2ee和密碼j2ee。通過用戶驗(yàn)證后執(zhí)行jsp文件,webtest.jsp打印出"hello!"(見圖9)。

    圖8
    圖8

    圖9
    圖9

    注釋:在第一個(gè)例子中已經(jīng)詳細(xì)的描述了各個(gè)步驟,在接下來的例子中會(huì)有一些與第一個(gè)例子相同的操作,因此對(duì)下面的例子只描述與第一個(gè)例子不同的步驟。

    基于表單的驗(yàn)證的例子

    基于表單的驗(yàn)證與基本的HTTP驗(yàn)證的唯一區(qū)別是基本的HTTP驗(yàn)證用瀏覽器提供的驗(yàn)證信息對(duì)話框收集用戶驗(yàn)證信息,而基于表單的驗(yàn)證允許自定義登陸頁面來收集用戶驗(yàn)證信息。本例子與第一個(gè)例子的步驟基本相同,不同的地方在于此例子要提供登陸頁面和出錯(cuò)頁面。

    登陸頁面login.html

    
    <form method="POST" action="j_security_check">
    <input type=text name="j_username">
    <input type=password name="j_password">
    <input type=submit name="login" value="login">
    </form>
    

    此文件有幾個(gè)地方值得注意:

    1. Action的值必須為"j_security_check"
    2. 獲取用戶名的域名必須是"j_username"
    3. 獲取用戶密碼的域必須是" j_password"

    出錯(cuò)頁面 error.html

    
    <html>
    用戶名或密碼不正確!
    </html>
    

    出錯(cuò)頁面只是簡(jiǎn)單的顯示出錯(cuò)信息。

    配置基于表單的驗(yàn)證

    首先將login.html和error.html加入到WebAppTest組件中。
    然后見圖10選擇Security屬性頁,在User Authentication Method下拉框中選擇Form Based選項(xiàng)。點(diǎn)擊Settings…彈出用戶驗(yàn)證設(shè)置對(duì)話框,在Login Page下拉框選login.html,在Error Page下拉框選error.html。

    圖10
    圖10

    重新部署應(yīng)用,再一次訪問http://localhost:8000/test/webtest.jsp 會(huì)出現(xiàn)login頁面(見圖11),如果用戶名或密碼錯(cuò)誤,error.html將顯示給用戶。

    圖11
    圖11

    部署描述文件

    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app PUBLIC 
    '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'
    'http://java.sun.com/dtd/web-app_2_3.dtd'>
    <web-app>
      <display-name>WebAppTest</display-name>     
                     .
                     .
                     .
    <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
      </security-constraint>
    <login-config>
        <auth-method>FORM</auth-method>                   //使用基于表單的驗(yàn)證方式
        <realm-name>Default</realm-name>                    //使用缺省的安全域
        <form-login-config>
          <form-login-page>/login.html</form-login-page>        //定義登陸頁面
          <form-error-page>/error.html</form-error-page>       //定義出錯(cuò)頁面
        </form-login-config>
      </login-config>
    <security-role>                                        
        <description>this is a user</description>                      
        <role-name>user</role-name>
      </security-role>
    </web-app>
    

    ejb方法授權(quán)的例子

    從j2ee1.3開始便提供了對(duì)ejb的方法進(jìn)行授權(quán)的安全服務(wù),這種授權(quán)服務(wù)由ejb容器實(shí)現(xiàn)。當(dāng)調(diào)用者調(diào)用ejb的方法時(shí),ejb容器用調(diào)用者的身份來查找授予此調(diào)用者的訪問權(quán)限條目,如果調(diào)用者調(diào)用的方法屬于授權(quán)條目,那么ejb容器調(diào)用方法。否則,ejb容器拒絕調(diào)用此方法,并向調(diào)用者返回拒絕訪問異常。可以對(duì)遠(yuǎn)程方法和home接口方法進(jìn)行授權(quán)。本例中我們將對(duì)一個(gè)遠(yuǎn)程方法和一個(gè)home接口方法進(jìn)行授權(quán)。

    
    首先創(chuàng)建一個(gè)session bean CountEjb
    遠(yuǎn)程接口 Count.java
    import javax.ejb.*;
    import java.rmi.RemoteException;
    
    public interface Count extends EJBObject {
    
      /**
       * 遠(yuǎn)程方法count
       */
      public int count() throws RemoteException;
    }
    
    Home接口 CountHome.java
    import javax.ejb.*;
    import java.rmi.RemoteException;
    
    /**
     * This is the home interface for CountBean.  
     * One create() method is in this Home Interface, which
     * corresponds to the ejbCreate() method in the CountBean file.
     */
    public interface CountHome extends EJBHome {
    
       /*
        * This method creates the EJB Object.
        *
        * @param val Value to initialize counter to
        *
        * @return The newly created EJB Object.
        */
      Count create(int val) throws RemoteException, CreateException;
    }
    
    實(shí)現(xiàn)類 CountBean.java
    import javax.ejb.*;
    import java.security.Principal;
    
    /**
     
    public class CountBean implements SessionBean {
    	
    	// The current counter is our conversational state.
    	public int val;
        private SessionContext sessionCtx;
            
    	//
    	// 遠(yuǎn)程商業(yè)方法實(shí)現(xiàn)
    	public int count() {
    		System.out.println("count()");
              
    		return ++val;
    	}
    
    	//
    	// home接口Create方法的實(shí)現(xiàn)
    	//
    
    	public void ejbCreate(int val) throws CreateException {
    		this.val = val;
    		System.out.println("ejbCreate()");
    	}
    
    	public void ejbRemove() {
    		System.out.println("ejbRemove()");
    	}
    
    	public void ejbActivate() {
    		System.out.println("ejbActivate()");
    	}
    
    	public void ejbPassivate() {
    		System.out.println("ejbPassivate()");
    	}
    
    	public void setSessionContext(SessionContext ctx) {
                sessionCtx=ctx;
    	}
    }
    客戶端程序 CountClient.java
    import javax.ejb.*;
    import javax.naming.*;
    import java.util.Properties;
    
    /**
     * This class is a simple example of client code.
     */
    public class CountClient {
    
    	public static void main(String[] args) {
    
    		try {
    			
                InitialContext ctx = new InitialContext();
                            
    			CountHome home = (CountHome)
    			  javax.rmi.PortableRemoteObject.narrow(
    			    ctx.lookup("java:comp/env/CountHome"), CountHome.class);
    			   
    
    			int countVal = 0;
    			Count count=null;
    
    			/*
    			創(chuàng)建并執(zhí)行遠(yuǎn)程方法			
    */
    			System.out.println("Instantiating beans...");
    			
    				 
    				count = home.create(countVal);
                                   
    				countVal = count.count();
    
    				System.out.println(countVal);
    
    			/*
    			 remove Count對(duì)象 
    			 */
    			count.remove();
    		
    		} catch (Exception e) {
                System.out.println(e.getMessage());
    			e.printStackTrace();
    		}
    	}
    }
    

    這個(gè)ejb包括一個(gè)遠(yuǎn)程商業(yè)方法count(),我們將將此方法授權(quán)給某個(gè)安全角色。此外還將home接口的Create()方法授權(quán)給安全角色。

    步驟1

    編譯以上源程序并用j2sdkee1.3.1的組裝發(fā)布工具(deploytool.bat)進(jìn)行組裝(如圖12)。

    圖12
    圖12

    步驟2:配置安全角色

    在對(duì)方法進(jìn)行授權(quán)前,必須創(chuàng)建將被授權(quán)的安全角色。創(chuàng)建安全角色的步驟前邊已經(jīng)介紹過了,此處不再重復(fù)。本例中我們創(chuàng)建名為admin的安全角色。

    步驟3:方法授權(quán)

    方法授權(quán)的過程是確定那些安全角色可以訪問特定方法的過程。方法授權(quán)一般是應(yīng)用程序組裝或應(yīng)用程序部署者的責(zé)任。他們根據(jù)企業(yè)特定的需求創(chuàng)建不同的安全角色,并授予這些安全角色特定的訪問權(quán)限。

    用鼠標(biāo)選中CountBean,在右端的窗口選擇Security屬性頁(如圖13),在Security Identity選項(xiàng)中選擇Use Caller ID,這意味著ejb容器將用方法調(diào)用者的身份來驗(yàn)證方法調(diào)用權(quán)限。 Run As Specified Role選項(xiàng)將在"傳播調(diào)用者身份標(biāo)識(shí)的例子"進(jìn)行介紹。由于在前面創(chuàng)建了admin安全角色,因此你可以看到Method Permissions欄中出現(xiàn)admin列。首先對(duì)遠(yuǎn)程方法count()進(jìn)行授權(quán)。選擇Remote選項(xiàng),并在count()方法的Availability列中選擇Sel Roles,然后選中count()方法的admin列。到此為止我們已對(duì)遠(yuǎn)程方法count()進(jìn)行了授權(quán)。接下來對(duì)home接口的create()方法進(jìn)行授權(quán)。在Show欄中選擇Remote Home,剩下的步驟與count()方法授權(quán)相同。我們已經(jīng)將count()方法和create()方法授權(quán)給了admin安全角色。但安全角色這是一個(gè)邏輯的集合,并不代表具體的用戶或用戶組,因此結(jié)下來我們要做的就是將安全角色與實(shí)際的用戶映射起來。

    步驟4:角色映射

    首先我們需要在我們的j2ee環(huán)境中創(chuàng)建一個(gè)用戶,用戶起名為Tony,密碼為1。

    圖13
    圖13

    這里我們使用用戶名和密碼的方式進(jìn)行身份驗(yàn)證。我們?cè)赿efault Realm中創(chuàng)建此用戶。可以使用命令行方式:"realmtool -add Tony 1 eng"。詳細(xì)的使用方法參見j2sdk1.3.1文檔的工具部分。接下來映射安全角色到用戶。選中ejb應(yīng)用CountEjb,在右邊窗口中選擇Security屬性頁(如圖14),點(diǎn)擊Edit Roles按鈕,選擇安全角色admin。再點(diǎn)擊Add按鈕選擇Tony用戶。這樣已經(jīng)將安全角色admin和用戶Tony映射起來了。

    步驟5:部署應(yīng)用

    部署應(yīng)用到本地機(jī),右鍵點(diǎn)擊ejb應(yīng)用CountEjb,選擇彈出菜單的deploy項(xiàng),按要求配置各項(xiàng)。

    步驟6:創(chuàng)建客戶端

    創(chuàng)建客戶端將客戶端程序的主類和其他輔助類打包。創(chuàng)建端將客的過程比較簡(jiǎn)單,這里就不作描述了。

    步驟7:運(yùn)行程序

    現(xiàn)在可以運(yùn)行客戶端程序來驗(yàn)證方法的授權(quán)了。通過命令runclient.bat -client客戶端jar包文件名 -name 主類名來執(zhí)行客戶端程序。客戶端程序的容器將顯示一個(gè)對(duì)話框來提示用戶輸入用戶名和密碼(如圖15),填寫用戶名和密碼,按OK。

    圖15
    圖15

    若用戶名或密碼與授權(quán)的方法不符,則會(huì)拋出沒有權(quán)限異常(如圖16)。

    圖16
    圖16

    Countejb的部署描述文件ejb.xml

    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE ejb-jar PUBLIC 
    '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' 
    'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
    
    <ejb-jar>
      <display-name>count</display-name>     
      <enterprise-beans>
        <session>                          // CountBean屬于session bean
          <display-name>CountBean</display-name>  //ejb組件的顯示名
          <ejb-name>CountBean</ejb-name>         //ejb組件名
    
          <home>CountHome</home>          //Home接口
          <remote>Count</remote>             //遠(yuǎn)程接口
          <ejb-class>CountBean</ejb-class>      //實(shí)現(xiàn)類
          <session-type>Stateful</session-type>   // CountBean屬于Stateful Bean
          <transaction-type>Container</transaction-type>    //CountBean事務(wù)類型為容器管理的
          <security-identity>                           //安全標(biāo)識(shí)
            <description></description>
            <use-caller-identity></use-caller-identity>		//CountBean使用調(diào)用者的身份標(biāo)識(shí)
          </security-identity>
        </session>
      </enterprise-beans>
      <assembly-descriptor>                           
        <security-role>
          <role-name>admin</role-name>             //定義安全角色admin
        </security-role>
        <method-permission>                //將方法count和remove授權(quán)給安全角色admin
          <role-name>admin</role-name>
    
          <method>                       //方法定義
            <ejb-name>CountBean</ejb-name>
            <method-intf>Remote</method-intf>
            <method-name>count</method-name>
            <method-params />
          </method>
          <method>
            <ejb-name>CountBean</ejb-name>
            <method-intf>Home</method-intf>
            <method-name>remove</method-name>
            <method-params>
              <method-param>java.lang.Object</method-param>
            </method-params>
          </method>
        </method-permission>
        <method-permission>
          <unchecked />              //不檢查以下方法的授權(quán)
          <method>
            <ejb-name>CountBean</ejb-name>
            <method-intf>Remote</method-intf>
            <method-name>getHandle</method-name>
            <method-params />
          </method>
              .
              .
              .
              .
          <method>
            <ejb-name>CountBean</ejb-name>
            <method-intf>Remote</method-intf>
            <method-name>getEJBHome</method-name>
            <method-params />
          </method>
        </method-permission>
        <container-transaction>        // CountBean的事務(wù)屬性
          <method>
            <ejb-name>CountBean</ejb-name>
            <method-intf>Remote</method-intf>
            <method-name>count</method-name>
            <method-params />
          </method>
          <trans-attribute>Required</trans-attribute>
        </container-transaction>
      </assembly-descriptor>
    </ejb-jar>
    

    可編程安全性和傳播調(diào)用者身份標(biāo)識(shí)的例子

    此例程包括兩個(gè)部分,分別演示可編程安全性和調(diào)用者身份傳播。

    可編程安全性例程
    可編程安全性可應(yīng)用在web層和EJB層,分別是通過javax.servlet.http.HttpServletRequest接口的isUserInRole ()、getUserPrincipal ()方法和javax.ejb.EJBContext接口的isCallerInRole ()、getCallerPrincipal ()方法來實(shí)現(xiàn)的。 public boolean isUserInRole(java.lang.String role)方法此方法用來判斷調(diào)用者是否屬于某一特定的安全角色,如果屬于返回true,否則返回false。參數(shù)role指定某一安全角色。通過此方法開發(fā)者可以在程序代碼中加入自己的安全邏輯判斷,從而增強(qiáng)了J2EE在安全方面的靈活性。

    public java.security.Principal getUserPrincipal()方法調(diào)用此方法可以得到一個(gè)java.security.Principal對(duì)象,此對(duì)象包含了調(diào)用者的用戶名,通過Principal.getName()方法可以得到用戶名。通過調(diào)用getUserPrincipal()方法開發(fā)者可以得到調(diào)用者的用戶名,然后對(duì)調(diào)用者的用戶名進(jìn)行特定的邏輯判斷。

    public java.security.Principal getCallerPrincipal()方法 和public boolean isCallerInRole(java.lang.String roleName)方法的作用和方法同上。

    下面我們通過例程來演示這些方法的用法
    程序清單:
    webtest.jsp

    
    <%@page contentType="text/html"%>
    <html>
    <head><title>JSP Page</title></head>
    <body>
    
    <%-- <jsp:useBean id="beanInstanceName" scope="session" class="package.class" /> --%>
    <%-- <jsp:getProperty name="beanInstanceName"  property="propertyName" /> --%>
    Hello!
    the caller is <%=request.getUserPrincipal().getName()%><br/> <%--得到調(diào)用者的用戶名--%>
    <% if (request.isUserInRole("admin")){%>  <%--判斷調(diào)用者是否屬于"admin"安全角色--%>
    the caller is admin Role;
    <%} %>
    </body>
    </html>
    
    web.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app PUBLIC 
    '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' 
    'http://java.sun.com/dtd/web-app_2_3.dtd'>
    <web-app>
      <display-name>WebApp</display-name>
      <servlet>
        <servlet-name>webtest</servlet-name>
        <display-name>webtest</display-name>
        <jsp-file>/webtest.jsp</jsp-file>
        <security-role-ref>
          <role-name>adminref</role-name>
          <role-link>admin</role-link>
        </security-role-ref>
        <security-role-ref>
          <role-name>guestref</role-name>
          <role-link>guest</role-link>
        </security-role-ref>
      </servlet>
      <session-config>
        <session-timeout>30</session-timeout>
      </session-config>
      <welcome-file-list>
        <welcome-file>webtest.jsp</welcome-file>
      </welcome-file-list>
      <security-constraint>
        <web-resource-collection>
          <web-resource-name>WRCollection</web-resource-name>
          <url-pattern>/webtest.jsp</url-pattern>
          <http-method>GET</http-method>
          <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
          <role-name>admin</role-name>
          <role-name>guest</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></realm-name>
      </login-config>
      <security-role>
        <role-name>admin</role-name>
      </security-role>
      <security-role>
        <role-name>guest</role-name>
      </security-role>
    </web-app>
    

    從web.xml文件的內(nèi)容可以看出,只有安全角色為"admin"和"guest"的用戶才有權(quán)對(duì)webtest.jsp文件進(jìn)行POST和GET操作。

    運(yùn)行結(jié)果:

    創(chuàng)建一個(gè)web應(yīng)用,將webtest.jsp作為一個(gè)web組件,并按照web.xml的內(nèi)容配置web應(yīng)用,在運(yùn)行環(huán)境中將用戶j2ee分配為admin安全角色,將用戶Tony分配為guest角色。發(fā)布web應(yīng)用到本地j2ee Server上。用ie訪問webtest.jsp 如圖17用用戶j2ee的身份進(jìn)行驗(yàn)證,用戶j2ee屬于admin安全角色。顯示結(jié)果見圖18

    圖17
    圖17

    圖18
    圖18

    如果用用戶Tony進(jìn)行驗(yàn)證,結(jié)果見圖19

    圖19
    圖19

    ejb中應(yīng)用可編程的安全性與在web中的方法相似,本文不再進(jìn)行介紹

    傳播調(diào)用者身份標(biāo)識(shí)例程

    本例程將演示調(diào)用者身份標(biāo)識(shí)如何在調(diào)用鏈中傳遞的,并且介紹如何應(yīng)用"Run As"來實(shí)現(xiàn)在調(diào)用鏈中更改調(diào)用者的身份。本例將用一個(gè)web組件(一個(gè)jsp文件)和兩個(gè)ejb組件來形成一個(gè)調(diào)用鏈。
    程序清單:
    webtest.jsp

    
    <%@page contentType="text/html"%>
    <%@page import="andy.*"%>
    <%@page import="javax.naming.*"%>
    <html>
    <head><title>JSP Page</title></head>
    <body>
    
    <%-- <jsp:useBean id="beanInstanceName" scope="session" class="package.class" /> --%>
    <%-- <jsp:getProperty name="beanInstanceName"  property="propertyName" /> --%>
    Hello!
    the caller is <%=request.getUserPrincipal().getName()%> <br/>
    <% if (request.isUserInRole("admin")){%>
    the caller is admin Role;
    <%} %>
    <%  
        try {
        Context ctx = new InitialContext();
        andy.CountHome home = 
    (andy.CountHome)javax.rmi.PortableRemoteObject.narrow(
    ctx.lookup("java:comp/env/CountHome"), andy.CountHome.class);
        andy.Count count = home.create(1);
        count.count();
        }catch (Exception e) 
        {
    	e.printStackTrace();
        }
    %>
    </body>
    </html>
    

    CountBean.java

    
    package andy;
    import javax.ejb.*;
    import javax.naming.*;
    public class CountBean implements SessionBean {
    	public int val;
        private SessionContext EjbCxt = null;
    	public int count()
    {
            int temp = 0;
    		System.out.println("CountBean.count()");
    		//打印調(diào)用者名
            System.out.println("the caller is "+EjbCxt.getCallerPrincipal().getName());
    		//判斷調(diào)用者的安全角色
            if(EjbCxt.isCallerInRole("adminref")) // adminref為安全角色admin的引用名
            {
                System.out.println("the caller is admin Role");
             }
             if(EjbCxt.isCallerInRole("guestref")) // guestref為安全角色guest的引用名
             {
                  System.out.println("the caller is guest Role");
              }
             if(EjbCxt.isCallerInRole("userref")) // userref為安全角色user的引用名
             {
                  System.out.println("the caller is user Role");
              }
             //調(diào)用另一個(gè)ejb的遠(yuǎn)程方法
              try {
                       Context ctx = new InitialContext();
                       CountHome1 home = 
    (CountHome1)javax.rmi.PortableRemoteObject.narrow(
    ctx.lookup("java:comp/env/CountHome1"), CountHome1.class);
              Count1 count = home.create(1);
              temp = count.count();
              }catch (Exception e) 
                    {
                          e.printStackTrace();
                     }
    		return ++temp;
    	}
    	public void ejbCreate(int val) throws CreateException {
    		this.val = val;
    	}
    	public void ejbRemove() {
    	}
    	public void ejbActivate() {
    	}
    	public void ejbPassivate() {
    	}
    	public void setSessionContext(SessionContext ctx) {
                EjbCxt = ctx;  //獲取EjbContext對(duì)象
    	}
    }
    
    CountBean1.java
    package andy;
    import javax.ejb.*;
    
    public class CountBean1 implements SessionBean {
    	public int val;
        private SessionContext EjbCxt = null; 
    	public int count() {
    		System.out.println("CountBean1.count()");
            System.out.println("the caller is "+EjbCxt.getCallerPrincipal().getName());
                    if(EjbCxt.isCallerInRole("adminref"))
                    {
                        System.out.println("the caller is admin Role");
                    }
                    if(EjbCxt.isCallerInRole("guestref"))
                    {
                        System.out.println("the caller is guest Role");
                    }
                    if(EjbCxt.isCallerInRole("userref"))
                    {
                        System.out.println("the caller is user Role");
                    }
                    
    		return ++val;
    	}
    	public void ejbCreate(int val) throws CreateException {
    		this.val = val;
    	}
    	public void ejbRemove() {
    	}
    	public void ejbActivate() {
    	}
    	public void ejbPassivate() {
    	}
    	public void setSessionContext(SessionContext ctx) {
                EjbCxt = ctx;
    	}
    }
    

    以上的三個(gè)文件分別是一個(gè)web組件和兩個(gè)ejb組件的源代碼,這三個(gè)組件構(gòu)成了一個(gè)調(diào)用鏈.webtest.jsp中,首先通過HttpServletRequest..getUserPrincipal ()方法來得到調(diào)用webtest.jsp的用戶的Principal對(duì)象,在通過Principal.getName()方法得到調(diào)用者的用戶名. 然后通過HttpServletRequest..isUserInRole()方法來判斷調(diào)用這是否屬于特定的安全角色.CountBean是一個(gè)stateful SessoinBean,它擁有一個(gè)count()遠(yuǎn)程方法,在這個(gè)遠(yuǎn)程方法中寫了用于得到調(diào)用者用戶名和判斷調(diào)用這安全角色的代碼,還包括調(diào)用CountBean1對(duì)象的代碼,用于展示調(diào)用者身份標(biāo)識(shí)是如何在調(diào)用鏈中傳遞和調(diào)用者的安全角色如何被改變的.CountBean1也是一個(gè)stateful SessoinBean,它的代碼內(nèi)容與CountBean基本相同,只不過它不包含調(diào)用其他Bean的代碼.

    現(xiàn)在我們應(yīng)該配置各組件的安全屬性了.我們?cè)诮M件webtest中創(chuàng)建安全角色admin,引用名為adminref,在組件CountBean和CountBean1中分別創(chuàng)建安全角色admin和user, 引用名分別為adminref和userref.將webtest組件配置為"HTTP Basic Authentication",給安全角色admin賦予訪問webtest.jsp的權(quán)限.把CountBean設(shè)置為Run As Specified Role,選擇user安全角色.在運(yùn)行環(huán)境中將用戶j2ee賦予admin安全角色和user安全角色.然后發(fā)布應(yīng)用到服務(wù)器.用用戶j2ee訪問webtest.jsp.

    執(zhí)行結(jié)果:
    客戶端見圖20

    圖20
    圖20

    服務(wù)器端:
    CountBean.count()
    the caller is j2ee
    the caller is admin Role
    CountBean1.count()
    the caller is j2ee
    the caller is user Role

    從運(yùn)行結(jié)果看,訪問webtest.jsp的用戶為j2ee,其安全角色為admin,訪問CountBean的用戶名為j2ee,安全角色為admin.可以看到用戶身份標(biāo)識(shí)從web容器傳遞到了ejb容器.再看組件CountBean1的輸出結(jié)果,由于CountBean被設(shè)置成了Run As Specified Role,因此在CountBean向下調(diào)用其他組件對(duì)象時(shí),用戶安全角色已經(jīng)被改為指定的安全角色,這里是user.所以我們會(huì)看到,調(diào)用組件CountBean1的用戶名為j2ee,安全角色為user.j2ee的這種安全特性滿足了同一用戶在不同應(yīng)用中具有不同安全角色的需求.開發(fā)人員也可以利用這種特性進(jìn)行靈活的安全邏輯判斷.

    關(guān)于作者
    王妍 某軟件公司系統(tǒng)架構(gòu)工程師、系統(tǒng)分析員,具有4年java開發(fā)工作的經(jīng)驗(yàn),對(duì)j2ee、ejb有較深的了解。 希望與廣大java愛好者進(jìn)行技術(shù)交流。Email: babaraNo_1@hotmail.com
    posted on 2005-04-14 17:39 笨笨 閱讀(1051) 評(píng)論(2)  編輯  收藏 所屬分類: J2EEALL

    評(píng)論

    # re: J2EE 中的安全第二部分--j2ee安全應(yīng)用 2005-10-27 13:59 libo-jlu-314
    客戶端調(diào)用EJB的方法,Ejb的方法是按角色來授權(quán)的,
    我在客戶端使用JAAS驗(yàn)證用戶后,是如何把這個(gè)用戶的角色加到Subject中的呢?
      回復(fù)  更多評(píng)論
      

    # re: J2EE 中的安全第二部分--j2ee安全應(yīng)用 2005-10-27 14:00 libo-jlu-314
    能幫忙給我個(gè)答案嗎?
      回復(fù)  更多評(píng)論
      

    主站蜘蛛池模板: kk4kk免费视频毛片| 亚洲中文字幕人成乱码| 久久亚洲中文字幕精品一区四| 免费毛片在线播放| 韩国欧洲一级毛片免费| 最近最好的中文字幕2019免费| 国产高清不卡免费在线| 久久受www免费人成_看片中文| 18禁免费无码无遮挡不卡网站| 黄页网站在线看免费| 日韩吃奶摸下AA片免费观看 | 2020天堂在线亚洲精品专区| 亚洲国产综合人成综合网站00| 亚洲国产成人久久77| 亚洲国产精品一区二区三区在线观看| 国产精品亚洲精品青青青 | 亚洲AⅤ永久无码精品AA| 亚洲色婷婷综合开心网| 亚洲精品无码不卡在线播HE| 久久精品国产亚洲av麻| 麻豆亚洲AV永久无码精品久久| 亚洲色图.com| 亚洲人成电影网站免费| 久久水蜜桃亚洲AV无码精品| 久久精品免费网站网| 特级精品毛片免费观看| 青娱分类视频精品免费2| 宅男666在线永久免费观看| 4338×亚洲全国最大色成网站| 亚洲乱码一区二区三区在线观看| 亚洲天堂中文字幕| 亚洲熟妇AV一区二区三区浪潮| 色妞WWW精品免费视频| 国产成人在线观看免费网站 | 日韩电影免费观看| 日本亚洲免费无线码| 亚洲?v女人的天堂在线观看| 亚洲av永久无码精品漫画 | 亚洲一区二区三区免费观看| 精品国产日韩亚洲一区91 | 亚洲AV香蕉一区区二区三区|