① 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
基本就这样啦!不过那个界面的设计代码就不给你啦!