Проблема декодирования токенов Okta JWT - PullRequest
1 голос
/ 28 сентября 2019

Я внедряю собственный авторизатор для AWS API Gateway, используя Okta okta-jwt-verifier-golang.

Мой serverless.yml выглядит так ...

functions:
  myfunc:
    handler: bin/myfunc
    events:
      - http:
          path: myfunc
          method: post
          authorizer: app-auth
          cors: true
  app-auth:
    handler: bin/auth/app

Мой авторизатор выглядит так...

# app-auth/main.go
package main

import (
    "context"
    "errors"
    "fmt"

    "myapi/utils"
    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
)

func Handler(ctx context.Context, event events.APIGatewayCustomAuthorizerRequest) (events.APIGatewayCustomAuthorizerResponse, error) {
    bearerToken := event.AuthorizationToken
    fmt.Println("Token:" + bearerToken)

    _, err := utils.VerifyAccessToken(bearerToken)

    fmt.Println("error:" + err.Error())
    if err != nil {
        fmt.Println("error not null")
        return events.APIGatewayCustomAuthorizerResponse{}, errors.New("Unauthorized")
    }

    return utils.GeneratePolicy("user", "Allow", event.MethodArn), nil
}

func main() {
    lambda.Start(Handler)
}
# utils/okta.go
package utils

import (
    "os"
    "fmt"
    verifier "github.com/okta/okta-jwt-verifier-golang"
)


func VerifyAccessToken(bearerToken string) (*verifier.Jwt, error) {
    tv := map[string]string{}
    tv["aud"] = "api://default"
    tv["cid"] = os.Getenv("CLIENT_ID")
    jv := verifier.JwtVerifier{
        Issuer:           os.Getenv("ISSUER"),
        ClaimsToValidate: tv,
    }
    jv.SetLeeway(60) //seconds
    fmt.Println("")
    return jv.New().VerifyAccessToken(bearerToken)
}

При вызове функции VerifyAccessToken из lib верификатора okta в журналах CloudWatch я вижу, что она выдает следующую ошибку: token is not valid: the tokens header does not appear to be a base64 encoded string.В lib это происходит в на этом шаге и на этом шаге .

Я также использую стартер приложения Okta React и отправляю сообщения на мою конечную точку с помощью accessToken.

try {
      const urlParams = decode(window.location.search.substr(1));
      const user = await this.props.auth.getUser()
      /* global fetch */
      const payload = {
        ...urlParams,
        user_id: user.sub
      }
      const response = await fetch(config.resourceServer.messagesUrl + "/v1/myfunc", {
        method: "POST",
        body: JSON.stringify(payload),
        // credentials: 'include',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${ await this.props.auth.getAccessToken() }`,
        },
      });

На клиенте я получаю правильные 401 из-за этой ошибки, но, хотя cors: true и мои конечные точки устанавливаются "Access-Control-Allow-Origin": "*", я получаю следующую ошибку клиента.

Access to fetch at 'https://myhost.com/v1/myfunc' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Я полагаю, что эта проблема будет решена, когда проблема с декодированием будет устранена.

Я пытался декодировать его сам, и на самом деле, похоже, он не декодируется правильно, поэтому токен может быть закодирован неправильно?Может, клиентское приложение что-то делает не так?Я проверил это и внимательно следил за документами, но не могу решить это самостоятельно.

Любые советы?

Обновление 1: похоже, что токен состоит из 3 частей.Часть 1 - заголовок, который выбрасывает ошибку декодирования.Весь токен должным образом декодируется с использованием https://www.jsonwebtoken.io/, так же как и часть заголовка независимо.Во время этого шага может возникнуть проблема с кодом библиотеки:

parts := strings.Split(jwt, ".")
    header := parts[0]
    header = padHeader(header)
    headerDecoded, err := base64.StdEncoding.DecodeString(header)

    if err != nil {
        return false, fmt.Errorf("the tokens header does not appear to be a base64 encoded string")
    }

Обновление 2: поэтому base64.StdEncoding.DecodeString создает следующую ошибку illegal base64 data at input byte 88.Тем не менее, декодирование на jsonwebtoken.io работает нормально.Кажется, это проблема lib .

...