1. 程式人生 > >開源jsp許可權管理,實現程式碼

開源jsp許可權管理,實現程式碼

事情挺讓我頭痛的,記得一年前在瀋陽,我曾經有一段時間也因因這個問題而疲於奔命,為什麼說疲於奔命呢?由

於當時專案進度不允許,導致最終系統許可權模組草草了事,每個模組都是由讀許可權字串來控制使用者ACL,當用戶無

法訪問時,提示許可權不夠。這麼做對使用者是很不負責任的,既然讓使用者看到了操作的方式和介面,為什麼又告訴用

戶沒有許可權呢?我開始懷疑我們是否應該在底層就封殺使用者的訪問許可權。

現在專案開展起來了,雖然目前我已經有了對許可權控制的一套方案,並且實施成了我的可重用框架程式碼,雖然目前

的許可權也是基於眾星捧月的AOP思想,但我至今對許可權設計仍有兩個疑惑:

疑惑一:很多同行提出方案,想要在底層就擷取使用者許可權,控制使用者對方法或者類的訪問。這樣做的好處在於可以

將系統功能與業務邏輯鬆散耦合,並且實現簡單,結構清晰,三兩個advisor、filter,或者acegi就能搞定,但在

web程式中體現出了他的劣勢,當我們將使用者的訪問拒絕在業務邏輯之外的時候,我們此時是否應該丟擲異常提示用

戶?一旦提示使用者沒有相應的許可權,我認為對於使用者來說,這就不是一個perfect practice。由此得出,我們根本

就不應該讓使用者做此次操作,而控制使用者操作的源頭就是介面,也就是說,在介面上我們就應該對使用者的許可權元素(

如新增按鈕、功能選單等)進行控制。此時,一對矛盾出現了,要控制介面上形形色色的元素只有兩種辦法,一,將

許可權與你的介面結合起來設計,這將違背AOP的思想,也使得系統控制模組的重用性大大下降,二,我們借鑑

primeton的想法,將許可權控制的理念抽取出來,單獨做成一套許可權系統,解決你所有的需要許可權控制的系統需求,

這樣也有令人頭痛的問題,你的所有想用它來控制權限的系統,必須介面上統一風格。或許這樣的方式對商業web系

統是合適的,畢竟需要你大刀闊斧個性化的地方不多,但我們卻很難保證在未來幾年內商業web系統的風格不改變。

再者,開發這麼一個系統也不是一蹴而就的事,在這個問題上一直讓我困惑不已。


疑惑二:大多應用的許可權判定是基於許可權字串的,但儲存在資料庫中的許可權字串能夠判定的許可權並不多,在我

們這次專案中,我引用了基於二進位制的8421許可權判定法則,我深深的感覺到許可權字串的弱勢,這使我想起了中國

古老一套數學理論-“盈不足術”,超遞增序列的魅力在我眼前滑過,

首先我來解釋一下盈餘不足理論:有十隻盒子,第一個盒子裡放一個盤子,第二個盒子裡放兩隻,第三個盒子裡放

四隻,第四個盒子裡放八隻……第九個盒子裡放256只,第十個盒子放512只,即第N只箱子裡放2^(N-1)只盤子,一

共1023只。那麼命題如下:在1023這個數字之內,任何一個數目都可以由這十隻盒子裡的幾隻組合相加而成。那麼1

、2、4、8、16、32、64、128、256、512這個序列為什麼有這麼個魔力?這個數列的特點:1、每項是後一項的二倍

,2、每項都比前面所有項的和大,而且大1。這個1就是關鍵,就因為這個1,它才可以按1遞增,拼出總和之內任意

一個整數。這個序列叫做超遞增序列,它是解決揹包問題的基礎。3、拼出總和之內任意一個整數可以由這個序列中

的一些數構成,且構成方法唯一,據說是密碼學中的NP定理。譬如說這個數列總合中20這個數,只能由16+4一種方

法構成,由此延伸出來,如果綜合中這個資料代表一個權值,我們可以解出它的所有構成引數(操作),如20這個

資料,我們可以挨個和序列中每一項按位與,得出來如果不等於0,就說明他是由這個數構成的。

儲存權值到int還是varchar對於我們來說是個問題,當然,儲存字串的好處是運算壓力小。我們可能聽過一個故

事,就是把這個超遞增序列延伸到第64項,就是那個術士和皇帝在國際象棋棋盤上要米粒的傳說。64項的和是一個

