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/e891ca604acf5fd49452509...
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"
## 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(a)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(a)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(a)lists.jboss.org
>>
https://lists.jboss.org/mailman/listinfo/keycloak-dev
>>
> _______________________________________________
> keycloak-dev mailing list
> keycloak-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/keycloak-dev
_______________________________________________
keycloak-dev mailing list
keycloak-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-dev