生成不记名令牌时签名无效

Invalid Signature when generate bearer token

我是 OAuth 新手,我用过 this tutorial to generate access token from client app to target app. The code itself is working fine, but the access token I generated has invalid signature when I decoded on https://jwt.io/

这是教程中的代码

public class ServicePrincipal
    {
        /// <summary>
        /// The variables below are standard Azure AD terms from our various samples
        /// We set these in the Azure Portal for this app for security and to make it easy to change (you can reuse this code in other apps this way)
        /// You can name each of these what you want as long as you keep all of this straight
        /// </summary>
        static string authority = "";  // the AD Authority used for login.  For example: https://login.microsoftonline.com/myadnamehere.onmicrosoft.com 
        static string clientId = ""; // client app's client id
        static string clientSecret = ""; // client app's secret key
        static string resource = ""; // target app's App ID URL

        /// <summary>
        /// wrapper that passes the above variables
        /// </summary>
        /// <returns></returns>
        static public async Task<AuthenticationResult> GetS2SAccessTokenForProdMSAAsync()
        {
            return await GetS2SAccessToken(authority, resource, clientId, clientSecret);
        }

        static async Task<AuthenticationResult> GetS2SAccessToken(string authority, string resource, string clientId, string clientSecret)
        {
            var clientCredential = new ClientCredential(clientId, clientSecret);
            AuthenticationContext context = new AuthenticationContext(authority, false);
            AuthenticationResult authenticationResult = await context.AcquireTokenAsync(
                resource,  // the resource (app) we are going to access with the token
                clientCredential);  // the client credentials
            return authenticationResult;
        }
    }

我发现还有一段代码也可以生成访问令牌:

     AuthenticationContext authenticationContext =
   new AuthenticationContext({authority});

        ClientCredential clientCredential = new ClientCredential({client app id}, {client app secret});
        try
        {
            AuthenticationResult result =
              await authenticationContext.AcquireTokenAsync({target app's App ID URL},
                                                                clientCredential);
        }
        catch (Exception e)
        {
            return false;
        }

这两个代码都给了我无效的 1.0 版签名访问令牌

这里有两个问题:

  1. 我注意到当我解码访问令牌时,它显示 "ver": "1.0"。这是否意味着它正在使用 OAuth1.0?因为我想使用 OAuth 2.0.. 为什么代码会生成创建 OAuth1.0 而不是 OAuth2.0 的令牌?

  2. 为什么会是无效签名?

您是否将密钥发布到 jwt.io 的表单中?尝试使用授权中的令牌进行真正的休息调用 header。如果一切正常而 jwt 不正常,也许就在他们身上。

I noticed is that when I decode the access token, it shows "ver": "1.0". Does it mean it is using OAuth1.0? Because I suppose to use OAuth 2.0.. Why would the code generate token that create OAuth1.0 not OAuth2.0?

您使用的是 OAuth2.0,ver:"1.0" 表示 JWT 令牌由 Azure AD V1.0 Endpoint 颁发。

Why would it be invalid signature?

API 需要检查 JWT header (属性 alg) 指定的算法是否与 API 期望的算法相匹配。 AAD 使用 RS256 ,所以你应该改为 RS256:

通常的方法是从模数和指数构建,从 https://login.microsoftonline.com/common/discovery/keys 匹配 kid 和 x5t 从令牌中找到它们。任何使用在线工具,例如 https://play.golang.org/ to get public key consists of two components: n and e. You can also use x5c value , click here 的示例。

我尝试了与你相同的代码,遇到了同样的情况 invalid signature,但是当我将 jwt 算法更改为 HS256 时,我得到了 Signature Verified.

以及签名:

以及RRS256和HS256的区别:

RS256(使用 SHA-256 的 RSA 签名)是一种非对称算法,它使用 public/private 密钥对:身份提供者有一个私有(秘密)用于生成签名的密钥,JWT 的消费者获得一个 public 密钥来验证签名。由于 public 密钥(与私钥相反)不需要保持安全,因此大多数身份提供者都可以让消费者轻松获取和使用它(通常通过元数据 URL)。

另一方面,

HS256(带 SHA-256 的 HMAC)是一种对称算法,只有一个(秘密)密钥在双方之间共享。由于同一密钥用于生成签名和验证签名,因此必须小心确保密钥不被泄露。