[keycloak-dev] OTP API
Marek Posolda
mposolda at redhat.com
Mon Nov 14 02:44:26 EST 2016
On 11/11/16 15:06, Thomas Darimont wrote:
> Hello Marek,
>
> I'm already using the direct grant auth flow for authenticating a
> desktop app against the Keycloak userbase,
> but thanks for the hint with the totp parameter, for the record I
> added a simple curl example below.
>
> Does anyone know about OIDC providers that support the display=popup
> parameter - I could not find a
> project / product that supports this.
>
> Btw. the usage for OTP to verify sensitive operations or transaction
> authorization seems indeed to be quite common.
> http://www.transmitsecurity.com/use_case/otp-one-time-password/
> https://bankapi.net/docs/public/authorization-getstarted.html
> https://www.owasp.org/index.php/Transaction_Authorization_Cheat_Sheet
Yeah, I agree. I hope that in future versions, we will have time to add
better support for things like step-up authentication, authentication
levels, display=popup etc. So the usecase when application wants to
display popup window where it needs to re-authenticate against Keycloak
server with TOTP (or any other secure auth mechanism) and this popup
will be shown for confirm every important transaction on application
side, will be possible.
Marek
>
> Cheers,
> Thomas
>
> --
>
> KC_REALM=otp-validation-test
> KC_USERNAME=tester
> KC_PASSWORD=test
> KC_OTP_CODE=654328
> KC_CLIENT=test-client
> KC_CLIENT_SECRET=c57dc179-09bb-4bb7-9128-91b29dd7fc35
> KC_URL="http://localhost:8081/auth"
>
> ## Request Tokens for credentials
> KC_RESPONSE=$( \
> curl -v \
> -d "username=$KC_USERNAME" \
> -d "password=$KC_PASSWORD" \
> -d 'grant_type=password' \
> -d "client_id=$KC_CLIENT" \
> -d "client_secret=$KC_CLIENT_SECRET" \
> -d "totp=$KC_OTP_CODE" \
> "$KC_URL/realms/$KC_REALM/protocol/openid-connect/token" \
> | jq .
> )
>
> KC_ACCESS_TOKEN=$(echo $KC_RESPONSE| jq -r .access_token)
> KC_ID_TOKEN=$(echo $KC_RESPONSE| jq -r .id_token)
> KC_REFRESH_TOKEN=$(echo $KC_RESPONSE| jq -r .refresh_token)
>
> ## Validate otp token with custom credential validation endpoint
>
> KC_OTP_CODE=027253 curl -v \
> -H "Authorization: Bearer $KC_ACCESS_TOKEN" \
> -H "Content-Type: application/json" \
> -d
> "[{"\""type"\"":"\""totp"\"","\""value"\"":"\""$KC_OTP_CODE"\""}]" \
> $KC_URL/realms/$KC_REALM/credential-validation
>
>
> 2016-11-11 11:26 GMT+01:00 Marek Posolda <mposolda at redhat.com
> <mailto:mposolda at redhat.com>>:
>
> On 11/11/16 11:00, Thomas Darimont wrote:
>
> Hi Stian,
>
> thanks for the feedback.I understand the philosophy behind not
> exposing
> credentials to an application and agree that
> one way to solve this is by using a custom endpoint.
>
> Question: Is there a general recommendation or guideline about
> resource
> names / paths? E.g. something like custom resources should be
> located
> beneath a special base path (e.g. /custom) to avoid potential
> clashes with
> Keycloak resources in newer versions?
>
> I also like the idea for (partial) re-auth via some sort of
> popup / iframe.
> Are there any JIRAs logged for this already?
> Another thing is that this might not work in every case, e.g. when
> integrating Desktop applications where a
> the "client" sends the user credentials to a server which then
> needs to
> check those credentials against keycloak, e.g. by trying to
> acquire an
> access token.
>
> One related JIRA is the support for OIDC "display" parameter. This
> allows to open login page in the popup (among other things). See
> https://issues.jboss.org/browse/KEYCLOAK-3322
> <https://issues.jboss.org/browse/KEYCLOAK-3322> .
>
> Regarding desktop client, we already have "Direct Grant"
> authentication flow, which has some support for OTP verification.
> You just need to add "totp" parameter to the request though. See
> the ValidateOTP class for details.
>
> Marek
>
>
> Cheers,
> Thomas
>
> 2016-11-11 8:48 GMT+01:00 Stian Thorgersen
> <sthorger at redhat.com <mailto:sthorger at redhat.com>>:
>
> This is not something we should add IMO. As Bill points
> out the whole idea
> is to not expose credentials to application. I'd rather
> see something that
> works without exposing credentials to the users. Could do
> a redirect with
> re-auth required. Could require just adding otp on
> re-auth. Could possibly
> do a popup with embedded login from KC. I'm sure there's
> cleaner ways than
> the applicaiton collection OTP.
>
> However, it's perfectly possible to implement this using a
> custom rest
> resource so if you really want it to do this then do it
> that way.
>
> On 10 November 2016 at 21:55, Thomas Darimont
> <thomas.darimont at googlemail.
> com> wrote:
>
> Hello guys,
>
> I agree with you Bill that requiring a user to re-auth
> by redirecting to
> the
> auth-server is often the best thing to do.
> However in business applications one often sees the
> requirement to
> periodically
> reauthenticate the user without requiring the user to
> login again (e.g.
> without leaving the application).
> A common example for this is that users need to
> reenter a OTP credential
> before performing a certain critical operation...
>
> I gave this a quick spin...
> https://github.com/thomasdarimont/keycloak/commit/e891ca604a
> <https://github.com/thomasdarimont/keycloak/commit/e891ca604a>
> cf5fd494525092c7a88628d9fb20bd
> as you can see I took some inspiration from the
> userinfo endpoint.
>
> Works quite well so far, but bruteforce protection is
> still missing.
>
> A demo session via curl looks like this:
>
> $ KC_REALM=otp-validation-test
> KC_USERNAME=tester
> KC_PASSWORD=test
> KC_CLIENT=test-client
> KC_CLIENT_SECRET=c57dc179-09bb-4bb7-9128-91b29dd7fc35
> KC_URL="http://localhost:8081/auth
> <http://localhost:8081/auth>"
>
> ## Request Tokens for credentials
> KC_RESPONSE=$( \
> curl -v \
> -d "username=$KC_USERNAME" \
> -d "password=$KC_PASSWORD" \
> -d 'grant_type=password' \
> -d "client_id=$KC_CLIENT" \
> -d "client_secret=$KC_CLIENT_SECRET" \
>
> "$KC_URL/realms/$KC_REALM/protocol/openid-connect/token"
> \
> | jq .
> )
>
> KC_ACCESS_TOKEN=$(echo $KC_RESPONSE| jq -r .access_token)
> KC_ID_TOKEN=$(echo $KC_RESPONSE| jq -r .id_token)
> KC_REFRESH_TOKEN=$(echo $KC_RESPONSE| jq -r
> .refresh_token)
> * Trying 127.0.0.1...
> % Total % Received % Xferd Average Speed Time
> Time Time
> Current
> Dload Upload
> Total Spent Left
> Speed
> 0 0 0 0 0 0 0 0
> --:--:-- --:--:-- --:--:--
> 0* Connected to localhost (127.0.0.1) port 8081 (#0)
>
> POST
> /auth/realms/otp-validation-test/protocol/openid-connect/token
>
> HTTP/1.1
>
> Host: localhost:8081
> User-Agent: curl/7.45.0
> Accept: */*
> Content-Length: 122
> Content-Type: application/x-www-form-urlencoded
>
> } [122 bytes data]
> * upload completely sent off: 122 out of 122 bytes
> < HTTP/1.1 200 OK
> < Connection: keep-alive
> < Content-Type: application/json
> < Content-Length: 3713
> < Date: Thu, 10 Nov 2016 20:32:16 GMT
> <
> { [3713 bytes data]
>
> # We got an acces token ... now lets try to validate a
> wrong OTP code
>
> curl -v \
> -H "Authorization: Bearer $KC_ACCESS_TOKEN" \
> -H "Content-Type: application/json" \
> -d '[{"type":"totp", "value":"24861"}]' \
> $KC_URL/realms/$KC_REALM/credential-validation
> * Trying 127.0.0.1...
> * Connected to localhost (127.0.0.1) port 8081 (#0)
>
> POST
> /auth/realms/otp-validation-test/credential-validation
> HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.45.0
> Accept: */*
> Authorization: Bearer eyJhb...EW3Q
> Content-Type: application/json
> Content-Length: 34
>
> * upload completely sent off: 34 out of 34 bytes
> < HTTP/1.1 400 Bad Request
> < Connection: keep-alive
> < Content-Length: 0
> < Date: Thu, 10 Nov 2016 20:30:42 GMT
> <
> * Connection #0 to host localhost left intact
>
> # Let's try a currently valid OTP code
>
> curl -v \
> -H "Authorization: Bearer $KC_ACCESS_TOKEN" \
> -H "Content-Type: application/json" \
> -d '[{"type":"totp", "value":"949784"}]' \
> $KC_URL/realms/$KC_REALM/credential-validation
> * Trying 127.0.0.1...
> * Connected to localhost (127.0.0.1) port 8081 (#0)
>
> POST
> /auth/realms/otp-validation-test/credential-validation
> HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.45.0
> Accept: */*
> Authorization: Bearer eyJhb...EW3Q
> Content-Type: application/json
> Content-Length: 35
>
> * upload completely sent off: 35 out of 35 bytes
> < HTTP/1.1 200 OK
> < Connection: keep-alive
> < Content-Length: 0
> < Date: Thu, 10 Nov 2016 20:34:11 GMT
> <
> * Connection #0 to host localhost left intact
>
> Cheers,
> Thomas
>
> 2016-11-10 14:27 GMT+01:00 Bill Burke
> <bburke at redhat.com <mailto:bburke at redhat.com>>:
>
> Should be generic and not specific to a credential
> type. Should also
> hook into brute force detection. IMO though, one
> of the reasons for SSO
> and keycloak is that the application does not
> gather credentials. This
> is the job of the auth server. IMO, we'd be
> better off with expiring
> the login at the client side, redirecting to auth
> server, auth server
> sees that the user session is 3 hours old, and
> requests OTP.
>
>
> On 11/10/16 7:52 AM, Thomas Darimont wrote:
>
> Hello Rohith,
>
> not that I know of - we'd also like to have
> this functionality.
>
>
> What would be the best place to add that?
> Perhaps this could be added
>
> to
>
> the UsersResource with a new
> endpoint like "/users/{userId}/otp-validation"
> or a (new) dedicated
> resource.
>
> A client could then do a POST to that
> endpoint with the current
>
> user's
>
> access token and the entered OTP code.
> Keycloak could then lookup and check the
> provided otp code.
> If the code is corret, response could indicate
> that via status HTTP
>
> 200
>
> or
>
> HTTP 400 otherwise.
>
> Cheers,
> Thomas
>
> 2016-11-10 12:11 GMT+01:00 gambol
> <gambol99 at gmail.com <mailto:gambol99 at gmail.com>>:
>
> Hiya
>
> Does the latest version of Keycloak
> provide any means of verifying a
>
> user's
>
> TOTP?. Our use-case at the moment, we have
> an application which once
>
> the
>
> user is authenticated we issue a token of
> sorts ... however, we wish
>
> to
>
> provide a popup that requests a user's
> TOPT every few hours which we
> "could" verify via service account ... I
> can't see any access at the
>
> moment
>
> via the rest api
>
> Rohith
> _______________________________________________
> keycloak-dev mailing list
> keycloak-dev at lists.jboss.org
> <mailto:keycloak-dev at lists.jboss.org>
> https://lists.jboss.org/mailman/listinfo/keycloak-dev
> <https://lists.jboss.org/mailman/listinfo/keycloak-dev>
>
> _______________________________________________
> keycloak-dev mailing list
> keycloak-dev at lists.jboss.org
> <mailto:keycloak-dev at lists.jboss.org>
> https://lists.jboss.org/mailman/listinfo/keycloak-dev
> <https://lists.jboss.org/mailman/listinfo/keycloak-dev>
>
> _______________________________________________
> keycloak-dev mailing list
> keycloak-dev at lists.jboss.org
> <mailto:keycloak-dev at lists.jboss.org>
> https://lists.jboss.org/mailman/listinfo/keycloak-dev
> <https://lists.jboss.org/mailman/listinfo/keycloak-dev>
>
> _______________________________________________
> keycloak-dev mailing list
> keycloak-dev at lists.jboss.org
> <mailto:keycloak-dev at lists.jboss.org>
> https://lists.jboss.org/mailman/listinfo/keycloak-dev
> <https://lists.jboss.org/mailman/listinfo/keycloak-dev>
>
>
> _______________________________________________
> keycloak-dev mailing list
> keycloak-dev at lists.jboss.org <mailto:keycloak-dev at lists.jboss.org>
> https://lists.jboss.org/mailman/listinfo/keycloak-dev
> <https://lists.jboss.org/mailman/listinfo/keycloak-dev>
>
>
>
>
More information about the keycloak-dev
mailing list