生成承载令牌时签名无效

时间:2019-03-21 01:09:42

标签: azure asp.net-core oauth-2.0 azure-active-directory access-token

我是OAuth的新手,我使用了this教程来生成从客户端应用到目标应用的访问令牌。代码本身可以正常工作,但是在https://jwt.io/

上解码时,我生成的访问令牌具有invalid signature

这是教程中的代码

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. 为什么签名无效?

enter image description here

3 个答案:

答案 0 :(得分:4)

我尝试了与您相同的代码,但情况相同invalid signature,但是当我将jwt ALGORITHM更改为 HS256 时,我得到了Signature Verified

enter image description here

签名:

enter image description here

RRS256和HS256的区别:

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

另一方面,

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

  
    

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

  

您正在使用OAuth2.0,loadGoogleClient = () => { gapi.load("client:auth2", () => { gapi.auth2.init({ 'client_id': my-client-id, 'apiKey': my-key, 'scope': "https://www.googleapis.com/auth/drive.readonly", 'discoveryDocs': ['https://content.googleapis.com/discovery/v1/apis/drive/v3/rest'] }) // Listen for sign-in state changes. console.log(`User is signed in: ${gapi.auth2.getAuthInstance().isSignedIn.get()}`); gapi.client.load("https://content.googleapis.com/discovery/v1/apis/drive/v3/rest") .then(() => { console.log("GAPI client loaded for API"); }, (error) => { console.error("Error loading GAPI client for API", error); }); console.log('Init should have worked'); }); } 表示JWT令牌是由Azure AD V1.0端点发行的。

  
    

为什么签名无效?

  

API需要检查JWT标头(属性alg)指定的算法是否与API期望的算法匹配。 AAD使用authGoogle = () => { gapi.auth2.getAuthInstance() .signIn({scope: "https://www.googleapis.com/auth/drive.readonly"}) .then(function() { console.log("Sign-in successful"); }, function(err) { console.error("Error signing in", err); }); } ,因此您应更改为ver:"1.0"

enter image description here

通常的方法是从模和指数构建,从RS256匹配的kid和令牌中的x5t中找到它们。任何使用https://play.golang.org/之类的在线工具来获取公钥都由两个部分组成:n和e。您还可以使用RS256值,单击here进行采样。

相关问题