zoukankan      html  css  js  c++  java
  • Dapr + .NET Core实战(七)Secrets

    4小时Dapr+.NET 5+K8S 的实战  https://ke.qq.com/course/4000292?tuin=1271860f

    Dapr进阶虚拟机集群实战(非K8S) https://ke.qq.com/course/4002149?tuin=1271860f

                       

    什么是Secrets

    应用程序通常会通过使用专用的存储来存储敏感信息,如连接字符串、密钥等。

    通常这需要建立一个密钥存储,如Azure Key Vault、Hashicorp等,并在那里存储应用程序级别的密钥。 要访问这些密钥存储,应用程序需要导入密钥存储SDK,并使用它访问这些密钥。 这可能需要相当数量的模板代码,这些代码与应用的实际业务领域无关,因此在多云场景中,可能会使用不同厂商特定的密钥存储,这就成为一个更大的挑战。

    让开发人员在任何地方更容易访问应用程序密钥, Dapr 提供一个专用的密钥构建块 ,允许开发人员从一个存储获得密钥。

    使用 Dapr 的密钥存储构建块通常涉及以下内容:

    1. 设置一个特定的密钥存储解决方案的组件。
    2. 在应用程序代码中使用 Dapr Secrets API 获取密钥。
    3. 在Dapr的Component文件中引用密钥

    工作原理

    1. 服务A调用 Dapr Secrets API,提供要检索的Serects的名称和要查询的项名字。
    2. Dapr sidecar 从Secrets存储中检索指定的机密。
    3. Dapr sidecar 将Secrets信息返回给服务。

    Dapr目前支持的Secrets存储请见存储

    使用Secrets时,应用程序与 Dapr sidecar 交互。 sidecar 公开Secrets API。 可以使用 HTTP 或 gRPC 调用 API。 使用以下 URL 调用 HTTP API:

    http://localhost:<dapr-port>/v1.0/secrets/<store-name>/<name>?<metadata>

    URL 包含以下字段:

    • <dapr-port> 指定 Dapr sidecar 侦听的端口号。
    • <store-name> 指定 Dapr Secrets存储的名称。
    • <name> 指定要检索的密钥的名称。
    • <metadata> 提供Secrets的其他信息。 此段是可选的,每个Secrets存储的元数据属性不同。 有关元数据属性详细信息

    项目实战

    通过Dapr SDK获取secrets

    仍然使用FrontEnd项目,并使用本地文件存储Secrets,首先在默认component目录C:Users<username>.daprcomponents中新建文件secrets01.json,声明密钥内容

    {
        "RabbitMQConnectStr": "amqp://admin:123456@192.168.43.101:5672"
    }

    在此目录新建secrets01.yaml定义store

    apiVersion: dapr.io/v1alpha1
    kind: Component
    metadata:
      name: secrets01
    spec:
      type: secretstores.local.file
      version: v1
      metadata:
      - name: secretsFile
        value: C:Usersusername.daprcomponentssecrets01.json
      - name: nestedSeparator
        value: ":"

    定义接口获取Secrets01的内容,新建SecretsController

    using Dapr.Client;
    
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace FrontEnd.Controllers
    {
        [Route("[controller]")]
        [ApiController]
        public class SecretsController : ControllerBase
        {
            private readonly ILogger<SecretsController> _logger;
            private readonly DaprClient _daprClient;
            public SecretsController(ILogger<SecretsController> logger, DaprClient daprClient)
            {
                _logger = logger;
                _daprClient = daprClient;
            }
    
            [HttpGet]
            public async Task<ActionResult> GetAsync()
            {
                Dictionary<string, string> secrets = await _daprClient.GetSecretAsync("secrets01", "RabbitMQConnectStr");
                return Ok(secrets);
            }
        }
    }

    运行Frontend

    dapr run --dapr-http-port 3501 --app-port 5001  --app-id frontend dotnet  .FrontEndinDebug
    et5.0FrontEnd.dll

    验证此api,获取成功

    通过IConfiguration访问Secrets

    Dapr还提供了从IConfiguration中访问Secrets的方法,首先引入nuget包Dapr.Extensions.Config

    在Program.cs中修改注册

            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                    .ConfigureAppConfiguration(config =>
                    {
                        var daprClient = new DaprClientBuilder().Build();
                        var secretDescriptors = new List<DaprSecretDescriptor> { new DaprSecretDescriptor("RabbitMQConnectStr") };
                        config.AddDaprSecretStore("secrets01", secretDescriptors, daprClient);
                    })
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup<Startup>().UseUrls("http://*:5001");
                    });

    在SecretsController注入IConfiguration

            private readonly ILogger<SecretsController> _logger;
            private readonly DaprClient _daprClient;
            private readonly IConfiguration _configuration;
            public SecretsController(ILogger<SecretsController> logger, DaprClient daprClient, IConfiguration configuration)
            {
                _logger = logger;
                _daprClient = daprClient;
                _configuration = configuration;
            }

    在SecretsController中新增接口

            [HttpGet("get01")]
            public async Task<ActionResult> Get01Async()
            {
                return Ok(_configuration["RabbitMQConnectStr"]);
            }

    调用接口,获取数据成功

    其他组件引用Secrets

    Dapr的其他组件,同样可以引用Secrets,我们以上节RabbitMQBinding为例,修改rabbitbinding.yaml

    apiVersion: dapr.io/v1alpha1
    kind: Component
    metadata:
      name: RabbitBinding
    spec:
      type: bindings.rabbitmq
      version: v1
      metadata:
      - name: queueName
        value: queue1
      - name: host
        secretKeyRef:
          name: RabbitMQConnectStr
          key: RabbitMQConnectStr
      - name: durable
        value: true
      - name: deleteWhenUnused
        value: false
      - name: ttlInSeconds
        value: 60
      - name: prefetchCount
        value: 0
      - name: exclusive
        value: false
      - name: maxPriority
        value: 5
    auth:
      secretStore: secrets01

    secretKeyRef元素引用指定的密钥。 它将替换以前的 明文 值。  在 auth 中找到对应的secretStore。

    现在运行Frontend

    dapr run --dapr-http-port 3501 --app-port 5001  --app-id frontend dotnet  .FrontEndinDebug
    et5.0FrontEnd.dll

    在RabbitMQ Management中发送消息,消费成功

    == APP == info: FrontEnd.Controllers.RabbitBindingController[0]
    == APP ==       .............binding.............11122444

    限制Secrets访问权限

    我们可以在Dapr的默认配置文件C:Usersusername.daprconfig.yaml中设置Secrets的访问权限,现在我们尝试禁止secrets01的权限

    apiVersion: dapr.io/v1alpha1
    kind: Configuration
    metadata:
      name: daprConfig
    spec:
      tracing:
        samplingRate: "1"
        zipkin:
          endpointAddress: http://localhost:9411/api/v2/spans
      secrets:
        scopes:
          - storeName: secrets01
            defaultAccess: deny

    设置之后,Frontend会启动失败,因为我们在Program.cs中设置了读取secrets01。

    == APP == Unhandled exception. Dapr.DaprException: Secret operation failed: the Dapr endpoint indicated a failure. See InnerException for details.
    == APP ==  ---> Grpc.Core.RpcException: Status(StatusCode="PermissionDenied", Detail="access denied by policy to get "RabbitMQConnectStr" from "secrets01"")
    == APP ==    at Dapr.Client.DaprClientGrpc.GetSecretAsync(String storeName, String key, IReadOnlyDictionary`2 metadata, CancellationToken cancellationToken)
    == APP ==    --- End of inner exception stack trace ---
    == APP ==    at Dapr.Client.DaprClientGrpc.GetSecretAsync(String storeName, String key, IReadOnlyDictionary`2 metadata, CancellationToken cancellationToken)
    == APP ==    at Dapr.Extensions.Configuration.DaprSecretStore.DaprSecretStoreConfigurationProvider.LoadAsync()
    == APP ==    at Dapr.Extensions.Configuration.DaprSecretStore.DaprSecretStoreConfigurationProvider.Load()
    == APP ==    at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
    == APP ==    at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
    == APP ==    at Microsoft.Extensions.Hosting.HostBuilder.BuildAppConfiguration()
    == APP ==    at Microsoft.Extensions.Hosting.HostBuilder.Build()
    == APP ==    at FrontEnd.Program.Main(String[] args) in C:demo	estDaprBackEndFrontEndProgram.cs:line 20

    我们可以修改配置让其允许

    apiVersion: dapr.io/v1alpha1
    kind: Configuration
    metadata:
      name: daprConfig
    spec:
      tracing:
        samplingRate: "1"
        zipkin:
          endpointAddress: http://localhost:9411/api/v2/spans
      secrets:
        scopes:
          - storeName: secrets01
            defaultAccess: deny
            allowedSecrets: ["RabbitMQConnectStr"]

    重启Frontend成功

    以下表格列出了所有可能的访问权限配置

    ScenariosdefaultAccessallowedSecretsdeniedSecretspermission
    1 - Only default access deny/allow empty empty deny/allow
    2 - Default deny with allowed list deny [“s1”] empty only “s1” can be accessed
    3 - Default allow with deneied list allow empty [“s1”] only “s1” cannot be accessed
    4 - Default allow with allowed list allow [“s1”] empty only “s1” can be accessed
    5 - Default deny with denied list deny empty [“s1”] deny
    6 - Default deny/allow with both lists deny/allow [“s1”] [“s2”] only “s1” can be accessed
  • 相关阅读:
    游记-HNOI2019
    题解-COCI2015Norma
    题解-Codeforces671D Roads in Yusland
    题解-POI2014 Supercomputer
    笔记-莫队的强制在线
    题解-HAOI2018全套
    题解-UOJ455 雪灾与外卖
    题解-Codeforces917D Stranger Trees
    题解-AtCoder Code-Festival2017 Final-J Tree MST
    Linux 配置svn
  • 原文地址:https://www.cnblogs.com/chenyishi/p/15346590.html
Copyright © 2011-2022 走看看