2015-05-28 36 views
2

我正在尝试使用OrientDB的文档数据库(Java)API工作来使用Record Level Security。我喜欢将数据库中某些记录的访问限制为特定角色的想法;但是,我无法找到如何在文档中做到这一点。我是OrientDB的新手,所以我确信我只是错过了一些东西。OrientDB - 如何 - 使用ODocument记录级别安全性

这是我到目前为止。

// Create database. 
ODatabaseDocumentTx db = new ODatabaseDocumentTx(path); 
db.create(); 

// Create role with no permissions. 
db.command(new OCommandSQL("INSERT INTO orole SET name = 'foobar', mode = 0;")).execute(); 

// Create a user with the new role. 
OSecurity sm = db.getMetadata().getSecurity(); 
OUser user = sm.createUser("user", "user", "foobar"); 
ORole foobarRole = sm.getRole("foobar"); 

// Insert 2 records, one restricted, one is not. 
OClass restricted = db.getMetadata().getSchema().getClass("ORestricted"); 
OClass docClass = db.getMetadata().getSchema().getOrCreateClass(TABLE_NAME, restricted); 

ODocument doc1 = new ODocument(docClass); 
ODocument doc2 = new ODocument(docClass); 

// The restricted record... 
doc1.field("name", TABLE_NAME); 
doc1.field("Id", 1, OType.INTEGER); 
doc1.field("Message", "Hello 1", OType.STRING); 
doc1.save(); 

// The unrestricted record... 
doc2.field("name", TABLE_NAME); 
doc2.field("Id", 2, OType.INTEGER); 
doc2.field("Message", "Hello 2", OType.STRING); 
doc2.save(); 

// Allow "user" with "foobar" role to read record doc2. 
String sql = String.format(
    "UPDATE %s ADD _allowRead = %s", 
    doc2.getIdentity().toString(), 
    foobarRole.getDocument().getIdentity().toString()); 

db.command(new OCommandSQL(sql)).execute(); 

// Give foobar role permission to read from table. 
db.command(new OCommandSQL(String.format("GRANT READ ON database.class.%s TO foobar", TABLE_NAME))).execute(); 

db.close(); 

// Open connection for "user". 
ODatabaseDocumentTx userDb = new ODatabaseDocumentTx(path); 
userDb.open("user", "user"); 

// Here I would expect to see the message from doc2 but not doc1. 
// Nothing gets printed... 
for (ODocument odoc : userDb.browseClass(TABLE_NAME)) 
{ 
    System.out.println(odoc.field("Message")); 
} 

该文档指出,在读取期间跳过角色不可访问的记录。在我的情况下,用户不能读取任何内容。

任何想法,我怎样才能得到这种行为工作?

回答

1

经过几天的摆弄,这就是我如何运作的。

// Create database. 
ODatabaseDocumentTx db = new ODatabaseDocumentTx(path); 
db.create(); 

// Create users/roles. 
OSecurity sm = db.getMetadata().getSecurity(); 

restrictedRole = sm.createRole("foobar", OSecurityRole.ALLOW_MODES.DENY_ALL_BUT); 
restrictedRole.addRule(ORule.ResourceGeneric.CLASS, TABLE_NAME, ORole.PERMISSION_READ); 
restrictedRole.addRule(ORule.ResourceGeneric.DATABASE, TABLE_NAME, ORole.PERMISSION_READ); 
restrictedRole.addRule(ORule.ResourceGeneric.CLUSTER, TABLE_NAME, ORole.PERMISSION_READ); 
restrictedRole.save(); 
restrictedRole.reload(); 

admin = sm.getUser("admin"); 
user2 = sm.createUser("user2", "user2", "foobar"); 

// Insert 2 records, one restricted, one is not. 
OClass restricted = db.getMetadata().getSchema().getClass("ORestricted"); 
OClass docClass = db.getMetadata().getSchema().getOrCreateClass(TABLE_NAME, restricted); 

ODocument doc1 = new ODocument(docClass); 
ODocument doc2 = new ODocument(docClass); 

// The restricted record... 
doc1.field("name", TABLE_NAME); 
doc1.field("Id", 1, OType.INTEGER); 
doc1.field("Message", "Hello 1", OType.STRING); 
doc1.save(); 

// The unrestricted record... 
doc2.field("name", TABLE_NAME); 
doc2.field("Id", 2, OType.INTEGER); 
doc2.field("Message", "Hello 2", OType.STRING); 
db.getMetadata().getSecurity().allowRole(doc2, OSecurityShared.ALLOW_READ_FIELD, "foobar"); 
doc2.save(); 

// 
// PRINT RESTRICTED 
// 
db.close(); 
db = new ODatabaseDocumentTx(path); 
db.open("user2", "user2"); 

// Prints: 
// Hello 2 
for (ODocument doc : db.browseClass(TABLE_NAME)) 
{ 
    System.out.println(doc.field("Message")); 
} 

// 
// PRINT ADMIN 
// 
db.close(); 
db = new ODatabaseDocumentTx(path); 
db.open("admin", "admin"); 

// Prints: 
// Hello 1 
// Hello 2 
for (ODocument doc : db.browseClass(TABLE_NAME)) 
{ 
    System.out.println(doc.field("Message")); 
} 

的角色addRule方法允许用户与该角色从课堂上阅读。第二个文档有一个额外的行allowRole,允许具有该角色的用户阅读该特定文档,这是故意排除在第一个文档之外的。结果是具有“foobar”角色的用户在阅读时只能获得第二个文档。管理员角色可以读取这两个文档。

此外,请注意从“ORestricted”的文档类继承。

OClass restricted = db.getMetadata().getSchema().getClass("ORestricted"); 
OClass docClass = db.getMetadata().getSchema().getOrCreateClass(TABLE_NAME, restricted); 

该文件需要继承ORestricted为了记录级别的安全性工作。就我个人而言,我没有发现如何在任何地方的代码中执行此操作的解释(也许我没有在正确的位置查找),并且Java中没有直接从类ORestricted继承的文档类。所以我们必须使用模式类元数据来告诉驱动程序我们正在创建的文档需要从ORestricted继承。

相关问题