Auth0 Home Blog Docs

401 when querying /userinfo with correct scope and RS256

api
userinfo
java
openid
unauthorized

#1

I’m querying the userinfo via the java authAPI with the following token

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik5rSkNOa000TVRJeU5EY3hNamt4TWpjMlF6WTVSVUU1T0VVM01VWTJSa1V5TnpjMk5qUTRPUSJ9.eyJpc3MiOiJodHRwczovL21lbmluc3VpdHMuZXUuYXV0aDAuY29tLyIsInN1YiI6Im14ZjBNMTdnZnRKY0xLcXVkRlFUcE1yM093c0lOcEVzQGNsaWVudHMiLCJhdWQiOiJodHRwczovL2hhc2gubmV0YmxvZ2dlci5tZS8iLCJleHAiOjE1MDY0MjUwODUsImlhdCI6MTUwNjMzODY4NSwic2NvcGUiOiJwcm9maWxlIG9wZW5pZCByZWFkOmdyZWV0aW5nIn0.BWWDDkWf4TSKD_-FcO58V-Tvqjd84Tz7SFgvUOLFq8xiS6jcBuO4iiObcT6kmOw-q3eyv-pT09J0mRb13khGWjplX3IGijPC1n_SOV_J1uN7AaZzM4D0nfO2IzstFzw0t0fKdvEAvURadGjLy77bSlBLRuj1dD_ztIB6f4mqkyyuTTM-JWJLMLJyn3UFKtn8CsVEcSpyBdHVL1RzfvLfa_LysjPCQNsBJUP8JfIJ3G-A26i0PkUyy_zTCR4v74IElHTvP1PS2YbUc0RLyqTT9ptdXqv-szgI3xBXBDJLSG7dghaSuhYpdzvMTX_NmzMRZ-w8qibNy4Q7ABQ0bmT7PQ

[EDIT] This token was generated using the following:

curl --request POST \
  --url https://meninsuits.eu.auth0.com/oauth/token \
  --header 'content-type: application/json' \
  --data '{"client_id":"xxx","client_secret":"xxx","audience":"https://hash.netblogger.me/","grant_type":"client_credentials"}'

This might not be the correct token to use, it seems this is only for server to server, think the correct way to do this is to actually generate the token on the front end and extract it and send it to the back end?


The Java code is as follows:

private AuthAPI auth = new AuthAPI("https://meninsuits.eu.auth0.com", "xx", "xx");
    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping("/secure/greeting")
    public Greeting secretGreeting(@RequestHeader("authorization") String authToken, @RequestParam(value="name", defaultValue="User") String name) {
        String token = authToken.substring(authToken.indexOf(" ")+1);
        Request<UserInfo> request = auth.userInfo(token);
        try {
            UserInfo info = request.execute();
        } catch (APIException exception) {
            System.out.println("API");
        } catch (Auth0Exception exception) {
            System.out.println("Auth");
        }
        return new Greeting(counter.incrementAndGet(),
                String.format(template, name));
    }

The thing is even when calling /userinfo directly in postman I still get 401 so it seems its not related to the java code itself, The client is a test client (non-interactive) as I’m using spring as a backend API but I don’t see why this would make a difference. It seems like I’m missing something config wise but not really sure what, I’ve dug through all the docs and been directed to this page several times: https://community.auth0.com/questions/516/httpsuserinfo-returns-401-unauthorized


#2

For the token you provided (side note: if I did the math right when you included the token in the question it was already expired, but as a general rule it’s best to remove/redact the signature part so that in this way you are sure you share a token only really useful for troubleshooting) the 401 would be expected because the token does not contain the /userinfo audience and as such is considered invalid for that purpose.

However, for access tokens issued to your own API’s when they use RS256 it’s possible to also request that the access token is suitable for /userinfo (including the openid scope in the initial request). In this case the token uses RS256 and it does show the openid scope so at first this is suspicious. However, in order to really troubleshoot this situation having the exact parameters used to obtain such access token would simplify things a lot. If you can reproduce this situation, please include the steps and parameters used to obtain the access token as an update to your question.


Update:

As you mentioned in your update, you’re obtaining a token through the client credentials grant which is indeed not suitable for /userinfo because in this machine to machine communication flow there is no end-user associated. Your original question already mentioned that you were using a non-interactive application, but I assumed it was for doing a resource owner password credentials grant from your own back-end; in this grant there would be an end-user (the one associated with the credentials used) so the access token could be suitable for /userinfo.

The recommendation is for you to perform an end-user based flow and use the access token issued as part of that flow. You can check these docs for a quick glance at which flow to use (within the end-user based ones).


#3

@xmeninsuits thanks for providing an update; I revised my answer to consider your additional information.


#4