天文數字!但計算機本身就是一個只認識二進位制的機器!很多程式設計師整天只關心架構,甚至不知道或者不關心位操

作是什麼玩意,當然我們有朋友擔心資料庫的int不夠長,那麼既然可以儲存一個只有0、1組成的varchar字串,

為什麼不能儲存一個十六進位制的字串,有人規定varchar只能儲存01嗎?十六進位制串的長度正好是二進位制的四分之

一。

由此我們可以無限制的擴充套件權值操作。

在最近的專案裡,我對許可權的控制分成兩個部分,第一就是使用者體驗上,我設定了一個許可權標籤,從資料庫中抽取

許可權資訊,然後做到標籤裡,也湊或算成是介面AOP了,第二就是底層的攔截,用了Spring 的AOP,為的是防止許可權

衝突,雙管齊下。暫時解決許可權所需,另外在演算法上我用了16進位制的許可權判別程式碼,雖然配置較麻煩,寫完程式碼還

要寫文件說明,不過也解決了許可權繁雜又多的問題,暫時就這樣了,嘿嘿,以後有空再研究。

_________________________________________________
 首先上文許可權設計拙見(1)中只是想記錄下自己許可權設計上的一點看法,以及將自己日常最常用的許可權解決方案記

錄下來以供日後回顧,沒想到有朋友關注此類的設計,那就只能先把程式碼拿出來獻醜了,拋磚引玉,大家共同探討

學習
      接著上文來說,上文所討論的許可權設計是一條思路,但既然是web應用,少不了資料庫的支援,本文我們來討

論一下資料庫的設計。(以下想法及思路僅僅代表本人拙見)
      說到許可權的資料庫設計,必先理清許可權中幾種實體及其關係,此部分想必有過設計許可權經驗的同仁都知道怎

麼設計了,網上擺渡一下也是一褲衩子一褲衩子的,我們就在最平凡直觀的資料庫關係的基礎上來建立許可權。下面

是我的幾個表(所有的表都帶有一個pk_id,作為表的自動生成的唯一主鍵):
使用者表(T_UserInfo):
 1/**//*==============================================================*/
 2/**//* Table: T_UserInfo                                            */
 3/**//*==============================================================*/
 4create table T_UserInfo 
 5(
 6    pk_id                NUMBER                         not null,
 7    name                 VARCHAR2(20),
 8    sex                  BOOLEAN,
 9    age                  int,
10    emp_num              NUMBER,
11    polity               int,
12    unit                 VARCHAR2(50),
13    department           VARCHAR2(20),
14    specialty            int,
15    position             VARCHAR2(10),
16    offtel               VARCHAR2(20),
17    famtel               VARCHAR2(20),
18    post_state           VARCHAR2(10),
19    remark               VARCHAR2(100),
20    constraint PK_T_USERINFO primary key (pk_id)
21);使用者表就不多說了,都是一些常用欄位,年齡、電話、職位等,建議大家建立一個通用一些,欄位多一些的一

個使用者表,便於以後擴充套件,以後如果有特殊需求,不用擴這個基本表,可以通過主外來鍵關係來新建一個表,用於擴

充欄位
角色表(T_RoleInfo):
 1/**//*==============================================================*/
 2/**//* Table: T_RoleInfo                                            */
 3/**//*==============================================================*/
 4create table T_RoleInfo 
 5(
 6    pk_id                number                         not null,
 7    role_name            VARCHAR2(20),
 8    role_desc            VARCHAR2(100),
 9    parent_role_id       NUMBER,
10    constraint PK_T_ROLEINFO primary key (pk_id)
11);角色表中需要說明的就一個parent_role_id父角色id,此欄位用來擴充套件角色的繼承關係。
資源表(T_ResourceInfo):
 1/**//*==============================================================*/
 2/**//* Table: T_ResourceInfo                                        */
 3/**//*==============================================================*/
 4create table T_ResourceInfo 
 5(
 6    pk_id                NUMBER                         not null,
 7    module_name          VARCHAR2(20),
 8    module_code          VARCHAR2(10),
 9    module_desc          VARCHAR2(100),
10    privilege_name       VARCHAR2(10),
11    privilege_code       CHAR,
12    privilege_desc       VARCHAR2(100),
13    constraint PK_T_RESOURCEINFO primary key (pk_id)
14);
15這個表需要說明的就比較多了,首先該表用來記錄資源與資源許可權,我這邊所謂的資源就是實體,就是資料庫表

