① java許可權設計
一、概要
通常,需要單獨的許可權系統是解決授權的管理和維護,再分配等難題,不針對開發而言。
系統架構目標:在易於理解和管理,開發的前提下,滿足絕大部分粗粒度和細粒度許可權控制的功能需要。
除了粗粒度許可權,系統中必然還會包括無數對具體Instance的細粒度許可權。這些問題,被留給對框架的擴展方法來解決,這樣的考慮基於以下兩點:
1、細粒度的許可權判斷必須要在資源上獲取許可權分配的支持的上下文信息才可能得以實現。
2、細粒度的許可權常常具有相當大的業務邏輯相關性。對不同的業務邏輯,常常意味著完全不同的許可權判定原則和策略。相比之下,粗粒度的許可權更具通用性,將其實現為一個架構,更有重用價值;而將細粒度的許可權判斷實現為一個架構級別的東西就顯得繁瑣,增加架構的復雜性。而且不是那麼的有必要,用定製的代碼來實現就更簡潔,更靈活。否則會變成各種邏輯代碼的堆砌。
比如,proct post數量的控制,這種一般要知道用戶個性化的信息,付錢數量到資料庫中查找最高數量,還要知道此用戶已經有多少產品等,規則不具備通用性和重用性,
所以細粒度控制不應該放在許可權架構層來解決。實例級的細粒度許可權的解決方案就是將它轉化為粗粒度許可權,這樣我們許可權客戶端就變得很簡單了。
名詞解釋
粗粒度許可權:一般可以通過配置文件來授權,授權只有真假,沒有多少之分,不需要上下文的支持。不消耗資源的。
邏輯表達式:判斷「Who對What(Which)進行How的操作」的邏輯表達式是否為真。
別名:靜態授權、類級授權
細粒度許可權:不能通過配置文件等表達,需要特定上下文的支持.
邏輯表達式:判斷「When(Where)的時候,Who對What(Which)進行How的操作」的邏輯表達式是否為真。
別名:動態授權、實例級授權
設計原則:框架只提供粗粒度的許可權。細粒度的許可權也需要集中管理和維護,細粒度的許可權通過定製的擴展代碼將細粒度轉化為粗粒度授權。
二、許可權系統的設計
許可權往往是一個極其復雜的問題, 設計許可權系統第一個要解決的問題就是什麼樣的行為是需要許可權控制,什麼樣的是業務方法。他們之間本來是沒有明確的區分,任何許可權從某種角度上說可以是一種業務方法。為了以後管理和開發方面我們從概念上需要將許可權和業務明確劃分清楚,指導開發。
許可權控制行為: 對What(Which)進行How的操作需要區分Who,具有Who身份差異性和可替換性。 我們將此類操作作為許可權。
特點: 可以收回也可以分配的,具有一定的抽象級別。 消耗資源,行為結果具備一些持久性的影響。
業務邏輯行為: 對What(Which)進行How的操作的時候與Who的身份無關或者具有Who身份差異性但 是不具有可替換性。
特點: 不能抽象和共享,很難回收和分配。不消耗資源,不產生持久性。現實中也存在某一時期行為是業務邏輯,最後演變成許可權控制,或者相反的過程。
1、粗粒度許可權設計
採用自主型訪問控制方法,操作給予訪問控制列表。每一個用戶通過角色獲得一組許可權集合,許可權系統的功能是驗證用戶申請的許可權(集合)是否在這個集合當中,即申請的許可權(集合)是否投影在用戶擁有的許可權集合,換句話說:只要某用戶直接或者間接的屬於某個Role那麼它就具備這個Role的所有許可權許可。
一個自主型訪問控制方法的許可權系統包括以下幾個部分:角色、許可權、訪問控製表、
(1)許可權
描述一個許可權可以通過以下幾個要素說明:
類型(class):
名稱(name):
動作(actions):
掩碼(mask):
屬性:
具體許可權Example:
1、Test
類型(class):com.yangjs.secutiry. permissions. TestPermission
名稱(name):如:test.* ,test.sub.* ,test.sub1.sub2
動作(actions): brower_detail ,post,repost,……
掩碼(mask):0x1,0x2,0x4…..
屬性: 無
.…………..
l 存取控制器(my--acl.xml)配置
存取控制項(ACE):角色到許可權的映射集合,表示某個角色可以在某些資源上執行某些動作,它們之間通過role關聯(繼承),ACE之間產生包含關系。
存取控制列表(ACL):ACE的集合。
我們的存取控制器(ACL)是通過一個xml的配置文件說明,存取控制列表由多個存取控制項(ACE)來描述。使用方法(略)
2、細粒度許可權設計
細粒度授權需要上下文的支持,而且每個許可權控制的上下問題都不一樣,這由相關的業務邏輯決定,而且此類授權一般變化較快,應此需要將強的可維護性和擴展性,支持變化,但又不能夠太復雜,否則缺乏可執行性。雖然此類許可權個性化較強,我們仍然可以總結出很多共性:
(1) 幾乎所有的授權需要用戶的角色和ID.
(2) 特定的上下文幾乎都同用戶資源使用情況相關.
我們將此類信息稱為UserState 即:User角色以及資源使用情況和當前狀態。大部分信息我們在用戶登陸的時候已經。獲得。授權貫穿Web層和Biz層,因此我們的登陸要獨立於Web端。因此上下文我們可以用UserState結合其他來抽象。
關於上下文的維護問題,我們不可能將UserState此類參數在Web層和Biz層來回傳遞,更加不能在需要授權的地方都加上一個這樣的方法參數,這樣不太現實。其次如果在授權的地方再從資料庫中取一次這樣雖然能夠解決部分問題(不能解決userId的傳遞),這樣效率太低,不能接受。
解決方法就是將此類信息cache起來,用的時候再去取,由於此類信息具有非常高的並發性,對線程安全較高,因此我們決定將此類信息放入一個線程上下文的內存cache中。此外我們由於引入cache,就需要解決所有cache共有的維護性問題。
Cache的生命周期:用戶的一次請求,屬於線程級,用戶請求線程結束,Cache結束。
Cache的更新:當上下文信息發生變化是需要及時更新Cache,這是一個不可避免的步驟。
Cache丟失:發生在如系統down機,線程崩潰,內存溢出等等,對用戶來說就是當前請求突然中斷。
當用戶重新發送請求,我們的系統就需要重新驗證用戶,此時我們可以更新Cache解決丟失問題。
Cache的清理:這個實現就是當用戶請求結束,返回應答的時候清理,可以通過Filter實現,比較簡單。
以上是相關的原理部分,我們看看系統地實現:
實現:線程上下文的cache
實現類:com.yangjs.cache.ThreadContextCache:
public class ThreadContextCache {
public static Map asMap();
public static boolean containsKey(Object key);
public static boolean containsValue(Object key);
public static Object get(Object key);
public static void put(Object key, Object value);
public static Object remove(Object key);
public static void clean();
public static int size() ;
public static void destroy()
② java怎麼實現數據級許可權控制,純純手寫
設計好許可權表,手寫攔截器,或者用框架,如:shiro
③ java許可權系統資料庫的設計,三張表的那種
用戶
create table T_USER
(
USERID NUMBER(10),
USERNAME VARCHAR2(50),
PASSWORD VARCHAR2(70),
TRUENAME VARCHAR2(50),
EMAIL VARCHAR2(100),
ADDRESS VARCHAR2(200),
TEL VARCHAR2(50),
STATE VARCHAR2(1) default '1',
MEMO VARCHAR2(100),
ROLEID NUMBER(10),
RANK NUMBER(2),
GENDER VARCHAR2(10) default '1'
)
角色
create table T_ROLE
(
ROLEID NUMBER(10),
ROLENAME VARCHAR2(100),
STATE VARCHAR2(1) default 1,
DESCRIPTION VARCHAR2(400)
)
功能
create table T_PERMISSION
(
ROLEID NUMBER(10),
PERMISSIONID NUMBER(10),
RESID NUMBER(10),
PRI_TYPE VARCHAR2(1)
)
④ java 中怎麼做許可權系統的控制和分配
下面是一個java的web許可權管理模塊的應用與實現。
先介紹數據模型和應用界面,後繼對實現細節做選擇性闡述。
數據表關系如下:
該圖標明了登陸用戶、角色、部門(機構)、用戶組、角色和模塊功能之間的關系。為方便起見,所有表都只保留必要欄位。
在本系統設計中,如下概念有著相對特殊的含義。
一、用戶(user): 系統的使用者。
二、部門(org):體現了用戶的行政關系,
三、組(group) :是某相同職能的用戶的集合,可以和用戶一樣與角色產生關聯。設置組的目的是為了方便用戶的角色分配,減少用戶與角色的直接對應關系。用戶的角色可以是其組角色和其直接分配的角色之合集。限於作者的時間和精力,組功能在該系統中沒有具體的實現。
四、角色(role):角色對應著某些功能(function)的集合,被分配一個角色意味著有權執行這些功能。角色表中的欄位"functions"記錄相關的功能id,id之間用逗號隔開。
五、功能(function):系統的一個或者多個執行准入。
⑤ java web開發多用戶博客系統,用戶許可權控制該怎麼實現
資料庫設計,設計如下:
用戶:user
角色:role
用戶-角色:user_role
資源:resource(包括上級菜單、子菜單、按鈕等資源)
角色-資源:role_resource
標準的許可權管理系統設計為以上5張表。
註:用戶、用戶-角色我就不做說明了,這兩個是很簡單的兩塊,用戶的crud,以及為用戶分配角色(多對多的關系)稍微琢磨一下就清楚了,下面都是針對為角色分配許可權的實現
後台實現
展示層採用ztree樹
⑥ java許可權系統資料庫的設計,三張表的那種
資料庫和程序都很重要。 資料庫方面設計許可權這一塊設計三張表,(用戶表、角色表、許可權表), 許可權表關聯用戶表和角色表的外鍵,這個就兩個一對多的關系代替了,多對多的關系。 在hibernate中配置的時候要配置用戶表和角色表的多對多關系。
⑦ 求助 java 的許可權相關設計,資料庫要怎麼樣設計才合理呢,要精確控制到模塊的,還有代碼實現方面。Help me
網路Hi圖
需求幾乎可以解決您的問題,我們也招了招手
ES的援助從網路知道:\ \
⑧ 使用java連接oracle資料庫的詳細步驟,以及怎樣在oracle資料庫里建庫建表,和用戶名及許可權的設置
你按照我以下的步驟就可以建立java跟oracle的鏈接:
(1)首先要安裝oracle資料庫(這是廢話,不過這個過程中你可以設置用戶名機密碼他的許可權相當於管理員),然後啟動查詢分析器再用 great database databasename(數據 庫的名稱)的命令建立資料庫,之後就是要建立資料庫的表,建表的命令如下(我給你的例子是建立一個學生表):
usr database/*你剛才所建立的資料庫的名稱,一定要相同,那麼你就是再這個資料庫中建立了這個表*/
CREATE TABLE stu
(
sno char(10) NOT NULL /*學號欄位*/
CONSTRAINT PK_sno PRIMARY KEY CLUSTERED,/*主鍵約束*/
sname char(8) NOT NULL, /*姓名欄位*/
sex char(2) NULL, /*性別欄位*/
native int NULL, /*籍貫*/
birthday varchar(20) NULL,/*學生出生日期*/
dno char(6) NULL,/*學生所在院系編號(外鍵)*/
spno char(8) NULL,/*專業代碼(外鍵)*/
classno char(4) NULL,/*班級號*/
entime char(4) NULL,/*學生入校時間*/
home varchar(40) NULL,/*學生家庭住址*/
tel varchar(40) NULL/*學生聯系電話*/
)
這樣你的資料庫和相應的表就建成了,如果你需要對資料庫的許可權進行設置那麼就涉及到角色的賦予或者你安裝oracle時需要進行設置的用戶明及密碼,這塊說來就話長啦!如果你只是學習java和資料庫的鏈接,那麼這個可以暫時放一邊,如果你非得想知道那麼你需要系統學習資料庫的知識。我這里就不跟你介紹了。建立完表之後就需要對表插入數據(插入數據可以用java編程,用自己設置的軟體插入數據也可以用資料庫的查詢分析氣用sql語句插入)
(2)這一步也是java跟資料庫鏈接的關鍵,在你安裝了資料庫的那台pc機或者伺服器注冊數據源步驟:進入你電腦的控制面板——管理工具——數據源——系統DNS(選中)——添加(在這裡面有你要添加的數據源添加microsoft DOBC for Orccle,再這里點擊完成後會彈出一個對話框,要你填寫數據源的名稱這個名稱一定要記住,java鏈接程序編程時需要用到這個名稱,還有要填伺服器的名稱,這個名稱需要你的伺服器名稱,如果你是單台pc機實驗,那麼在你資料庫登錄的界面那個伺服器名稱就可以了,然後點擊下去進行必要的設置就可以了),這樣我們對資料庫部分的工作已經完成啦!接下來就是完成java的編程部分。
(3)這里就是java的編程部分,這里我給了你一個我從教材弄來的編好並調試成功的程序(當然這跟你自己建立的資料庫是相關的):
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
class add extends JFrame {
private StudentUI userInterface;
private JButton clearButton, writeButton;
// 載入啟動程序和建立資料庫的地址,遠程和對本機的資料庫載入是不一樣得,這里給你一個對本機資料庫的操作
static final String JDBC_DRIVER = "("oracle.jdbc.driver.OracleDriver";
static final String DATABASE_URL = "oracle.jdbc.driver:剛才叫你記住的那個數據源的名字";
// declare Connection and Statement for accessing
// and querying database
private Connection connection;
private Statement statement;
String sqlString ;
//set up column names
String names[] = { "學 號","姓 名","性 別","年 齡","所 在 系"};
// set up GUI
public Add()
{
super( "Add a record of students" );
initialize(); //connect to database
// create instance of reusable user interface
userInterface = new StudentUI( names ); // four textfields
getContentPane().add( userInterface, BorderLayout.CENTER );
// configure button doTask1 for use in this program
writeButton = userInterface.getDoTask1Button();
writeButton.setText( "保存" );
// register listener to call addRecord when button pressed
writeButton.addActionListener(
// anonymous inner class to handle writeButton event
new ActionListener() {
// call addRecord when button pressed
public void actionPerformed( ActionEvent event )
{
addRecord();
}
} // end anonymous inner class
); // end call to addActionListener
// configure button doTask2 for use in this program
clearButton = userInterface.getDoTask2Button();
clearButton.setText( "清除" );
// register listener to call userInterface clearFields() when button pressed
clearButton.addActionListener(
// anonymous inner class to handle clearButton event
new ActionListener() {
// call userInterface clearFields() when button pressed
public void actionPerformed( ActionEvent event )
{
userInterface.clearFields();
}
} // end anonymous inner class
); // end call to addActionListener
// register window listener to handle window closing event
addWindowListener(
// anonymous inner class to handle windowClosing event
new WindowAdapter() {
// add current record in GUI to file, then close file
public void windowClosing( WindowEvent event )
{
terminate(); //close databse
}
} // end anonymous inner class
); // end call to addWindowListener
setSize( 300, 200 );
setVisible( true );
} // end of constructor
// connect to database
public void initialize()
{
try {
Class.forName( JDBC_DRIVER );
// establish connection to database
connection = DriverManager.getConnection( DATABASE_URL,"sa",null );
// create Statement for querying database
statement = connection.createStatement();
}
catch ( SQLException sqlException ) {
JOptionPane.showMessageDialog( null, sqlException.getMessage(),
"Database Error", JOptionPane.ERROR_MESSAGE );
System.exit( 1 );
}
// detect problems loading database driver
catch ( ClassNotFoundException classNotFound ) {
JOptionPane.showMessageDialog( null, classNotFound.getMessage(),
"Driver Not Found", JOptionPane.ERROR_MESSAGE );
System.exit( 1 );
}
} // end method openFile
// close database
public void terminate()
{
try {
statement.close();
connection.close();
}
// handle exceptions closing statement and connection
catch ( SQLException sqlException ) {
JOptionPane.showMessageDialog( null,
sqlException.getMessage(), "Database Error",
JOptionPane.ERROR_MESSAGE );
System.exit( 1 );
}
} // end method
// add record to file
public void addRecord()
{
String fieldValues[] = userInterface.getFieldValues();
// if sno field value is not empty
if ( ! fieldValues[ StudentUI.SNO ].equals( "" ) ) {
// output values to student
try {
int numberAge = Integer.parseInt(
fieldValues[ StudentUI.SAGE ] );
//define string for sql insert statement
String sqlInsert = "INSERT INTO student " +
"VALUES ('" +
fieldValues[0] + "', '" +
fieldValues[1] +"', '"+
fieldValues[2]+ "', "
+numberAge+",'"+fieldValues[4] + "')";
int result = statement.executeUpdate(sqlInsert);
if (result!=0) {
userInterface.clearFields();
JOptionPane.showMessageDialog( this,
"Inserted sucess!", "Insert Result",
JOptionPane.INFORMATION_MESSAGE );
}
} // end try
// process invalid age number
catch ( NumberFormatException formatException ) {
JOptionPane.showMessageDialog( this,
"Bad age number ", "Invalid Number Format",
JOptionPane.ERROR_MESSAGE );
}
// process exceptions from file output
catch (SQLException ee)
{ System.out.println(ee); }
} //end of if sno field value is not empty
else //if sno field value is empty
JOptionPane.showMessageDialog( this,
"Bad sno number ", "Invalid Number Format",
JOptionPane.ERROR_MESSAGE );
} // end method addRecord
public static void main( String args[] )
{
new AddStudentFrame();
}
} // end AddStudentFrame class
基本就這樣啦!不過那個界面的設計代碼就不給你啦!