Get 400 with message unknown_error for any POST to Keycloak REST Api - keycloak

I want, for example, create a new client with admin user using admin-cli client.
The token generation works fine:
POST /auth/realms/master/protocol/openid-connect/token
b'username=admin&password=admin&grant_type=password&client_id=admin-cli'
Using that token I can also do some queries like when I need to get id of a client:
GET /auth/admin/realms/master/clients?clientId=my-test-cli
H' Authorization: Bearer xyz
H' Content-Type: application/json
However, when I want to create a new client-role or a new client I always get 400 error. I changed the log level to DEBUG in the Keycloak server but there is nothing useful there other than seeing logs that says the token successfully created.
POST /auth/admin/realms/master/clients/7534ac42-fe8b-4cde-b6c6-c385f4958e3b/roles
400 {"error":"unknown_error"}
I am using Python v3.x and Keycloak v14.0.0 running with JBoss Wildfly container.
Looking at admin user, it seems it has all the roles like admin, default-roles-master, create-realm and I don't see any role in the listings to assign because it seems it has it all. The same for the admin-cli client. The configuration of these two (admin user and admin-cli) are the default configuration that you start the server for the first time.
Do I need anything extra like creating a new role or something in order to get this working?
My payload to create a confidential client:
payload = {
"name": "Some Name",
"clientId": "some-name",
"secret": "some-name-secret",
"enabled": true,
"publicClient": false,
"authorizationServicesEnabled": true,
"redirectUris" : ["/*"]
}

I want to answer my question so that everyone with similar situation won't face the same issue.
Turned out that the payload that I was sending was not correct, thanks to #JanGaraj who pointed that out. But what I want to answer here is that how to find out what should the request body look like.
First, do not look at the documentation. In the documentation all the fields are optional and URLs are not correct either.
The simplest way is to start Keycloak server locally and log into the admin console in Firefox or Chrome, then press F12 to open Development Mode. Then you can see all the requests/responses in there.
For example, if you want to see how to update a role, go to Roles menu item on the main menu and select a role and update it. You can see PUT request with its body. That tells you what you need to pass in and to what URL.
As a hint, you don't need to pass everything when updating, normally only IDs and the fields that you want to update are enough.

Related

What is the workflow for a basic Auth OIDC with Keycloak

