aws-lambda - Okta JWT 令牌解码问题
问题描述
我正在使用 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
从 CloudWatch 日志中的 okta 验证程序库调用func 时,我可以看到它抛出以下错误: token is not valid: the tokens header does not appear to be a base64 encoded string
. 在库中,这发生在这一步和这一步。
我还在使用 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 上解码工作正常。这似乎是一个库问题。
解决方案
所以看起来event.AuthorizationToken
来自授权处理程序的 没有解析Bearer
出来并且正在搞乱解码。
bearerToken := event.AuthorizationToken
token := strings.Replace(bearerToken, "Bearer ", "", -1)
_, err := utils.VerifyAccessToken(token)
推荐阅读
- r - GROUP BY ... 在 dbplyr 中有
- java - 我在我的 android 项目中出现错误,并显示其他四个错误?
- laravel - 在laravel中检索日期之间的数据
- python - 如何爬取IMDB?[阅读更多] 按钮未按下
- python - ModuleNotFoundError:没有名为“intersys.pythonbind31”的模块
- kubernetes - 谷歌 Kubernetes 引擎节点空闲超时
- bash - 为什么每次重启都需要更新系统变量?
- .net - 无法创建虚拟目录。找不到 Web 服务器“http://localhost/foo”
- python - 如何在sklearn的isolationforest中使用文档向量
- php - 如何更改日期格式,同时在codeigniter中的数据库php myadmin中导入excel ..?