,角色需要對應到資源,有些角色對該資源有許可權,有些角色則對該資源無許可權,角色可對此資源操作的許可權也不

同。說白了,就是不同的角色對不同的資料庫表的操作許可權不同。因此我們這裡的資源就是資料庫表。
module_name:資源名;module_code:資原始碼(存放資料庫表名);
privilege_name:許可權名;privilege_code:許可權程式碼(代表權限的code,也就是我們上文所說的權值)
例如角色a對資料庫表T_UserInfo有新增與刪除的許可權則該表應該按照如下配置:
module_name:人員資訊;
module_code:T_UserInfo
privilege_name:新增與刪除
privilege_code:6
這裡我們假設的是2的0次方為新增許可權,2的1次方為新增許可權,2的2次方為刪除許可權,2的3次方為更新許可權,則擁

有新增與刪除許可權就應該為2的1次方+2的2次方=6,其實2的幾次方代表什麼含義我們可以另外開個資料庫表來配置

(或者xml檔案)此處我們忽略這些步驟。當然如果你的許可權較多,譬如你還希望a這個角色對人員資訊表有上傳得

許可權,我們可以將將上傳許可權定義為2的4次方,16,16的16進位制數為10,記錄在資料庫裡的形式應該為0x10如果a角

色擁有新增、刪除、更新、上傳許可權,則a的權值應該為2的1次方+2的2次方+2的3次方+2的4次方=30,用16進位制來表

示就應該為0x1E,記錄16進位制資料,你不用擔心位數不夠。
剩餘的就是幾張關係表了:
人員角色關係表(T_R_User_Role):
 1/**//*==============================================================*/
 2/**//* Table: T_R_user_role                                         */
 3/**//*==============================================================*/
 4create table T_R_user_role 
 5(
 6    pk_id                NUMBER                         not null,
 7    user_id              NUMBER,
 8    role_id              NUMBER,
 9    constraint PK_T_R_USER_ROLE primary key (pk_id)
10);
11角色資源關係表(T_R_Role_Resource)
 1/**//*==============================================================*/
 2/**//* Table: T_R_role_resource                                     */
 3/**//*==============================================================*/
 4create table T_R_role_resource 
 5(
 6    pk_id                NUMBER                         not null,
 7    role_id              NUMBER,
 8    res_id               NUMBER,
 9    constraint PK_T_R_ROLE_RESOURCE primary key (pk_id)
10);
11當然如果你不怕麻煩,可以新增進去組(group)、系統(system)、組織(organization),建立起一套屬於你自己的

完整的許可權解決方案,作為系統無關的模組去套用到每個你所架構的應用中去,那是一件極爽的事情。
連續劇開始了,暫時擱筆~~


__________________________________________________________________________
在上文中我們提到了一個資源對應一個數據庫表,在T_ResourceInfo表中我們也提到了有一個欄位專門來記錄表名

,然後我書寫一個資源配置檔案,用來配置我的業務類與資源的對應關係,程式碼如下:
1<?xml version="1.0" encoding="GB2312"?>
2<data>
3    <mapping SysName="s">
4        <module BusinessClass="com.ideal.framework.business.businessface.IBLogin"

TableName="user_info"/>
5    </mapping>
6</data>其中BusinessClass代表業務介面,TableName代表該業務介面所要操作的資料實體(資料表),此處的

TableName必須與T_ResourceInfo中的Module_Code一致。
使用者登入後,需要操作T_UserInfo這個表時,我們的邏輯將會把請求帶入IBLogin這個業務邏輯中,在我們的AOP模

塊中,可以用MethodInterceptor來截獲當前使用者想要操作的業務邏輯,當AOP模組截獲了使用者的請求,並判斷使用者

想要操作IBLogin這個業務邏輯,它將在上述的mapping檔案中去找該業務邏輯對應的資源user_info,然後去資源表

中判斷該使用者是否有操作user_info的許可權。
(注:上述xml檔案在系統初始化時候載入入記憶體中,我們也可以將許可權資訊也載入在記憶體中,不會很大,一切資源

在記憶體中操作,非常快)
下面我貼點程式碼,在系統初始化時:
 1package com.ideal.framework;
 2
 3import java.util.*;
 4import java.sql.*;
 5import com.ideal.framework.dao.daoface.*;
 6import com.ideal.framework.po.*;
 7
 8public class ResourceContainer
 9{
10    public static boolean change_resource; //更新資源  系統持久
11    public static Vector resource_container = new Vector(); //資源容器  使用者持久
12    private IUserRoleDAO m_user_role_dao;
13    private IRoleResourceDAO m_role_resource_dao;
14    private IUserDAO m_user_dao;
15
16    public ResourceContainer()
17{
18    }
19
20    public void setUserResource()
21    {
22        System.out.println("initialize resource:");
23        List user_list = m_user_dao.getAllUser();
24        for (int i = 0; i < user_list.size(); i++)
25        {
26            UserInfo user = (UserInfo) user_list.get(i);
27            List role_list = m_user_role_dao.getRoleInfo(user);
28            for (int j = 0; j < role_list.size(); j++)
29            {
30                RoleInfo role = (RoleInfo) role_list.get(j);
31                List resource_list = m_role_resource_dao.
32                    getResourceInfo(role);
33                for (int k = 0; k < resource_list.size(); k++)
34                {
35                    Hashtable hash = new Hashtable();
36                    hash.put(user.getLoginId(), resource_list.get(k));
37                    hash.put("Unit_"+user.getLoginId(), user.getUnit());
38                    hash.put("Role_"+user.getLoginId(), role.getRoleName());
39                    ResourceContainer.resource_container.add(hash);
40                }
41            }
42        }
43    }
44
45    public Vector getResource_container()
46    {
47        return resource_container;
48    }
49
50    public void setResource_container(Vector resource_container)
51    {
52        this.resource_container = resource_container;
53    }
54
55    public IRoleResourceDAO getM_role_resource_dao()
56    {
57        return m_role_resource_dao;
58    }
59
60    public IUserDAO getM_user_dao()
61    {
62        return m_user_dao;
63    }
64
65    public IUserRoleDAO getM_user_role_dao()
66    {
67        return m_user_role_dao;
68    }
69
70    public void setM_role_resource_dao(IRoleResourceDAO m_role_resource_dao)
71    {
72        this.m_role_resource_dao = m_role_resource_dao;
73    }
74
75    public void setM_user_dao(IUserDAO m_user_dao)
76    {
77        this.m_user_dao = m_user_dao;
78    }
79
80    public void setM_user_role_dao(IUserRoleDAO m_user_role_dao)
81    {
82        this.m_user_role_dao = m_user_role_dao;
83    }
84
85    public void setChange_resource(boolean change_resource)
86    {
87        this.change_resource = change_resource;
88    }
89
90    public boolean isChange_resource()
91    {
92        return change_resource;
93    }
94}
95將使用者對應的角色,資源資訊載入如記憶體,另外在初始化時候的xml檔案的樹形結構也載入入記憶體,這邊就不貼代

碼了
下面是AOP模組的advice程式碼:
package com.ideal.framework.sys.advice;

/** *//**
 * <p>Title: BusinessAccessAdvisor</p>
 * <p>Description: 業務模組AOP許可權監聽器</p>
 * <p>Copyright: Copyright (c) 2006</p>
 * <p>Company: ideal</p>
 * @author alex
 * @version 1.0
 */

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import com.ideal.framework.InitResource;
import com.ideal.framework.util.XMLUtil;
import java.util.ArrayList;
import java.util.Hashtable;
import com.ideal.framework.sys.accesscontrol.GenericAccessBase;
import java.lang.reflect.Field;
import com.ideal.framework.po.*;
import java.lang.reflect.Method;
import java.util.*;
import java.io.*;
import javax.servlet.http.HttpServletRequest;

