Very cool. A few questions/comments:
* As it's Java based it does make it harder to package/install. Compare
'oc' tool for instance to our 'kcadmin' and 'kcclient' tools. Not
sure how
realistic it would be to write our CLI tools in for instance Go though.
* I assume the console display is optional and it basically means that you
can only use authenticators that support this rather than all
authenticators require to implement it.
* Not sure I fully understand the user experience with the encrypted
password file. How does this compare to kinit and ssh-agent for instance?
They both allow unlocking automatically through the regular OS login I
believe. For 'kcadmin' and 'kcclient' we don't currently protect the
tokens
so we should probably consider aligning these approaches (probably even
getting rid of the auth stuff there in favour of kcinit).
* Should we consider merging all our CLIs into one CLI? Just 'kc' instead
of 'kcinit', 'kcadmin' and 'kcclient'? If we someone could get
this stuff
in Go and get native binaries that'd be even easier for users to use.
On 12 March 2018 at 14:29, Bill Burke <bburke(a)redhat.com> wrote:
I'm finally finishing the generic console login tool I've
been
promising and working on for awhile now. Its an extension of
KeycloakInstalled, but it works entirely on the command line and
doesn't require a browser. Its all text input and output in your
command line console to login. All driven by the server and rendered
by the utility. Supports localization just like the browser too.
* To enable this a simple challenge-based protocol was implemented.
OAuth Code to token flow is required.
Authenticator returns 401 with a WWW-Authenticate header with value of
X-Text-Form-Challenge callback="{url}" param="username"
label="Username: " mask="false"
param/label/mask are input parameter definitions that require command
line console input and can be repeated for each input parameter you
require from the console. Label is what should be outputed to the
console. If mask is true, this means it is a password field and
should be hidden on input.
If the Response contains "text/plain" content, then that should be
outputed before command input is asked for. Client should loop and
render/ask for input until a 302 response is returned that contains a
"code" parameter. Then regular OAuth is used to get the token.
* The access and refresh token is stored locally in a password
protected file (like ssh does). This file is checked before login is
initiated to see if the user is still logged in.
* If logged in, and the client has permission, the kcinit tool can
also perform token exchange to obtain tokens for other clients. It
stores these tokens in password protected files on local disk.
* I have extended the OAuth layer on the server to support the OIDC
"display" parameter. (It just stores this value in the AuthSession.
I'm also in the process to refactor all the built-in Authenticators
and Required Actions to support the "display" parameter and use the
texts protocol described above if the "display" parameter is
"console".
* kcinit is implemented via Java and a shell and windows batch
scripts. There's also a wrapper template script that can be used to
secure existing command line tools. here's example usage with the
target app command being `oc`.
$ . kcinit
Initially you will be prompted for the "local password" that protects
token files on local disk. If you do not "source" this script (with a
'.' or 'source' command), then you will have to enter in this local
password every time you interact with kcinit utility.
the kcinit script will prompt for this local password. Once it gets
the password value, it will invoke the Java kcinit program:
read -sp 'Local password: ' password
KC_SESSION_KEY=`java -jar kcinit.jar password $password`
The `password` command will generate an AES key from the password that
will be used encrypt and decrypt locally stored files. I do it this
way so that when the user's shell is exited, they can no longer access
stored tokens.
Once the user is logged in, they can start using command line
utilities that are secured by it. To secure a command line utility
the developer must use a wrapper script for each of their command line
tools. The wrapper script looks like this
- checks to see if KC_SESSION_KEY is set. If not, it will prompt for
the local password and generate this key.
- It then tries to obtain the token for the app
token=`java -jar kcinit.jar token oc`
This will perform a token exchange to obtain a token for the `oc`
client. If this is not successful, an error message is displayed
(i.e. "You are not logged in".) If successful, then the target
command line tool is invoked. The tool extracts the "token"
environment variable to invoke on its REST services.
$path_to_real_command/$0 $@
* There is an install option for kcinit
$ kcinit install
This will prompt you for auth server url, realm, client, client
secret, and the local password to encrypt things.
--
Bill Burke
Red Hat
_______________________________________________
keycloak-dev mailing list
keycloak-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-dev