Hi John,
Thank you for you feedback. Answers in text below.
On Fri, Dec 6, 2019 at 2:13 PM John Norris <johnnorris-10(a)outlook.com>
wrote:
Hi Michal and Tony,
I think my confusion lays in the fact that I have an adminuser which is
defined in the master realm because that was there during keycloak setup.
Then I added a working realm and working client app. And I added users to
the working realm and mapped them to a realm based role.
And I do that by logging on to keycloak via a local browser, I have to use
the admin user defined in master realm. And then I can create users in the
working realm and add them to the realm based role.
And all of that works. When I browse to a protected resource in my Spring
app, I get redirected to keycloak login and after a successful login with
an ordinary user, get sent to that resource. Success.
So I assumed the same approach would work when using the java api. Builder
object based on the admin user, saying that I would use the working realm
and the client id. Because I want those new users to be added to the
working realm, not the master realm.
But obviously this does not work because the permissions are not right,
hence the 401 error.
I see your confusion. I will quote one section from our documentation which
can help you understand how this works (sorry if you have already seen
this, it is copy&paste from here:
https://www.keycloak.org/docs/latest/server_admin/index.html#_admin_permi...
):
The master realm in Keycloak is a special realm and treated differently
than other realms. Users in the Keycloak master realm can be granted
permission to manage zero or more realms that are deployed on the Keycloak
server. When a realm is created, Keycloak automatically creates various
roles that grant fine-grain permissions to access that new realm. Access to
The Admin Console and Admin REST endpoints can be controlled by mapping
these roles to users in the master realm. It’s possible to create multiple
super users, as well as users that can only manage specific realms.
When you created your working realm, your adminuser was automatically
granted all permissions to manage your working realm. Now when you open
admin console you are logging into client 'security-admin-console' within
'master' realm and you are able to manage it because your adminuser from
master realm is granted all permission he needs to manage that realm.
I have been basing my code on
https://gist.github.com/thomasdarimont/c4e739c5a319cf78a4cff3b87173a84b.
As an aside, I am finding that that keycloak does not quite add up. For
instance, I tried to use the self register feature in KC. They works in
that it adds a user to the working realm but the user is unusable because
it is not associated with a role. The answer could be to have a default
role for new users. Or it could be to call some SB app code that added the
role. Except that there is no post registration feature to redirect to a
end point to run this code.
You can add default roles on admin console in Roles -> Default Roles. See:
https://www.keycloak.org/docs/latest/server_admin/index.html#_default_roles
And with the api, the Builder object can have completely the wrong
information (non existent user, wrong password) and no exception is thrown.
I realise that permissions can be caught before they are used (eg a user
can look but not create) so it is only when a non permissible action is
called that an exception is called. But the wrong authentication?
It looks like that actual authentication is performed in time it is really
needed,
in time some request is done, I can't see anything wrong there. If
you think this should be changed, feel free to file a new issue in our
issue tracker. More information here:
https://www.keycloak.org/community.html.
So does the api have the same workflow as the browser admin?
Yes it does. The only difference is that the authentication is performed
prior to request, not when you .build() Keycloak object. However you need
to make sure you are using master realm and client within master realm. If
I understand it correctly, you should do something like that to make admin
client work:
Keycloak keycloak = KeycloakBuilder
.builder()
.serverUrl(SERVER_URL)
.realm(*"master"*)
.username(USERNAME)
.password(PASSWORD)
.clientId(*"admin-cli"*) *// or some other client
within master realm, it is here for authentication purposes*
.resteasyClient(new
ResteasyClientBuilder().connectionPoolSize(10).build())
.build();
CredentialRepresentation credentialRepresentation = new
CredentialRepresentation();
credentialRepresentation.setType(CredentialRepresentation.PASSWORD);
credentialRepresentation.setValue("12345678");
UserRepresentation userRepresentation = new
UserRepresentation();
userRepresentation.setUsername(owner.getUserName());
userRepresentation.setFirstName(owner.getFirstName());
userRepresentation.setLastName(owner.getSurName());
userRepresentation.setEnabled(true);
userRepresentation.setCredentials(Arrays.asList(credentialRepresentation));
keycloak.realm(*"your_working_realm"*
).users().create(userRepresentation);
Regards,
John
------ Original Message ------
From: "Michal Hajas" <mhajas(a)redhat.com>
To: "John Norris" <johnnorris-10(a)outlook.com>
Cc: "keycloak-user(a)lists.jboss.org" <keycloak-user(a)lists.jboss.org>
Sent: 06/12/2019 09:33:41
Subject: Re: [keycloak-user] create user via java api
Have you changed clientId to some from master realm? In testsuite we are
using "admin-cli" client.
Michal
------ Original Message ------
From: "Tony Harris" <Tony.Harris(a)oneadvanced.com>
To: "John Norris" <johnnorris-10(a)outlook.com>
Sent: 06/12/2019 09:23:54
Subject: RE: Re[2]: create user via java api
John, I will tell you what I did when I was playing in this very area. We
have an app that allows some users to manager users and few other bits and
pieces in the realm.
We created a confidential client in the realm we want users to be able to
manage. We did not assign realm management rights to any normal users.
Instead we used Spring Security to restrict access to functions that allow
user creation/maintence by saying users with role X can do this. Then we
used the RestTemplate to obtain a server side bearer token for the service
account that we enabled when we created the confidential client, the
service account was assigned the realm management rights and can do the
required realm management functions within out SpringBoot application.
For us this meant that if any single normal user account was compromised
or that user tried to gain access to the keycloak console, they could not
be used to manage the realm.
Back when we did want individual users able to manage a realm the user was
created in that realm and given the rights based on the relam-management
client roles.