Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI user authentication #448

Closed
nynymike opened this issue Mar 26, 2021 · 5 comments
Closed

CLI user authentication #448

nynymike opened this issue Mar 26, 2021 · 5 comments

Comments

@nynymike
Copy link
Contributor

We should require authentication to use the CLI. Having shell access is not enough.

In the Admin UI, we have a mapping of roles to scopes. The CLI should have the same behavior. The good news is that the scopes are populated by an Introspection Interception Script. So as long as the CLI authenticates the user and obtains an access token, the scopes will be present.

There should be two ways to authenticate the user:

  1. The user presents username/password
  2. The user presents a refresh token

To pass the username, you can use a argument like -u or --username.

To pass the password, I suggest two options: -p or --password, or -j --passwordFile, where the admin can store the password. The advantage of -j is that the password would not show in the history (and hopefully the admin would remove the password after running the command).

With the username and password, the CLI can make an HTTPS call to the /token endpoint of the Authorization Server responsible for issuing access tokens to authorize calling the config-api, using the ROPW grant. How the user might obtain a refresh token is out of scope (there would have to be some admin client application that provided this).

Note some applications may not allow the ROPW grant type. If this is the case, the admin could also present the -t or --tokenFile argument. This would reference a file with a long lived access token. Nice to have would be call to secets vault.

In interactive mode, if the user does not provide credentials via the command line, the system should ask for username and password. Note, this would be limited to ROPW flow.

@devrimyatar
Copy link
Contributor

@duttarnab Can you summarize steps to be performed?

@duttarnab
Copy link
Contributor

We need 2 OIDC clients for this

  • OIDC auth client (C1) with password grant_type
  • OIDC token client (C2) for config-api token generation

Steps:

  1. Auth client will be used to do authentication and get user-info containing user-role.
  2. Token client will generate config-api token. It will add appropriate scopes (based on user-role) to the token using Intropection_script.

@nynymike
Copy link
Contributor Author

nynymike commented Dec 2, 2021

I think you can use one client. If OAuth is required for security: grant_type = client credential grant; otherwise grant_type = password. However, you may want to create one client for "read" access and one client for "write" access, i.e. with different scopes. For OAuth, the client should have long lived access tokens (client specific setting), 30 days default (?).

BTW, I like how Github is handling CLI operations. They offload authn to the Web Browser, and then hand you an access token for your CLI application. This should be the model.

@duttarnab
Copy link
Contributor

BTW, I like how Github is handling CLI operations. They offload authn to the Web Browser, and then hand you an access token for your CLI application. This should be the model.

I checked and found that github is using device flow to achieve this..
https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps#device-flow

And we have already implemented device flow in Gluu auth server.
https://gluu.org/docs/gluu-server/4.3/admin-guide/device-authz-grant/#device-request-response

So here are the steps:

  1. We will need to create oidc client with grant_type urn:ietf:params:oauth:grant-type:device_code
  2. When trying to login .. the jans-cli will execute device_authorization_endpoint to get the user-code