public class BusinessAccessAdvisor
    implements MethodInterceptor
{

    public BusinessAccessAdvisor()
    {
    }

    public Object invoke(MethodInvocation invocation) throws
        Throwable
    {
        String user_name = "";
        Object obj = invocation.getArguments()[1];
        if (obj instanceof HttpServletRequest)
    {
            HttpServletRequest request = (HttpServletRequest)obj;
            user_name = (String)request.getSession().getAttribute("UserName");//取出使用者名稱
        }
        String bean_name = invocation.getMethod().getDeclaringClass().getName();//取出使用者想要操作的

業務邏輯
        XMLUtil xml = (XMLUtil) InitResource.context.getBean("XMLUtil");
        ArrayList list = xml.getFieldList("mapping", "s", xml.doc);
        for (int i = 0; i < list.size(); i++)
    {
            Hashtable hash = (Hashtable) list.get(i);
            if (hash.get("BusinessClass").equals(invocation.getMethod().//判斷使用者是否有權操作該業務

邏輯所對應表
                                                 getDeclaringClass().getName()))
        {
                String table_name = (String) hash.get("TableName");
                GenericAccessBase access_controller = (GenericAccessBase)
                    InitResource.context.getBean("GenericAccessBase");
                if (access_controller.CheckAccessPrivilege(user_name, table_name))//若使用者有權操作該

表,則讓程式進入業務邏輯
            {
                    return invocation.proceed();
                }
            }
        }
        System.out.println("no permission .reject by " + bean_name);
        return null;
    }
}
下面是判斷使用者是否具有操作該表許可權的類:
 1package com.ideal.framework.sys.accesscontrol;
 2
 3import com.ideal.framework.InitResource;
 4import com.ideal.framework.util.XMLUtil;
 5import com.ideal.framework.po.UserInfo;
 6import com.ideal.framework.ResourceContainer;
 7import java.util.*;
 8//import com.ideal.framework.po.ResourceInfo;
 9
10public class GenericAccessBase
11{
12    UserInfo user;
13
14    public GenericAccessBase()
15    {
16    }
17
18    public void setUser(UserInfo user)
19    {
20        this.user = user;
21    }
22
23    public boolean CheckAccessPrivilege(String user_name, String table_name)
24    {
25        for (int i = 0; i < ResourceContainer.resource_container.size(); i++)
26        {
27            Hashtable temp_hash = (Hashtable)ResourceContainer.resource_container.get(i);//從記憶體中

取出使用者資源資訊
28            if (temp_hash.containsKey(user_name))
29            {
30                ResourceInfo resource = (ResourceInfo)temp_hash.get(user_name);
31                if (table_name.trim().toLowerCase().equals(resource.getModuleCode().trim

().toLowerCase()))//比對使用者擁有的資源和當前的table_name
32                {
33                    return true;
34                }
35            }
36        }
37        return false;
38    }
39}
40ok,到此為止,我們的底層攔截就完成了,接下來就是介面許可權處理,介面許可權比較複雜,因為使用者可能具有添

加許可權,沒有上傳許可權,有下載許可權卻沒有更新許可權等,情況很複雜,所以我們這邊必須有一個判斷當前使用者是否

具有這些複雜許可權的類:
  1package com.ideal.framework.sys.privilege;
  2
  3/** *//**
  4 * <p>Title: GenericPrivilegeBase</p>
  5 * <p>Description: 通用許可權法則</p>
  6 * <p>Copyright: Copyright (c) 2006</p>
  7 * <p>Company: ideal</p>
  8 * @author alex
  9 * @version 1.0
 10 */
 11
 12public class GenericPrivilegeBase
 13{
 14    public final static int NO_PRIVILEGE = 0;
 15    public final static int QUERY_OR_USE_PRIVILEGE = 1;//察看許可權
 16    public final static int CREATE_PRIVILEGE = 2;//新增許可權
 17    public final static int DELETE_PRIVILEGE = 4;//刪除許可權
 18    public final static int UPDATE_PRIVILEGE = 8;//更新許可權
 19    public final static int ALL_PRIVILEGE = QUERY_OR_USE_PRIVILEGE |
 20        CREATE_PRIVILEGE | DELETE_PRIVILEGE | UPDATE_PRIVILEGE;//增刪改查許可權
 21
 22    public GenericPrivilegeBase()
 23    {
 24    }
 25
 26    public static boolean isValidPrivilege(int privilege)//判斷是否具有許可權
 27    {
 28        if ( (privilege & QUERY_OR_USE_PRIVILEGE) != 0)
 29        {
 30            return true;
 31        }
 32
 33        if ( (privilege & CREATE_PRIVILEGE) != 0)
 34        {
 35            return true;
 36        }
 37
 38        if ( (privilege & DELETE_PRIVILEGE) != 0)
 39        {
 40            return true;
 41        }
 42
 43        if ( (privilege & UPDATE_PRIVILEGE) != 0)
 44        {
 45            return true;
 46        }
 47
 48        return false;
 49    }
 50
 51    public static boolean checkQueryPrivilege(int privilege)//判斷是否具有察看許可權
 52    {
 53        if ( (privilege & QUERY_OR_USE_PRIVILEGE) != 0)
 54        {
 55            return true;
 56        }
 57        else
 58        {
 59            return false;
 60        }
 61    }
 62
 63    public static boolean checkUsePrivilege(int privilege)
 64    {
 65        if ( (privilege & QUERY_OR_USE_PRIVILEGE) != 0)
 66        {
 67            return true;
 68        }
 69        else
 70        {
 71            return false;
 72        }
 73    }
 74
 75    public static boolean checkCreatePrivilege(int privilege)//判斷是否有新增許可權
 76    {
 77        if ( (privilege & CREATE_PRIVILEGE) != 0)
 78        {
 79            return true;
 80        }
 81        else
 82        {
 83            return false;
 84        }
 85    }
 86
 87    public static boolean checkDeletePrivilege(int privilege)//判斷是否有刪除許可權
 88    {
 89        if ( (privilege & DELETE_PRIVILEGE) != 0)
 90        {
 91            return true;
 92        }
 93        else
 94        {
 95            return false;
 96        }
 97    }
 98
 99    public static boolean checkUpdatePrivilege(int privilege)
100    {
101        if ( (privilege & UPDATE_PRIVILEGE) != 0)
102        {
103            return true;
104        }
105        else
106        {
107            return false;
108        }
109    }
110}
111然後我們自定義兩個標籤,Privilege與noPrivilege用來判斷使用者是否具有許可權,這兩個標籤必須具有三個基本

