对于如何使用GraphQLAPI在AWSAppSync中的DynamoDB对象之间实现“分层”权限?感兴趣的读者,本文将会是一篇不错的选择,并为您提供关于AWSAmplify,从AppSyncgrap
对于如何使用 GraphQL API 在 AWS AppSync 中的 DynamoDB 对象之间实现“分层”权限?感兴趣的读者,本文将会是一篇不错的选择,并为您提供关于AWS Amplify,从 AppSync graphql API 获取项目时出现“错误:无凭证”、AWS AppSync and the GraphQL Info Object、AWS Appsync Graphql Java 客户端 - IAM 授权、AWS DynamoDb使用DynamoDbEnhancedClient读取BatchRead的有用信息。
本文目录一览:- 如何使用 GraphQL API 在 AWS AppSync 中的 DynamoDB 对象之间实现“分层”权限?
- AWS Amplify,从 AppSync graphql API 获取项目时出现“错误:无凭证”
- AWS AppSync and the GraphQL Info Object
- AWS Appsync Graphql Java 客户端 - IAM 授权
- AWS DynamoDb使用DynamoDbEnhancedClient读取BatchRead
如何使用 GraphQL API 在 AWS AppSync 中的 DynamoDB 对象之间实现“分层”权限?
如何解决如何使用 GraphQL API 在 AWS AppSync 中的 DynamoDB 对象之间实现“分层”权限??
我正在使用 AppSync 和 GraphQL 构建一个项目,以使餐厅能够跟踪订单。有四个 DynamoDB 表(以下每个实体一个):餐厅、员工、表和订单。每个餐厅可以有许多员工,每个员工被分配到一张或多张桌子。每个表可以有多个订单,但一个订单只能属于一个表(有关这些关系的可视化,请参阅 System Design diagram)。
问题
我的问题是我需要非常细粒度的分层访问控制,主要有 3 个问题:
-
属于一家餐厅的员工不得能够创建、读取、更新或删除属于其他餐厅的任何实体。
-
餐厅的所有员工都可以查看餐厅中的所有餐桌。但是,他们只能查看属于该表的订单,如果它们被分配到该表(例如,将特定 Staff 成员连接到该表的 StaffTableJoin 对象存在。)OR他们是餐厅管理员(参见第 3 部分)
-
作为餐厅管理员的员工可以查看属于餐厅任何餐桌的所有订单。
为每个员工创建一个 cognito 用户,并应根据我的 DynamoDB 表中实体之间的关系分配他们的权限。
考虑的解决方案
我访问了 AWS 文档中的 Authorization and Authentication 页面以探索限制权限的选项。到目前为止,我已经考虑过使用 COGNITO_USER_POOLS 和 AWS_LAMDBA 授权。
-
对于使用 COGNITO_USER_POOLS 的方法,我将为每个餐厅创建一个 Cognito 用户组。当新员工注册时,他们会被分配到他们餐厅的用户组。然后,我将向每个数据库中的每个实体添加一个 groupsCanAccess 字段。我的解析器会检查请求用户是否属于允许访问每个资源的组。然而,这只能解决问题 1,因为餐厅的所有员工都将拥有访问其餐厅资源的相同权限。
-
对于使用 AWS_LAMBDA 的方法,我不太确定这将如何工作,但我考虑创建一个 Authorization lambda 来检查请求用户所属的餐厅。例如,如果用户请求订单,我需要检查订单属于哪个表,然后检查是否存在 StaffUserJoin(将请求用户连接到表)。这种方法看起来很困难(也许不可能)。
非常感谢可以提供的任何建议,因为我已经为此苦苦挣扎了很长时间。这似乎是一个常见的用例,需要基于对象层次结构的权限。提前致谢:)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
AWS Amplify,从 AppSync graphql API 获取项目时出现“错误:无凭证”
我想我可能已经找到了解决方案。
我只需要像这样用 @aws_api_key
注释我的 schema.graphql:
type Item @model @aws_api_key {
id: ID!
name: String
}
当然还有您定义的任何自定义更改和订阅。
见:https://aws.amazon.com/blogs/mobile/graphql-security-appsync-amplify/
AWS AppSync and the GraphQL Info Object
https://amazonaws-china.com/blogs/mobile/appsync-and-the-graphql-info-object/
This article was written by Brice Pellé, Principal Specialist Solutions Architect, AWS
AWS AppSync is a fully managed service that allows to deploy Serverless GraphQL backends in the AWS cloud. GraphQL is a data language for your API that makes it easy and straight forward to interact with multiple data sources. One of the advantages of GraphQL is that it can retrieve data from multiple sources at once, with a single request. Additionally GraphQL queries provide a selection set that specifies the shape of the expected results, ensuring that only the wanted fields and nested fields are returned.
Today we are pleased to announce support for the GraphQL Info object in AWS AppSync. When making queries or mutations, resolvers now have access to an info object that provides information about the GraphQL request being made. In addition to providing the field name, parent name and variables of the query, the info object also exposes details about the selection set. This makes it possible to make calls to your data sources that are fine-tuned based on your queries expected data shape.
For example, the info object comes in handy when a type is backed by a primary data source, and is also composed of fields whose types are backed by other data sources. Using a single resolver, the info object’s selection set information can be used to identify which fields have been requested and which data sources should be queried. It removes the need to attach additional resolvers to nested fields and optimizes the GraphQL query performance by reducing the number of resolver invocations.
The info object is part of the $context
variable in the AppSync resolver and has the following definition:
{
"fieldName": "string",
"parentTypeName": "string",
"variables": { ... },
"selectionSetList": ["string"],
"selectionSetGraphQL": "string"
}
The field selectionSetList
contains the list of the fields in the selection set. The field names include the full path to the field. (i.e.: field/childField
). Note that alias fields will only be referenced by their alias name. The field selectionSetGraphQL
is a string representation of the selection set formatted as GraphQL schema definition language (SDL).
To give you an idea of how the info object works and how to use it with your AppSync resolvers, let’s take a look at this simple schema that consists of posts and comments, where a post can have multiple comments associated with it:
type Post {
id: ID!
content: String!
comments: [Comment]!
}
type Comment {
id: ID!
content: String!
postID: ID!
}
type Query {
getPost(id: String!): Post
}
The application data is stored in a SQL database hosted with the Amazon Relational Database Service (RDS). The Post and Comment entries are respectively stored in the tables Posts
and Comments
. The getPost
query uses a Lambda resolver that invokes an AWS Lambda function to connect and make calls to the backend database.
As a side note, using Lambda to connect to RDS instances can be made even better with the newly released RDS Proxy which optimizes database connections by managing connection pooling, as well as Lambda support for provisioned concurrency to address any concerns related to cold starts. GraphQL clients can now leverage these new capabilities when accessing SQL data backed by AppSync APIs and Lambda functions, however this is outside of the scope of this article.
Clients interacting with the AppSync API defined by the schema above can get a post with its list of comments using the following GraphQL query:
query GetPost($id: ID!) {
getPost(id: $id) {
id
content
comments {
id
content
}
}
}
and related variables:
{ "id": "<id>" }
Previously, without the info object, there was no way for the getPost
resolver to know if fetching comments was necessary. The resolver had to always fetch comments (even if not requested) or another resolver had to be attached to the comments field of the Post
type. Now when a request to the query getPost
is made, the AppSync resolver is called and the following info
object is available.
{
"fieldName": "getPost",
"parentTypeName": "Query",
"variables": { "id": "<id>" },
"selectionSetList": [
"id",
"content",
"comments",
"comments/id",
"comments/content"
],
"selectionSetGraphQL": "{\n id\n content\n comments {\n id\n content\n }\n}"
}
You can pass selectionSetList
and selectionSetGraphQL
to your Lambda function in your resolver by adding them to the payload:
{
"version" : "2017-02-28",
"operation": "Invoke",
"payload": {
"arguments": $utils.toJson($ctx.args),
"selectionSetList": $utils.toJson($ctx.info.selectionSetList),
"selectionSetGraphQL": $utils.toJson($ctx.info.selectionSetGraphQL)
}
}
Note that you must specifically reference the selection set items if you want them to be available in the payload. They will not be available if you only pass the info object directly with $utils.toJson($ctx.info)
.
Now your Lambda function can use specific business logic to make an optimized call to your backend. For example, Lambda can check for the existence of the comments
field. If present, the Lambda function can then query the database for the post with a matching ID and for all the comments with a postId
equal to the post’s ID. The code below shows how selectionSetList
can be used in a Lambda function:
const mysql = require(''mysql'')
const connection = mysql.createConnection({...}) // connect to the database
function executeSQL(sql, fields) {
console.log(''Executing SQL:'', sql, fields)
return new Promise((resolve, reject) => {
connection.query(sql, fields, (err, results) => {
if (err) {
return reject(err)
}
return resolve(results)
})
})
}
exports.handler = async event => {
const id = event.arguments.id
const fields = event.selectionSetList.filter(f => !f.startsWith(''comments''))
const postQuery = `SELECT ?? FROM ?? where id = ?`
const results = await executeSQL(postQuery, [fields, ''Posts'', id])
if (results.length === 0) {
return null
}
const post = results[0]
var comments = []
const found = event.selectionSetList.find(f => f === ''comments'')
if (found) {
const fields = event.selectionSetList
.filter(f => f.startsWith(''comments/''))
.map(f => f.split(''/'')[1])
const commentQuery = `SELECT ?? FROM ?? where postId = ?`
comments = await executeSQL(commentQuery, [fields, ''Comments'', id])
}
return { ...post, comments }
}
Next steps
The introduction of the info object opens up the door to new improvements and further optimization of your AppSync resolvers business logic. We’re looking forward to seeing how AppSync users can leverage it.
If you have any questions or want to submit feedback about this new feature, make sure to visit the AWS AppSync Forum. You can find more information about the info object by visiting the AppSync Resolver Context reference in the documentation.
AWS Appsync Graphql Java 客户端 - IAM 授权
如何解决AWS Appsync Graphql Java 客户端 - IAM 授权?
这是我实现业务逻辑的架构
type Query {
getLicenseinformation(localmd5: String): License @aws_cognito_user_pools
getUserinformation(username: String!): CognitoUser @aws_iam
listUsers(searchString: String): [NamedResource] @aws_iam
}
我使用 RestTemplate 作为我的 Java 客户端来使用提供 API 密钥作为授权的 graphql 端点。我在标题 paart 中添加了 api 密钥作为 x-api-key。
RestTemplate restTemplate=new RestTemplate();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.set("x-api-key",api_key.getId());
requestHeaders.set("Content-Type","application/graphql");
httpentity entity = new httpentity(requestHeaders);
ResponseEntity<String> exchange = restTemplate.exchange(URL,HttpMethod.POST,new httpentity(query,requestHeaders),String.class);
上述实现从后端检索值。 但是根据其他团队定义的模式,授权模式不是API key而是iam。所以我必须相应地配置其余模板。
我可以在 Java 客户端代码中的何处进行配置,以便将 aws_iam 用作从端点检索信息的授权方法。 Dynamodb 是数据源
解决方法
像下面这样构建请求对象有帮助:
*ngFor
AWS DynamoDb使用DynamoDbEnhancedClient读取BatchRead
由于您具有分区键和排序键,我认为您在 .sortValue()
Key.builder()
它必须为 Key.builder().partitionValue(projectId).sortValue(your-sort-key).build()
如果您希望所有内容都在某个分区键下,请执行以下操作:
List<DTO> DTOs = pageToList(mappedTable.query(
QueryEnhancedRequest
.builder()
.queryConditional(
QueryConditional.keyEqualTo(
Key.builder().partitionValue(projectId).build()
)
)
.build()
private List<DTO> pageToList(SdkIterable<Page<DTO>> iterable) {
List<DTO> rVal = new ArrayList<>();
iterable.forEach(item -> rVal.addAll(item.items()));
return rVal;
}
请注意,这是假设您使用的是最新的增强依赖项:
software.amazon.awssdk 动力增强我们今天的关于如何使用 GraphQL API 在 AWS AppSync 中的 DynamoDB 对象之间实现“分层”权限?的分享就到这里,谢谢您的阅读,如果想了解更多关于AWS Amplify,从 AppSync graphql API 获取项目时出现“错误:无凭证”、AWS AppSync and the GraphQL Info Object、AWS Appsync Graphql Java 客户端 - IAM 授权、AWS DynamoDb使用DynamoDbEnhancedClient读取BatchRead的相关信息,可以在本站进行搜索。
本文标签: