1

I am new to OAuth and I used 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/

Here's the code from the tutorial

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;
        }
    }

There is another piece of code I found that can also generate the access token:

     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;
        }

Both of the code gave me invalid signature access token with version 1.0

There are two issues here:

  1. 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?

  2. Why would it be invalid signature?

enter image description here

superninja
  • 3,114
  • 7
  • 30
  • 63

3 Answers3

4

I tried the same code with yours, got the same situation invalid signature, but when I changed the jwt ALGORITHM to HS256, I got the Signature Verified.

enter image description here

And the signature:

enter image description here

And the differences about RRS256 and HS256:

RS256 (RSA Signature with SHA-256) is an asymmetric algorithm, and it uses a public/private key pair: the identity provider has a private (secret) key used to generate the signature, and the consumer of the JWT gets a public key to validate the signature. Since the public key, as opposed to the private key, doesn't need to be kept secured, most identity providers make it easily available for consumers to obtain and use (usually through a metadata URL).

HS256 (HMAC with SHA-256), on the other hand, is a symmetric algorithm, with only one (secret) key that is shared between the two parties. Since the same key is used both to generate the signature and to validate it, care must be taken to ensure that the key is not compromised.

SunnySun
  • 1,900
  • 1
  • 6
  • 8
1

Are you posting your key into the form at jwt.io? Try to make a real rest call using the token in the authorization header. If everything is working and jwt isn't, maybe it's on them.

Nick Gamb
  • 86
  • 6
  • I did try to make a rest call using the access token, and it kept giving me 401 error without hitting any of my break point. So that's why i am suspecting the access token has issues. I also used https://www.jsonwebtoken.io/ to verify the token and it is giving me the same result - `Invalid - Token Signature has failed` – superninja Mar 21 '19 at 01:19
  • Do a rest call again, run fiddler or Insomnia and post the trace. Let's rule out the call first then move to token – Nick Gamb Mar 21 '19 at 01:23
  • Will do. At the mean time, i edited the question and found the decoded token shows `ver: 1.0`.. Does it mean it is giving me a token with OAuth1.0? – superninja Mar 21 '19 at 01:25
  • Yes it does. You should be using oAuth2.0 unless there is a reason to use 1. You should be using OWIN if your using .net. Follow this guide. http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/ – Nick Gamb Mar 21 '19 at 01:36
  • Im using asp.net core – superninja Mar 21 '19 at 01:36
1

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?

You are using OAuth2.0 , the ver:"1.0" means the JWT token is issued by Azure AD V1.0 Endpoint .

Why would it be invalid signature?

The API needs to check if the algorithm, as specified by the JWT header (property alg), matches the one expected by the API . AAD use RS256 , so you should change to RS256:

enter image description here

The normal way is to build from modulus and exponent , finding them from https://login.microsoftonline.com/common/discovery/keys matching kid and x5t from the token . Any use online tool like https://play.golang.org/ to get public key consists of two components: n and e. You can also use x5c value , click here for samples .

Nan Yu
  • 26,101
  • 9
  • 68
  • 148
  • @WWpana , do you put your client secret to verify signature area ? The client secret is the one used to acquire access token . The client app's client secret . – Nan Yu Mar 21 '19 at 02:26
  • Not need to put to both area , the below one is used to issue token . – Nan Yu Mar 21 '19 at 02:27
  • So to rephrase your steps: 1) Enter the access token and make sure it is `RS256` By the time I finished this step it is already showing invalid signature 2) Then enter the app secret in the public key section - nothing happened in the tool.. Am I missing any step? – superninja Mar 21 '19 at 02:46