在上文中我們提到了一個資源對應一個數據庫表,在T_ResourceInfo表中我們也提到了有一個字段專門來記錄表名,然后我書寫一個資源配置文件,用來配置我的業務類與資源的對應關系,代碼如下:
用戶登錄后,需要操作T_UserInfo這個表時,我們的邏輯將會把請求帶入IBLogin這個業務邏輯中,在我們的AOP模塊中,可以用MethodInterceptor來截獲當前用戶想要操作的業務邏輯,當AOP模塊截獲了用戶的請求,并判斷用戶想要操作IBLogin這個業務邏輯,它將在上述的mapping文件中去找該業務邏輯對應的資源user_info,然后去資源表中判斷該用戶是否有操作user_info的權限。
(注:上述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;
????}
}
下面是判斷用戶是否具有操作該表權限的類:
貼一個privilege標簽的代碼:
如此,系統會自動根據當前session中的用戶來判斷是否需要顯示當前的添加按鈕。
到此所有權限的代碼完成,在此套權限設計中,我始終抱著AOP的想法:讓他屬于一個系統切面,以后再開發其他系統時,作為一個模塊就可以加載上去,與系統無關
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一致。
2

3

4

5

6

用戶登錄后,需要操作T_UserInfo這個表時,我們的邏輯將會把請求帶入IBLogin這個業務邏輯中,在我們的AOP模塊中,可以用MethodInterceptor來截獲當前用戶想要操作的業務邏輯,當AOP模塊截獲了用戶的請求,并判斷用戶想要操作IBLogin這個業務邏輯,它將在上述的mapping文件中去找該業務邏輯對應的資源user_info,然后去資源表中判斷該用戶是否有操作user_info的權限。
(注:上述xml文件在系統初始化時候加載入內存中,我們也可以將權限信息也加載在內存中,不會很大,一切資源在內存中操作,非常快)
下面我貼點代碼,在系統初始化時:
?1
package?com.ideal.framework;
?2
?3
import?java.util.*;
?4
import?java.sql.*;
?5
import?com.ideal.framework.dao.daoface.*;
?6
import?com.ideal.framework.po.*;
?7
?8
public?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文件的樹形結構也加載入內存,這邊就不貼代碼了
?2

?3

?4

?5

?6

?7

?8

?9


10

11

12

13

14

15

16

17


18

19

20

21


22

23

24

25


26

27

28

29


30

31

32

33

34


35

36

37

38

39

40

41

42

43

44

45

46


47

48

49

50

51


52

53

54

55

56


57

58

59

60

61


62

63

64

65

66


67

68

69

70

71


72

73

74

75

76


77

78

79

80

81


82

83

84

85

86


87

88

89

90

91


92

93

94

95

下面是AOP模塊的advice代碼:










































































?1
package?com.ideal.framework.sys.accesscontrol;
?2
?3
import?com.ideal.framework.InitResource;
?4
import?com.ideal.framework.util.XMLUtil;
?5
import?com.ideal.framework.po.UserInfo;
?6
import?com.ideal.framework.ResourceContainer;
?7
import?java.util.*;
?8
//import?com.ideal.framework.po.ResourceInfo;
?9
10
public?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
}
40
ok,到此為止,我們的底層攔截就完成了,接下來就是界面權限處理,界面權限比較復雜,因為用戶可能具有添加權限,沒有上傳權限,有下載權限卻沒有更新權限等,情況很復雜,所以我們這邊必須有一個判斷當前用戶是否具有這些復雜權限的類:
?2

?3

?4

?5

?6

?7

?8

?9

10

11


12

13

14

15


16

17

18

19


20

21

22

23

24


25

26


27

28

29


30

31

32


33

34

35

36

37

38

39

40

??1
package?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
?12
public?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:用戶想要進行什么操作
??2

??3


??4

??5

??6

??7

??8

??9

?10

?11

?12

?13



?14

?15

?16

?17

?18

?19

?20

?21

?22

?23



?24

?25

?26

?27



?28

?29



?30

?31

?32

?33

?34



?35

?36

?37

?38

?39



?40

?41

?42

?43

?44



?45

?46

?47

?48

?49

?50

?51

?52



?53

?54



?55

?56

?57

?58



?59

?60

?61

?62

?63

?64



?65

?66



?67

?68

?69

?70



?71

?72

?73

?74

?75

?76



?77

?78



?79

?80

?81

?82



?83

?84

?85

?86

?87

?88



?89

?90



?91

?92

?93

?94



?95

?96

?97

?98

?99

100



101

102



103

104

105

106



107

108

109

110

111

貼一個privilege標簽的代碼:
??1
package?com.ideal.framework.tag;
??2
??3
import?javax.servlet.jsp.tagext.BodyTagSupport;
??4
import?javax.servlet.jsp.tagext.*;
??5
import?javax.servlet.http.*;
??6
import?javax.servlet.jsp.*;
??7
import?java.sql.*;
??8
import?java.io.*;
??9
import?com.ideal.framework.*;
?10
import?com.ideal.framework.po.ResourceInfo;
?11
import?java.util.Hashtable;
?12
import?com.ideal.framework.sys.privilege.GenericPrivilegeBase;
?13
?14
public?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;
?79
return?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
在頁面上,我們如此使用該標簽:
??2

??3

??4

??5

??6

??7

??8

??9

?10

?11

?12

?13

?14

?15

?16



?17

?18

?19

?20

?21

?22



?23

?24

?25

?26

?27



?28

?29

?30

?31

?32



?33

?34

?35

?36

?37



?38

?39

?40

?41

?42



?43

?44

?45

?46



?47

?48

?49



?50

?51

?52

?53

?54



?55

?56

?57

?58

?59

?60

?61



?62

?63

?64

?65



?66

?67

?68

?69

?70



?71

?72

?73

?74

?75

?76

?77

?78

?79

?80

?81

?82

?83



?84

?85

?86



?87

?88

?89

?90



?91

?92

?93

?94

?95

?96

?97

?98

?99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115



116

117

118

119

120



121

122



123

124



125

126

127

128

129



130

131

132

133

134

135

136



137

138

139

140



141

142

143

144

1
<privilege?beanName="user_info"?scope="session"?operation="create">
2
????<input?type="button"?value="添加">
3
</privilege>

2

3

如此,系統會自動根據當前session中的用戶來判斷是否需要顯示當前的添加按鈕。
到此所有權限的代碼完成,在此套權限設計中,我始終抱著AOP的想法:讓他屬于一個系統切面,以后再開發其他系統時,作為一個模塊就可以加載上去,與系統無關