2012-04-26 91 views
0

摘要如何做基于内容的授权?


我有一些复杂的数据库结构,我想仅提供授权的成员数据 - 的人也依赖于存储在数据库中的数据的角色。它一直工作到现在,但现在我想扩展服务,它变得非常复杂。必须有一个优雅的方式。

注意:我没有使用ASP.NET,所以请不要建议那些与它紧密相关的补救措施,尽管我很乐意为授权过程建模提供建议。

背景


好吧,我再次问这个问题之前太多,但出乎我的意料,它没有任何收获良好的反应正因为如此,所以我在这里张贴在不同的字。我正在开发一个Web应用程序,并且在如何以优雅的方式建模授权过程方面存在问题。

比方说,我有一个应用程序提供以下服务。有'项目'/工作区,您可以发布内容并评论这些帖子。被视为“开放”的项目也可以被“追踪” - 因此内容可供追随者访问。为了使这种情况更接近我的实际服务,项目“成员”可以决定关注者的访问权限。这可能(或可能不)!看起来很复杂,但实际的应用程序更复杂。我所做的是在sql查询本身内填写过滤代码。下面是一个代码示例:

public function getProjectById($id) { 
     $auth = new Auth(); 
     $userid = $auth->getCurrentUserId(); 


     $sql = " 
      SELECT P.id, P.userId, P.name, P.description, 
       P.creationTime, P.startTime, P.endTime, P.isOpen 
      FROM  projects P 
      INNER JOIN project_members PM 
         ON PM.projectid = P.id 
        AND P.id = '{id}' 
        AND (PM.userId = '{userid}' OR P.isOpen = 1) 
     "; 

     return $this->result($sql, array("userid" => $userid, "id" => $id)); 
    } 

这看起来不太好,因为我也有提供这个数据来预测的追随者(这里没有显示)。复杂性在评论和帖子处理代码中上升。现在有没有更好的方法来做到这一点 - 必须有。我应该将授权逻辑分解到其他类吗?或者/我应该使用数据库中的“视图”(完全不必要,但我仍想指出它们不是MVC视图)?或者还有更好的,笨拙的方法来解决这个问题吗?

欢迎您提出所有建议 - 即使那些旨在改变数据库结构的建议 - 尽管我不知道为什么需要这样做。

在此先感谢!

回答

1

我认为你的观点是正确的,但由于每次调用都需要传递用户ID,这听起来像你真正需要的是表值函数。我最熟悉微软SQL,它会是这个样子:

SELECT P.* 
FROM Projects AS P 
    INNER JOIN dbo.AuthProjects(@UserID) AS AP ON P.ProjectID = AP.ProjectID 

注意,TVF字面上返回一个表,对此你会加入,看看哪些项目是可用的。 TVF的定义可能看起来像这样:

CREATE FUNCTION dbo.AuthProjects(@UserID INT) 
    RETURNS @Results TABLE (ProjectID INT NOT NULL, WriteAccess BIT NOT NULL) 
AS BEGIN 
    INSERT INTO @Results (ProjectID, WriteAccess) 
     SELECT 
      ProjectID, WriteAccess 
     FROM 
      Authorizations 
     WHERE 
      UserID = @UserID 

    -- Additional logic for more ways a project may be authorized 

    RETURN 
END 
+0

哦!感谢您提供宝贵的答案,但是我担心 - 我对MS SQL并不了解,因为我正在使用MySQL - 据我所知,这似乎不适用于MySQL ...但是真的,谢谢有兴趣引导我... – 2012-04-27 15:59:11

+0

刚才检查它,它支持功能!哇!我不知道...哦!你不知道你有多少帮助我...... thanx! – 2012-04-27 17:35:55