如何做基于内容的授权?

时间:2012-04-26 17:00:00

标签: sql architecture authorization

摘要


我有一些复杂的数据库结构,我想只向授权成员提供数据 - 他们的角色也取决于存储在数据库中的数据。它一直在工作,但现在我想扩展服务,它变得非常复杂。必须有一种优雅的方式。

注意:我没有使用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 个答案:

答案 0 :(得分:1)

我认为你在视频的正确轨道上,但由于每次调用都需要传递用户ID,听起来你真正需要的是表值函数。我最熟悉Microsoft 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