Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keycloak API always returns 401

I'm trying to interact with Keycloak via its REST API. I have the master realm and the default admin user, and a test realm. Firstly, I get an access token for the admin account and test realm:

let data = {
    grant_type : 'password',
    client_id : 'test-realm',
    username : 'admin',
    password : 'admin'
};
let headers = {
    'Content-Type': 'application/x-www-form-urlencoded'
};
axios.post(
    'https://someurl.com:8080/auth/realms/master/protocol/openid-connect/token',
    qs.stringify(data),
    headers
)

That works ok. Then I try to make a call to create a user (or do anything else) and I get a 401 unauthorized error:

headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': `Bearer ${accessToken}`
};
data = {
    rep: {
        email: "[email protected]",
        username: "[email protected]"
    },
    path: 'test-realm'
};
axios.post('https://someurl.com:8080/auth/admin/realms/test-realm/users',
    qs.stringify(data),
    headers
)

Is that not the correct way to include the token? Is the access token the one you use for authenticating other API calls? Shouldn't the admin account's token work for authenticating calls to other clients with the master realm? Would it be some setting in the master realm that I have to change in the admin console? Any help appreciated.

like image 842
Jayce444 Avatar asked Oct 23 '17 05:10

Jayce444


4 Answers

I fixed it by enabling the below "Service Accounts Enabled" button under Settings for admin-cli

enter image description here

like image 97
jalaj Avatar answered Nov 15 '22 05:11

jalaj


I got a 401 error because I generated the offline token by using http://localhost:8080 and then I tried to request the api by using http://keycloak:8080 which is not allowed. Unfortunately the log doesn't tell you that.

To debug JWT tokens I recommend https://jwt.io/

like image 28
Tobias Ernst Avatar answered Nov 15 '22 05:11

Tobias Ernst


Is that not the correct way to include the token?

This is a correct way.

You just do something incorrectly. Please, refer for an example from keycloak-request-token Node.js module:

https://github.com/keycloak/keycloak-request-token/blob/master/index.js#L43

You use

client_id : 'test-realm'

but there is

client_id: 'admin-cli' 

there.

Also, to create a user, you should use

'Content-Type': 'application/json'

You can refer for Node.js examples of Keycloak REST API here:

https://github.com/v-ladynev/keycloak-nodejs-example/blob/master/lib/adminClient.js

Examples of other useful stuff like:

  • custom login
  • storing Keycloak token in the cookies
  • centralized permission middleware

can be found in the same project: keycloak-nodejs-example

like image 9
v.ladynev Avatar answered Nov 15 '22 06:11

v.ladynev


I had this issue and solved it by making sure that there is no more than 1 minute between the first and the second API request. So, if you are doing this manually (2 curl requests), the token may expire and you may get error 401. Nevertheless, you should use admin-cli as mentioned above.

like image 2
Maan Haj Rachid Avatar answered Nov 15 '22 06:11

Maan Haj Rachid