的attribute,beanName:當前所要操作的哪個資源;scope:使用者資訊存放在哪個域;operation:使用者想要進行什

麼操作
貼一個privilege標籤的程式碼:
  1package com.ideal.framework.tag;
  2
  3import javax.servlet.jsp.tagext.BodyTagSupport;
  4import javax.servlet.jsp.tagext.*;
  5import javax.servlet.http.*;
  6import javax.servlet.jsp.*;
  7import java.sql.*;
  8import java.io.*;
  9import com.ideal.framework.*;
 10import com.ideal.framework.po.ResourceInfo;
 11import java.util.Hashtable;
 12import com.ideal.framework.sys.privilege.GenericPrivilegeBase;
 13
 14public class PrivilegeTag
 15    extends BodyTagSupport
 16{
 17    String operation;
 18    private String beanName;
 19    private String scope;
 20
 21    public PrivilegeTag()
 22    {
 23        super();
 24    }
 25
 26    public void setOperation(String operation)
 27    {
 28        this.operation = operation;
 29    }
 30
 31    public void setBeanName(String beanName)
 32    {
 33        this.beanName = beanName;
 34    }
 35
 36    public void setScope(String scope)
 37    {
 38        this.scope = scope;
 39    }
 40
 41    public int doStartTag() throws JspTagException
 42    {
 43        if (scope == null || scope.equals(""))
 44            return SKIP_BODY;
 45        else
 46        {
 47            String user_name = "";
 48            if (scope.equalsIgnoreCase("session"))
 49            {
 50                HttpSession session = pageContext.getSession();
 51                user_name = (String) session.getAttribute("UserName");
 52            }
 53            else
 54            {
 55                HttpServletRequest request = (HttpServletRequest) pageContext.
 56                    getRequest();
 57                user_name = (String) request.getAttribute("UserName");
 58            }
 59
 60            for (int i = 0; i < ResourceContainer.resource_container.size(); i++)
 61            {
 62                Hashtable temp_hash = (Hashtable) ResourceContainer.
 63                    resource_container.get(i);
 64                if (temp_hash.containsKey(user_name))
 65                {
 66                    ResourceInfo resource = (ResourceInfo) temp_hash.get(
 67                        user_name);
 68                    if (beanName.trim().toLowerCase().equals(resource.
 69                        getModuleCode().trim().toLowerCase()))
 70                    {
 71                        if(this.checkPrivilege(resource.getPrivilegeCode()) == EVAL_BODY_TAG)
 72                            return EVAL_BODY_TAG;
 73                    }
 74                }
 75            }
 76
 77        }
 78        return SKIP_BODY;
 79return EVAL_BODY_TAG;
 80    }
 81
 82    public int checkPrivilege(String privilege)
 83    {
 84        int int_privilege = 0;
 85        try
 86        {
 87            int_privilege = Integer.parseInt(privilege);
 88        }
 89        catch (NumberFormatException ex)
 90        {
 91            System.out.println(ex.getMessage());
 92        }
 93        GenericPrivilegeBase gpb = new GenericPrivilegeBase();
 94        if (operation.equals("NONE"))
 95            return EVAL_BODY_TAG;
 96        if (operation.equals("QUERY"))
 97            if (gpb.checkQueryPrivilege(int_privilege))
 98                return EVAL_BODY_TAG;
 99        if (operation.equals("CREATE"))
100            if (gpb.checkCreatePrivilege(int_privilege))
101                return EVAL_BODY_TAG;
102        if (operation.equals("DELETE"))
103            if (gpb.checkDeletePrivilege(int_privilege))
104                return EVAL_BODY_TAG;
105        if (operation.equals("UPDATE"))
106            if (gpb.checkUpdatePrivilege(int_privilege))
107                return EVAL_BODY_TAG;
108        if (operation.equals("USE"))
109            if (gpb.checkUsePrivilege(int_privilege))
110                return EVAL_BODY_TAG;
111        return SKIP_BODY;
112    }
113
114    public int doAfterBody() throws JspTagException
115    {
116        return SKIP_BODY;
117    }
118
119    public int doEndTag() throws JspTagException
120    {
121        try
122        {
123            if (bodyContent != null)
124            {
125                bodyContent.writeOut(bodyContent.getEnclosingWriter());
126            }
127        }
128        catch (IOException ex)
129        {
130            throw new JspTagException("IO Error:" + ex.getMessage());
131        }
132        return EVAL_PAGE;
133    }
134
135    public void doInitBody() throws JspTagException
136    {
137    }
138
139    public void setBodyContent(BodyContent bodyContent)
140    {
141        this.bodyContent = bodyContent;
142    }
143}
144在頁面上,我們如此使用該標籤:
1<privilege beanName="user_info" scope="session" operation="create">
2    <input type="button" value="新增">
3</privilege>
如此,系統會自動根據當前session中的使用者來判斷是否需要顯示當前的新增按鈕。
到此所有許可權的程式碼完成,在此套許可權設計中,我始終抱著AOP的想法:讓他屬於一個系統切面,以後再開發其他系