I have keycloak on docker (v20.0.2) and as you know some versions change some or good part of the UI, so is hard to follow tutorials around the web...
I am trying to follow this particular tuto
https://developers.redhat.com/blog/2020/11/24/authentication-and-authorization-using-the-keycloak-rest-api#keycloak_sso_demo
that seems the more updated. My keycloak is actually behind traeffic and thomseddon/traeffic-fordward-auth with a docker-compose file (but the connection through traeffic is good and I have acces to admin UI)
So on step 10 of the tutorial things change for me, I have to look for that particular view inside:
Click on lateral menu Client Scope
Click on button Create client scope
Give a name to the scope, and click on Tab Mapper
All mappers are predefined... so there is no "New mapper" don't understand this bit
then just follow the tuto
With that series of steps I get an error when retriving the token...
https://keycloak:8443/realms/education/protocol/openid-connect/token
enter image description here
(this are fake local data from the realm I created for testing)
that responds with a or something similar I have also tried to change the grant_type to password, and the same happens can not query the token....
{
"error": "invalid_client",
"error_description": "Invalid client or Invalid client credentials"
}
But if I do not link a user with an scope/role as in the tuto suggest then I get the token, but of course I want to use the role or scope to limit who can see which endpoint and who can not
Any step that I'm missing from this update, do you have the same error?
Thank you in advance
I have tried to run it with different combinations of options to see if there is a toggle that actually allows me to fetch the token
Also with different types of grant_type
I will build an API in Python (I don't know Java and prefer Json instead of XML) that connect to this keycloak to allow users or not based on their scope/role/permission or something
I need to be able to block user so if user Student try to access an url from another Student he get blocked that url. So is based on the role or scope or I don't know which is prefered or easer to accomplish, the mission is to block users or not based on a factor that could be used for this in keycloak.

flask-jwt-extended - Catch raise RevokedTokenError('Token has been revoked')

I already tried reading the documents as well try out the changing default behaviors https://flask-jwt-extended.readthedocs.io/en/latest/changing_default_behavior.html to handle the error (the link shows how to handle expired token) and search around in google everything in every keyword combination i could do but seems no one has example about this.
I tried using #jwt.revoked_token_loader to handle the RevokedTokenError but it seems it doesn't work as I applied it like this
#jwt.revoked_token_loader
def revoked_token_response(revoked_token):
jwtkn = revoked_token['jti']
return jsonsify({
'msg': 'token {} already been revoked!'.format(jwtkn)
)}, 401
actually, i don't know exactly how does the example on the link to handle expired tokens had parameter of 'expired_token', is that self-declaration like what I did above on the 'revoked_token'?? as far as I know, 'jti' is like a default value in the flask-jwt-extended package as I see error whenever I don't use this (in my db, it is different but there is no problem at all.
I tried following this tutorial and it works out fine on my side (as well his original code source) but I see that this one doesn't have a catch exception also on Revoke Tokens https://codeburst.io/jwt-authorization-in-flask-c63c1acf4eeb
I use postman and if based on the tutorial link, here's how i get this
i do login
i use the access token generated to access protected routes ('/secrets')
i do logout
i use again the access token generated to access protected routes
after the last one, i get this error on my server side (ide):
....flask_jwt_extended\utils.py", line 216, in verify_token_not_blacklisted
raise RevokedTokenError('Token has been revoked')
flask_jwt_extended.exceptions.RevokedTokenError: Token has been revoked
127.0.0.1 -- [02/Jul/2019 22:25:26] "GET /secrets HTTP/1.1" 500 -
in postman, this is what I get:
{
'message': 'Internal Server Error'
}
my target is to send out a custom json response instead of 'Internal Server Error'
edit:
I am no wiz on programming or such, a beginner that wanted to practice out python about secured web development. I don't yet quite understand still how decorator works out in terms of application, etc. so i don't know if others tweaks out the flask-jwt-extended package to work such things out.
Getting back a 500 error normally occurs because of a bug in other flask extensions and how that interact with native flask errorhandlers. You can find a bunch of discussions about it here (https://github.com/vimalloc/flask-jwt-extended/issues/86), but the tl;dr version is you might need to set app.config['PROPAGATE_EXCEPTIONS'] = True if using something like Flask-Restul, or use a hack like this if using flask-restplus:
jwt = JWTManager(app)
api = Api()
jwt._set_error_handler_callbacks(api)
If those don't help you, please take a look through that linked github issue, and if nothing in there helps make a reply in that issue detailing your setup.
Cheers.

How To Programmatically Check Tumblr Username Availability?

is there any way to check for username availability for tumblr? i want to check if a username is available to register on tumblr.
I tried checking HTTP response of urls like username.tumblr.com but the one that returns 404 are still not available for registration. Any idea?
Thanks!
This is the closest I got:
curl 'https://www.tumblr.com/svc/account/register' --data 'user%5Bemail%5D=x#apple.com&tumblelog%5Bname%5D=USERNAMETOCHECK&form_key=!1231473848212%7CKpTkShMIsrNRL3V1GPCfNlpw6V8&action=signup_account'
BUT:
It's not a public API so your IP might be blocked or it might just stop working without notice.
the form_key parameter might expire after a little while; you should be able to parse that from https://www.tumblr.com/ to get a new one.
Notes:
I found this request from the registration screen in Chrome's developer tool, "copied it as CURL", and removed everything that wasn't necessary.
x#apple.com is just the shortest non-used email address I could think of.
The response will be something like:
{
"redirect": false,
"redirect_method": "GET",
"errors": [
"Someone beat you to that username.",
"You forgot to enter your password!"
],
"signup_success": false,
"next_view": false,
"usernames": [
"..."
]
}
If Someone beat you to that username. is present in the errors, then the username is taken.
Your alternative is using one of the many services and APIs that probably do the same thing.

Facebook Login using scribe

I'm using scribe to get user id, however I get this error:
OAuthConnectionException: There was a problem while creating a connection to the remote service.
I follow this example enhanced with javax filters (to get the parameter code correctly)
https://github.com/fernandezpablo85/scribe-java/blob/master/src/test/java/org/scribe/examples/FacebookExample.java
I also tried doing things manually and i got the access token which looks somehow like this ( i changed it a bit ) CAAHZCFE7YllgBAAZAenKbvZBrMZAZBkDGgydU2vAekwsM1V0StpZAgHXukEYWIDSpc5ZCXc4LB6suFeaPagcpj2ju6ayvAgrxYttvCQg9i7ZAdcF2ZCvhMNqTddsDUkNq1c1cX47U9KwutS5t6xpbV0cRabaVpgZCZAo4ZCTEtgckFmMajsb3zYWTH9LEfKj3CgcJ39lD2x1yRoXyAds0lKARmHZC
and while asking for user id like this:
https://graph.facebook.com/me?access_token=CAAHZCFE7YllgBAAZAenKbvZBrMZAZBkDGgydU2vAekwsM1V0StpZAgHXukEYWIDSpc5ZCXc4LB6suFeaPagcsj2ju6aYvYgrxYttvCQg9i7ZAdcF2ZCvhMNqTddsDUkNq1c1cX47U9KwutS5t6xpbV0cRabaVpgZCZAo4ZCTEtgckFmMajsb3zYWTH7LEfKj3CycJ39lD2x1yRoXyAds0lWLRmHZC%20,%20458856e03b909f426ec5d3791f0af466?fields=id,name
I get Malformed access token.
Do you have any suggestions regarding what I am doing wrong?
The URLs are the same, dunno what my mistake is :/

GitHub OAuth in lua

I am working on a library in LUA for an ipad app called Codea. I'm trying to figure out to use OAuth for GitHub Gists. Only part that i can not figure out is how to get an Auth token via code. I used curl in terminal to get myself a token but this seems to be to much work for other users.
I've read through the github api docs multiple times but I cant figure out how to get a Token programmatically. I've tried to duplicate the method I've used to GET and POST gists but it does not seem to work. I'm not sure how to pass the username and password.
I'm creating a table with the needed params then encoding it in json. Everything I try gets a 404 error or 500 error. Thank you all in advance.
local url = "https://api.github.com/authorizations"
local d = {}
d.scopes = {"gist"}
d.note = "AutoGist Codea"
projectAuth = json.encode(d)
opts = { data = projectAuth }
opts.method = "POST"
opts.headers = {Authorization = "basic " .."username:password"}
http.request(url,successCallback,failedCallback,opts)
Scopes are coming, but only in Q4 2013.
See "OAuth changes coming" (October 2013, by Tim Cleam - tclem):
Starting today, we are returning granted scopes as part of the access_token response.
For example, if you are making a POST with the application/json mime-type you’ll see an additional field for the granted scopes.
{
"access_token":"e72e16c7e42f292c6912e7710c838347ae178b4a",
"scope":"repo,gist",
"token_type":"bearer"
}
Right now, these scopes will be identical to what you requested, but we are moving towards a feature set that will allow GitHub users to edit their scopes, effectively granting your application less access than you originally requested.
You should be aware of this possibility and adjust your application behavior accordingly.
Some things to watch out for and keep in mind:
Most third party applications using GitHub OAuth to identify users have the best success in adoption by starting out with a request for the minimum access that the application can possibly get away with.
Something like no scopes or just user:email is very sane.
It is important to handle the error cases where a users chooses to grant you less access than you originally requested.
Now that we are surfacing the granted scopes on the access_token response, applications can warn or otherwise communicate with their users that they will see reduced functionality or be unable to perform some actions.
Applications can always send users back through the flow again to get additional permission, but don’t forget that users can always say no.