Go中的Azure JWT验证不起作用



我有一个Go HTTP服务器。我想用Azure JWT令牌保护我的路由。我能够生成令牌,但我无法验证它。

我是这样做的:

package main
import (
"context"
"errors"
"fmt"
"github.com/dgrijalva/jwt-go"
"github.com/lestrrat-go/jwx/jwa"
"github.com/lestrrat-go/jwx/jwk"
njwt "github.com/lestrrat-go/jwx/jwt"
)
const token = "<access-token>"
const jwksURL = `https://login.microsoftonline.com/common/discovery/keys`
func main() {
set, _ := jwk.Fetch(context.TODO(), jwksURL)
// verified that set has required kid 
verify2(token, set)
token, err := verify(token, set)
// token, err := jwt.Parse(token, getKey)
if err != nil {
panic(err)
}
claims := token.Claims.(jwt.MapClaims)
for key, value := range claims {
fmt.Printf("%st%vn", key, value)
}
}
func verify2(token string, keyset jwk.Set) {
btoken := []byte(token)
parsedToken, err := njwt.Parse(
btoken, //token is a []byte
njwt.WithKeySet(keyset),
njwt.WithValidate(true),
)
fmt.Printf("%v %v", parsedToken, err)
}
func verify(tokenString string, keySet jwk.Set) (*jwt.Token, error) {
tkn, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if token.Method.Alg() != jwa.RS256.String() {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
kid, ok := token.Header["kid"].(string)
if !ok {
return nil, errors.New("kid header not found")
}
keys, ok := keySet.LookupKeyID(kid)
if !ok {
return nil, fmt.Errorf("key %v not found", kid)
}
var raw interface{}
err := keys.Raw(&raw)
return raw, err
})
return tkn, err
}

verify2(..)给出<nil> failed to match any of the keysverify(..)得到crypto/rsa: verification error

my JWT header:

{
"typ": "JWT",
"nonce": "...",
"alg": "RS256",
"x5t": "-KI3Q9nNR7bRofxmeZoXqbHZGew",
"kid": "-KI3Q9nNR7bRofxmeZoXqbHZGew"
}

您正在使用错误类型的Azure AD访问令牌。那些在JWT头中带有nonce的代码并不是为了让你自己的api验证而设计的——它们是为微软自己的api设计的。

您需要公开一个API作用域来修复这个问题,之后您将在JWT头中获得一个没有nonce的访问令牌。我的博客文章有一些进一步的相关信息。

我在另一种语言中有类似的问题。我的手动令牌验证适用于某些令牌。这引起了我的注意,当我有"疼痛"的时候;在JWT标头上声明,验证失败,对于其他令牌,当我没有它时,它可以工作。请您用另一个代币查询一下没有"nonce_"字样的地方好吗?(只是为了缩小问题范围)

任何时候我们添加一个作用域来访问微软图形API。Azure返回一个access_token,它只能由Microsoft graph API验证。

替代方法1:

  • 签署我自己的JWT以授权后端
  • 中的前端请求
  • access_token存储在某处

替代方法2:

  • 调用图形API并使用声明签署JWT
  • 在FE和BE之间验证并使用JWT

注意:不要在声明中存储敏感信息

微软的OAuth令牌所有者对此发表评论:https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/609#issuecomment-524434987

了解Azure OIDC的更多信息:https://xsreality.medium.com/making-azure-ad-oidc-compliant-5734b70c43ff

相关内容

  • 没有找到相关文章

最新更新