統時,作為一個模組就可以載入上去,與系統無關

相關推薦

開源jsp許可權管理實現程式碼

事情挺讓我頭痛的,記得一年前在瀋陽,我曾經有一段時間也因因這個問題而疲於奔命,為什麼說疲於奔命呢?由 於當時專案進度不允許,導致最終系統許可權模組草草了事,每個模組都是由讀許可權字串來控制使用者ACL,當用戶無 法訪問時,提示許可權不夠。這麼做對使用者是很不負責任的,既然讓使用者看到了操作的方式和介面,為什

Shiro 整合SpringMVC 並且實現許可權管理登入和登出

Apache Shiro是Java的一個安全框架。目前,使用Apache Shiro的人越來越多,因為它相當簡單,對比Spring Security,可能沒有Spring Security做的功能強大,但是在實際工作時可能並不需要那麼複雜的東西,所以使用小而簡單

Jenkins+maven+git 實現自動構建、許可權管理、靜態程式碼檢測、遠端部署、傳送郵件功能

Jenkins配置 1. 使用者許可權設定 配置->Configure Global Security (注:想讓匿名使用者可以瀏覽jenkins網站 需勾選Overall 中的read 和 Job

Django實戰1-許可權管理功能實現-01:搭建開發環境

1 專案開發環境 語言環境: python3.6.2 , django-2.1.2 資料庫環境:sqlite3(開發環境使用,部署環境使用mysql5.6) 開發工具:pycharm 2 安裝python 說明:已經安裝過python3.6環境的可以跳過此步。python安裝包下載地址

利用svn鉤子hooks/post-commit實現程式碼更新自動執行指令碼

1. 在svn伺服器對應的專案中會存在以下幾個目錄和檔案 conf  db  format  hooks  locks  README.txt 其中目錄hooks是放置程式碼提交執行的檔案 進入 hooks目錄新建一個 post-comm

許可權管理資料備份、pymysql模組

許可權管理 許可權管理重點 MySQL 預設有個root使用者,但是這個使用者許可權太大,一般只在管理資料庫時候才用。如果在專案中要連線 MySQL 資料庫,則建議新建一個許可權較小的使用者來連線。 在 MySQL 命令列模式下輸入如下命令可以為 MySQL 建立一個新使用者:

功能許可權和資料許可權管理實現

1      引言 許可權,可分為“功能(操作)許可權”和資料許可權兩種,在系統中,兩種許可權應當同時有效。例如,在windows系

RBAC許可權管理系統實現思路(一)

RBAC(Role-Based Access Contro) 是基於角色的許可權訪問控制,系統根據登入使用者的角色不同,從而給予不同的系統訪問許可權,角色的許可權隨角色創立時進行分配。 首先,許可權控制很多系統中都需要,但是不同的系統對於許可權的敏感程度不同,

一個完整的簡單jsp+servlet例項實現簡單的登入

開發環境myeclipse+tomcat8 1、先建立web project,專案名為RegisterSystem, 2、在WebRoot 目錄下建立login.jsp檔案: <%@

許可權管理系統實現思路(SpringCloud+Thymeleaf)(二)

許可權分配    下面主要來說說Thymeleaf模板使用和許可權分配的實現思路。    先看效果圖:    實現該功能的思路是:傳往前端的資料為Map,該Map以columnName(許可權分欄名)為key,以該分欄下的所有許可權為value。因為要回顯許

Unity程式設計技巧:使用巨集定義程式碼更整潔實現程式碼和渠道SDK解耦等

筆者從一年前開始做VR開發,移動端PC端的應用都有,因為當前VR市場還很混亂,並且硬體標準太多單我使用過作開發的VR裝置就有5、6種之多,更別說只是用過聽過的裝置,並且每一家的API都不一樣,這也增加了發不同的渠道包的工作量。這裡我將就我使用的只用解決方案

許可權管理(資料庫程式碼編寫)

--許可權表(選單表) create table Premisson_Func (     Id int primary key identity(1,1),     Name nvarchar(128), ---選單名     url nvarchar(216), ---

android6.0動態許可權管理小米bug適配

在Android6.0以後開始,對於部分敏感的“危險”許可權,需要在應用執行時向用戶申請,只有使用者允許的情況下這個許可權才會被授予給應用。這對於使用者來說,無疑是一個提升安全性的做法。那麼對於開發者,應該怎麼做呢? Android6.0規定的危險許可權有下面

【無私分享:從入門到精通ASP.NET MVC】從0開始一起搭框架、做專案(8) 許可權管理自定義許可權擴充套件許可權

索引 簡述 今天我們來做許可權的管理,這篇比較多 希望新手朋友慢慢消化 專案準備 我們用的工具是:VS 2013 + SqlServer 2012 + IIS7.5 希望大家對ASP.NET MVC有一個初步的理解,理論性的東西我們不做過多解釋,有些地方不理解也沒關係,會用就行了,用的多了,用的

PHPStorm 配置遠端伺服器資料夾在本地windows映象實現程式碼自動同步(類似於Samba架構檔案同步功能)

場景介紹:這是一種類似samba架構,也和 filezilla+xshell 模式相類似的程式碼檔案同步的模式,但是卻更加優雅,也更加方便簡潔。環境介紹:本地windows端:編輯器phpstorm遠端Linux端:centos(香港節點伺服器)LNMP一、實現檔案同步1、在

SSM環境shiro跨域AJAX許可權管理資料請求

首先,專案環境是用: Java後端:Myeclipse10 後端採用框架:ssm,沒有用到mevan管理jar包 實行前後分離開發模式,通過api介面向前端傳遞資料 web前端:HTML5 首先跨域問題,重寫過濾器Filter的doFilter()方法    @Overri

關於Android 6.x 及以上許可權管理閃退

原因1. 沒有授權檢查; 原因2. 許可權檢查與宣告不匹配  例如: 近期,維護一個接手的App,由於歷史原因,沒有許可權管理,直接導致在高版本的Android上閃退。 直接匯入了以前專案使用的以下程式碼 public static String[] check

SAP許可權管理我的理解

本人2001年至今一直從事basis工作,曾經是erphome-basis版主之一,管理過多個500人以上的sap系統N年,創有BASIS終極授權の內部顧問引數檔案的產生 https://github.com/basis100/SAPauthor我經歷的多個ERP系統中,

SVN版本管理提交程式碼規範

專案開發要求: 1、工作目錄要及時更新,不要和SVN伺服器有太大的差別 2、提交程式碼時,如果出現衝突,必須仔細分析解決,不可以強行提交 3、提交程式碼之前先在本地進行測試,確保專案能編譯通過,且能夠正常執行,不可盲目提交 4、必須保證SVN上的版本是正確的,專案有錯誤時,不要進行提交 SVN注意事項,請

CAS4.0+禪道開源版11.2實現禪道的單點登入

本文在 夜風飄塵的部落格 基礎上進行修改。所以cas的客戶端和服務端就不做詳解了,