You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于AWS Lambda无服务器架构实现Spring Security ACL类细粒度授权

AWS无服务器方案实现实例级细粒度授权(博客评论场景)

核心设计思路

基于DynamoDB存储实例级ACL规则,通过Lambda函数处理权限配置与校验逻辑:

  • 用DynamoDB复合键快速定位「特定博客」对应的「用户/角色权限规则」
  • 博客所有者触发Lambda写入屏蔽规则(禁止指定用户/角色评论)
  • 评论接口前置调用授权校验Lambda,判断当前用户是否被屏蔽

DynamoDB表结构设计

表名:ResourceACL

分区键(PK)排序键(SK)属性字段说明
resourceType#resourceIdprincipalType#principalIdaction控制的操作,如comment
effect权限效果,如deny
createdBy规则创建者(博客ID/用户ID)
createdAt规则创建时间戳

示例数据:PK为blog#123,SK为user#456,action为comment,effect为deny → 表示禁止用户456评论博客123

Lambda函数实现(TypeScript)

1. 添加屏蔽规则(博客所有者调用)

该函数接收博客ID、目标主体类型(user/role)、主体ID,写入DynamoDB ACL规则:

import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall } from "@aws-sdk/util-dynamodb";

const client = new DynamoDBClient({});

export const handler = async (event: any) => {
  const { blogId, principalType, principalId, createdBy } = JSON.parse(event.body);
  
  const params = {
    TableName: "ResourceACL",
    Item: marshall({
      PK: `blog#${blogId}`,
      SK: `${principalType}#${principalId}`,
      action: "comment",
      effect: "deny",
      createdBy,
      createdAt: Date.now()
    })
  };

  try {
    await client.send(new PutItemCommand(params));
    return { statusCode: 200, body: JSON.stringify({ message: "屏蔽规则已添加" }) };
  } catch (error) {
    return { statusCode: 500, body: JSON.stringify({ error: "添加规则失败" }) };
  }
};

2. 评论权限校验(评论接口前置调用)

该函数接收当前用户ID、博客ID,查询DynamoDB判断是否存在禁止评论的规则:

import { DynamoDBClient, GetItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

const client = new DynamoDBClient({});

export const handler = async (event: any) => {
  const { userId, blogId } = event.queryStringParameters;
  
  // 校验用户级屏蔽规则
  const userParams = {
    TableName: "ResourceACL",
    Key: marshall({
      PK: `blog#${blogId}`,
      SK: `user#${userId}`
    })
  };

  const userResult = await client.send(new GetItemCommand(userParams));
  if (userResult.Item) {
    const rule = unmarshall(userResult.Item);
    if (rule.action === "comment" && rule.effect === "deny") {
      return { statusCode: 403, body: JSON.stringify({ message: "你已被禁止评论该博客" }) };
    }
  }

  // 校验用户所属角色的屏蔽规则(假设角色信息来自Cognito授权上下文)
  const userRoles = event.requestContext.authorizer?.roles || [];
  for (const roleId of userRoles) {
    const roleParams = {
      TableName: "ResourceACL",
      Key: marshall({
        PK: `blog#${blogId}`,
        SK: `role#${roleId}`
      })
    };
    const roleResult = await client.send(new GetItemCommand(roleParams));
    if (roleResult.Item) {
      const rule = unmarshall(roleResult.Item);
      if (rule.action === "comment" && rule.effect === "deny") {
        return { statusCode: 403, body: JSON.stringify({ message: "你的角色已被禁止评论该博客" }) };
      }
    }
  }

  // 无屏蔽规则,允许评论
  return { statusCode: 200, body: JSON.stringify({ allowed: true }) };
};

前端调用示例(JavaScript)

博客所有者点击「屏蔽用户」按钮时,调用添加规则的API:

async function blockUserFromComment(blogId, userId, currentUserId) {
  try {
    const response = await fetch('https://<api-gateway-id>.execute-api.<region>.amazonaws.com/prod/add-block-rule', {
      method: 'POST',
      headers: { 
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${window.localStorage.getItem('idToken')}`
      },
      body: JSON.stringify({
        blogId,
        principalType: 'user',
        principalId: userId,
        createdBy: currentUserId
      })
    });
    const data = await response.json();
    alert(data.message);
  } catch (error) {
    console.error('添加屏蔽规则失败:', error);
  }
}

扩展优化建议

  • 给DynamoDB添加全局二级索引,支持按用户/角色查询所有被屏蔽的博客
  • 用AWS Cognito做身份认证,通过IAM策略限制只有博客所有者能调用添加规则的Lambda
  • 批量校验角色权限时,改用BatchGetItemCommand提升查询效率

内容的提问来源于stack exchange,提问作者NinjaDev786

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 15:15:33