【问题标题】:Authentication methods using the vault API package使用 Vault API 包的身份验证方法
【发布时间】:2017-07-19 20:15:24
【问题描述】:

我正在尝试使用Vault Golang Package 使用 API 进行身份验证。

我创建了一个新客户端,然后可以设置我的令牌:

client, err := api.NewClient(&api.Config{Address: vaultAddr, HttpClient: httpClient})

 if err != nil {
   return nil, errors.Wrap(err, "could not create vault client")
 }

client.SetToken(token)

这很好,但我想使用其他身份验证方法之一(LDAP、Userpass 等)针对 API 进行身份验证

这甚至可能吗?如何使用 API 检索令牌?

我想我可以使用 net/http 通过 API 调用来检索令牌,但是有没有其他方法可以通过其他方式实际进行身份验证?

【问题讨论】:

    标签: go hashicorp-vault


    【解决方案1】:

    最终,我设法弄清楚了这一点。这不是很明显,但很有意义。

    保险柜有一个generic write method 用于写入数据。您可以利用它通过简单地构建 URL 并向该端点发送 PUT 请求来使用 API 执行登录

    看起来有点像这样:

    // create a vault client
    client, err := api.NewClient(&api.Config{Address: url, HttpClient: httpClient})
    if err != nil {
        panic(err)
    }
    
    // to pass the password
    options := map[string]interface{}{
       "password": password,        
    }
    
    // the login path
    // this is configurable, change userpass to ldap etc
    path := fmt.Sprintf("auth/userpass/login/%s", username)
    
    // PUT call to get a token
    secret, err := client.Logical().Write(path, options)
    

    【讨论】:

    【解决方案2】:

    如果没有足够的声誉,请在此处添加额外的提示,而不是对已接受的答案进行评论。可以从身份验证响应中提取令牌,如下所示:

    client.SetToken(secret.Auth.ClientToken)
    

    相关接口记录在这里:

    https://godoc.org/github.com/hashicorp/vault/api#Secret

    https://godoc.org/github.com/hashicorp/vault/api#SecretAuth

    【讨论】:

      【解决方案3】:

      我编写了一个 GitHub gist,其中包含一个使用 AWS IAM 角色对您的 Go 程序进行身份验证的函数。这里是a link

      注意:对 Vault 进行身份验证只会获得一个令牌。如果 AWS IAM 角色允许,该令牌稍后可用于读取机密。

      您需要创建一个 AWS STS 请求,从中提取一些信息,然后将其发送到 Vault。

      这是来自 GitHub gist 的函数。它将使用一个 AWS IAM 角色和一些 Vault 环境变量,例如 VAULT_ADDR。这是 Vault Golang 库可能会阅读的一些 other environment variables。它会生成经过身份验证的 Vault *api.Client、令牌和来自身份验证请求的响应。

      它基于this GitHub project

      package vault
      
      import (
          "encoding/base64"
          "encoding/json"
          "fmt"
          "io/ioutil"
      
          "github.com/aws/aws-sdk-go/aws/session"
          "github.com/aws/aws-sdk-go/service/sts"
          "github.com/hashicorp/vault/api"
      )
      
      // AWSLogin will create a Vault client, login via an AWS role, and return a valid Vault token and client that can be
      // used to get secrets.
      // The authProvider is likely "aws". It's the "Path" column as described in these docs:
      // https://www.vaultproject.io/api/auth/aws#login.
      // The serverID is an optional value to be placed in the X-Vault-AWS-IAM-Server-ID header of the HTTP request.
      // The role is an AWS IAM role. It needs to be able to read secrets from Vault.
      func AWSLogin(authProvider, serverID, role string) (client *api.Client, token string, secret *api.Secret, err error) {
      
          // Create the Vault client.
          //
          // Configuration is gathered from environment variables by upstream vault package. Environment variables like
          // VAULT_ADDR and VAULT_SKIP_VERIFY are relevant. The VAULT_TOKEN environment variable shouldn't be needed.
          // https://www.vaultproject.io/docs/commands#environment-variables
          if client, err = api.NewClient(nil); err != nil {
              return nil, "", nil, fmt.Errorf("failed to create Vault client: %w", err)
          }
      
          // Acquire an AWS session.
          var sess *session.Session
          if sess, err = session.NewSession(); err != nil {
              return nil, "", nil, fmt.Errorf("failed to create AWS session: %w", err)
          }
      
          // Create a Go structure to talk to the AWS token service.
          tokenService := sts.New(sess)
      
          // Create a request to the token service that will ask for the current host's identity.
          request, _ := tokenService.GetCallerIdentityRequest(&sts.GetCallerIdentityInput{})
      
          // Add an server ID IAM header, if present.
          if serverID != "" {
              request.HTTPRequest.Header.Add("X-Vault-AWS-IAM-Server-ID", serverID)
          }
      
          // Sign the request to the AWS token service.
          if err = request.Sign(); err != nil {
              return nil, "", nil, fmt.Errorf("failed to sign AWS identity request: %w", err)
          }
      
          // JSON marshal the headers.
          var headers []byte
          if headers, err = json.Marshal(request.HTTPRequest.Header); err != nil {
              return nil, "", nil, fmt.Errorf("failed to JSON marshal HTTP headers for AWS identity request: %w", err)
          }
      
          // Read the body of the request.
          var body []byte
          if body, err = ioutil.ReadAll(request.HTTPRequest.Body); err != nil {
              return nil, "", nil, fmt.Errorf("failed to JSON marshal HTTP body for AWS identity request: %w", err)
          }
      
          // Create the data to write to Vault.
          data := make(map[string]interface{})
          data["iam_http_request_method"] = request.HTTPRequest.Method
          data["iam_request_url"] = base64.StdEncoding.EncodeToString([]byte(request.HTTPRequest.URL.String()))
          data["iam_request_headers"] = base64.StdEncoding.EncodeToString(headers)
          data["iam_request_body"] = base64.StdEncoding.EncodeToString(body)
          data["role"] = role
      
          // Create the path to write to for Vault.
          //
          // The authProvider is the value referenced in the "Path" column in this documentation. It's likely "aws".
          // https://www.vaultproject.io/api/auth/aws#login
          path := fmt.Sprintf("auth/%s/login", authProvider)
      
          // Write the AWS token service request to Vault.
          if secret, err = client.Logical().Write(path, data); err != nil {
              return nil, "", nil, fmt.Errorf("failed to write data to Vault to get token: %w", err)
          }
          if secret == nil {
              return nil, "", nil, fmt.Errorf("failed to get token from Vault: %w", ErrSecret)
          }
      
          // Get the Vault token from the response.
          if token, err = secret.TokenID(); err != nil {
              return nil, "", nil, fmt.Errorf("failed to get token from Vault response: %w", err)
          }
      
          // Set the token for the client as the one it just received.
          client.SetToken(token)
      
          return client, token, secret, nil
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-08-11
        • 1970-01-01
        • 1970-01-01
        • 2021-06-24
        • 2015-08-18
        • 2015-11-03
        • 2020-05-17
        • 1970-01-01
        相关资源
        最近更新 更多