curl -k -u '83e3f1bc-99d2-4047-9fdd-d27fdf8ad035:4a1ea0bd-8ae0-4b9d-b7ca-42d9449e7c01' https://ce-dev6.gluu.org/jans-auth/restv1/device_authorization -d 'client_id=83e3f1bc-99d2-4047-9fdd-d27fdf8ad035' -d 'scope=openid+profile+email'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   376  100   303  100    73    214     51  0:00:01  0:00:01 --:--:--   266{
    "user_code": "HWSS-BRXT",
    "device_code": "8b345943f330b3a88cf995a37c1b324c8e1f0273b4041529",
    "interval": 5,
    "verification_uri_complete": "https://ce-dev6.gluu.org/device-code?user_code=HWSS-BRXT",
    "verification_uri": "https://ce-dev6.gluu.org/device-code",
    "expires_in": 1800
}
  1. The user_code and verification_uri is obtained from the response. The User will need to open verification_uri on browser and enter user_code. The user will ask to authenticate if not already done.
  2. step#3 may take some time. The jans-cli will keep polling the token url ... to find whether the process is completed or not. It will get authorization_pending error if the process is not completed.
  3. Once step# 3 is completed jans-cli will get access_token.
 curl -k -u '83e3f1bc-99d2-4047-9fdd-d27fdf8ad035:4a1ea0bd-8ae0-4b9d-b7ca-42d9449e7c01' https://ce-dev6.gluu.org/jans-auth/restv1/token -d 'grant_type=urn:ietf:params:oauth:grant-type:device_code' -d 'scope=openid+profile+email' -d 'device_code=8b345943f330b3a88cf995a37c1b324c8e1f0273b4041529'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2106  100  1963  100   143   1663    121  0:00:01  0:00:01 --:--:--  1786{"access_token":"eyJraWQiOiI4ZjNmZGEzMy00Y2VhLTRhMmMtOTE3ZS0zYjZmNjg5Y2Y0NzBfc2lnX3JzMjU2IiwidHlwIjoiand0IiwiYWxnIjoiUlMyNTYifQ.eyJhdWQiOiI4M2UzZjFiYy05OWQyLTQwNDctOWZkZC1kMjdmZGY4YWQwMzUiLCJzdWIiOiJMbDk3OW9laVpWdXp4c3k0TnpBT2FQcU9vM1puWlhNRm9hcWlXeUhsSU1zIiwieDV0I1MyNTYiOiIiLCJjb2RlIjoiZWMzYjllMWYtOGIxZC00YWVlLWE4ZjQtMzQ0MzA0NGVlYjQ2Iiwic2NvcGUiOlsib3BlbmlkIiwicHJvZmlsZSIsImVtYWlsIl0sImlzcyI6Imh0dHBzOi8vY2UtZGV2Ni5nbHV1Lm9yZyIsInRva2VuX3R5cGUiOiJCZWFyZXIiLCJleHAiOjE2Mzg4NjMzNTIsImlhdCI6MTYzODg2MzA1MiwiY2xpZW50X2lkIjoiODNlM2YxYmMtOTlkMi00MDQ3LTlmZGQtZDI3ZmRmOGFkMDM1IiwidXNlcm5hbWUiOiJEZWZhdWx0IEFkbWluIFVzZXIifQ.GR0emoBs8Lkwl_e_mjfdbpqULKQBhxlN2uVYRDu6hsnf6FsssJVsk473oaKtaOHC_sIhguzrOXOS81o-dg6hIoGX2zdg488C7RD6wHCptTestQeL9lWS6252qO0fK9SZ1oqz_L-OQ_6omlr_C1UvcYWpZF7obGTt2e0kJGW1qz072VYlFMB4FSJDICZtUhW4htugwf9tWwUCA1jmrXXVkXCPrRaTvJ7OowdyoInYbQ37Sf50ZjgnWsRnjkZ4NR7_NXpzaRrsor68Rb6fcgsml3ea8Cej82ek_px0X824AB_ypDlv6__mLN_G_dt-a3x5Al9uqHiMM5kChp9uRJ0vow","scope":"openid profile email","id_token":"eyJraWQiOiI4ZjNmZGEzMy00Y2VhLTRhMmMtOTE3ZS0zYjZmNjg5Y2Y0NzBfc2lnX3JzMjU2IiwidHlwIjoiand0IiwiYWxnIjoiUlMyNTYifQ.eyJhdF9oYXNoIjoidWRWYWFuTzBjZUxDNEF1NFJMaHEzUSIsImF1ZCI6IjgzZTNmMWJjLTk5ZDItNDA0Ny05ZmRkLWQyN2ZkZjhhZDAzNSIsInN1YiI6IkxsOTc5b2VpWlZ1enhzeTROekFPYVBxT28zWm5aWE1Gb2FxaVd5SGxJTXMiLCJjb2RlIjoiYTQ4NDJiNDEtMjkxNS00Y2YyLTlkOTUtNjk1OTBkNDA0MDYxIiwiaXNzIjoiaHR0cHM6Ly9jZS1kZXY2LmdsdXUub3JnIiwiZXhwIjoxNjM4ODY2NjUzLCJncmFudCI6InVybjppZXRmOnBhcmFtczpvYXV0aDpncmFudC10eXBlOmRldmljZV9jb2RlIiwiaWF0IjoxNjM4ODYzMDUzLCJveE9wZW5JRENvbm5lY3RWZXJzaW9uIjoib3BlbmlkY29ubmVjdC0xLjAifQ.dMAV_N04H8sTDHB_3lh2nhfoNZOhYqTgm5ZJqaouLkssizdfjNGy-lYULxvLJQukdzUpgqAfJG_SQSh493RkHt1WRPV1STs65-zb4PEW_q3R7rImE_ejvvG1Z6pCKSiONlBn7YuVmPV-G8GsQIbjUoz6tpHNINuUEQqxCGkIesw3PREuTatbrFJXBcoewmIOxuNHFInjvU-vNf_YvVX8ab-cxKc1SzBZ85AXe_5qBfT4txvG7kGVkZgflOn2XmRlkpUaWDiJsQQVYoSHGzIPVNY5SFuMSQhEWB_3C0XQ7cfLYtnPWGUNiYChjdh3mMy8DgTg5kdBeK0RRaRT4x4ezA","token_type":"Bearer","expires_in":299}

Then it can use access token for furthur processing like getting user-info --> getting role from user-info---> use role to add scopes in config-api token (using script) etc.

@nynymike
Copy link
Contributor Author

nynymike commented Dec 7, 2021

This makes sense to me

devrimyatar referenced this issue in JanssenProject/jans-cli Dec 10, 2021
@ossdhaval ossdhaval transferred this issue from JanssenProject/jans-cli Jan 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants