Our implementation for the automatic one-time login is making good progress. We've now
got a REST service that can create an action token and an action token handler that logs
the user in (see main code below). It uses an authentication flow with no
steps/executions.
If we use to action token key and build a URL like
http://localhost:8180/auth/realms/myrealm/login-actions/action-token?key=....
then the user is login in but ends up in the account console.
Now we would like to integrate it into our Spring Boot application and would be grateful
for some hints:
- How can we initiate an OIDC flow from Spring Boot with the action token URL?
- How can we ensure that the flow ends on a specific page in our application?
Regards
Manuel
public class DirectLoginActionTokenHandler extends
AbstractActionTokenHander<DirectLoginToken> {
public DirectLoginActionTokenHandler() {
super(DirectLoginToken.TOKEN_TYPE, DirectLoginToken.class,
"not_allowed", EventType.LOGIN, "invalidCodeMessage");
}
@Override
public Response handleToken(DirectLoginToken token,
ActionTokenContext<DirectLoginToken> tokenContext) {
return tokenContext.processFlow(false, LoginActionsService.AUTHENTICATE_PATH,
tokenContext.getRealm().getFlowByAlias("direct login"), null,
new AuthenticationProcessor());
}
@Override
public String getAuthenticationSessionIdFromToken(DirectLoginToken token,
ActionTokenContext<DirectLoginToken> tokenContext, AuthenticationSessionModel
authenticationSessionModel) {
return null;
}
@Override
public AuthenticationSessionModel startFreshAuthenticationSession(DirectLoginToken
token, ActionTokenContext<DirectLoginToken> tokenContext) {
return tokenContext.createAuthenticationSessionForClient(token.getIssuedFor());
}
@Override
public boolean canUseTokenRepeatedly(DirectLoginToken token, ActionTokenContext
tokenContext) {
return false;
}
}
-----Ursprüngliche Nachricht-----
Von: Dmitry Telegin <demetrio(a)carretti.pro>
Gesendet: Dienstag, 18. Juni 2019 19:12
An: Manuel Bleichenbacher <manuel.bleichenbacher(a)acrea.com>;
keycloak-user(a)lists.jboss.org
Betreff: Re: AW: [keycloak-user] Automatic one-time login
Hi Manuel, you're welcome,
On Tue, 2019-06-18 at 14:02 +0000, Manuel Bleichenbacher wrote:
Hi Dmitry
Thanks so much for your valuable input. It contains so much useful information.
I had studied the action-token-authenticator quickstart example before but I can't
see how we could fit it into our solution. I haven't mentioned so far that an
unregistered user never goes to a login or registration page. Instead the flow is similar
to what you find in some web shops: a customer purchases some items and - as part of the
checkout process - enters email address and mobile phone number. After the checkout is
complete, the customer is asked if an account should be created for him. Up to this
moment, Keycloak has not been involved and no authentication or registration flow has been
initiated. And since no further entry is needed (in the future the user will log in with
email address and a one-time password sent to the mobile number), the Keycloak user can be
immediately created and the customer can immediately be logged in.
So given this flow: the quickstart example with a switch from the Keycloak flow to an
external application and back is probably not applicable, right?
Correct. This is exactly what I meant by "Had you been using Keycloak's
registration flow, this quickstart could have been applicable entirely". Third
conditional :)
In other words, you should use this quickstart just as a source of inspiration if you
decide to go with action token handler + authenticator + app-specific token instead of
REST + one-time code.
Cheers,
Dmitry
Regards
Manuel
-----Ursprüngliche Nachricht-----
Von: Dmitry Telegin <demetrio(a)carretti.pro>
Gesendet: Dienstag, 18. Juni 2019 15:14
An: Manuel Bleichenbacher <manuel.bleichenbacher(a)acrea.com>;
keycloak-user(a)lists.jboss.org
Betreff: Re: [keycloak-user] Automatic one-time login
Hi Manuel,
You might even avoid implementing one-time code logic (incl. REST endpoint, custom
credential etc.) by using the approach demonstrated in the quickstart [1].
Had you been using Keycloak's registration flow, this quickstart could have been
applicable entirely (modulo authentication vs. registration flow), but still you can
borrow the main idea from it: using app-specific signed token (instead of one-time code)
to assert that registration succeeded.
Keycloak already supports one-time action tokens (see
org.keycloak.authentication.actiontoken.ActionTokenHandler::canUseTokenRepeatedly). To
ensure that your app-specific token is one-time too, you could associate it with the
"parent" action token using the latter's "nonce" claim. One thing
you need to know about one-time action tokens in Keycloak - this is done via
org.keycloak.models.ActionTokenStoreProvider, and the default implementation
(o.k.models.sessions.infinispan.InfinispanActionTokenStoreProvider) is non-persistent, so
if by some reason the whole cluster gets restarted before action token expires, it could
be potentially reused.
Otherwise, both options that you described should be viable. Please find the answers
below.
On Tue, 2019-06-18 at 08:03 +0000, Manuel Bleichenbacher wrote:
> Hi everybody,
>
> Our new application will have a length user registration procedure that we would
like to keep separate from Keycloak (it will mainly require application data, reuse part
of the application's UI etc.). At the end of the registration procedure, we would
still like to automatically login the user so he/she doesn't need to reenter the
username and password. What are our options to achieve it?
>
> The backend will certainly use a privileged Keycloak user (e.g. to create the new
user via the REST Admin API). And the result of the login should be that the user's
access token (JWT) is available in the user's session in the backend. So far we have
come up with the following options:
>
> Option A: REST endpoint / custom authenticator
>
> - Add a custom REST endpoint so the backend can create a one-time
> code and save it as a credential on the new user
> - Add a custom authenticator to the browser flow that checks for the
> one-time code
> - The user would then be directed to the regular authentication flow. If the
one-time code is present and correct, the username/password step and possibly all other
authentication steps will be skipped and the authentication immediately succeeds.
>
> Option B: REST endpoint / action token
>
> - Add a custom REST endpoint so the backend can create a one-time
> code and save it as a credential on the new user
> - Implement an additional action token handler that checks the
> one-time token to authenticate the user
> - The user would then be directed to the action token URL. If the one-time code is
correct, the user is authenticated.
>
> What is your recommendation:
> - Are these feasible options?
> - Are we missing a good option?
>
> For option A: How can we pass the one-time code to the authentication flow? Can we
use a URL parameter, HTTP header attribute?
This is possible, but not much reliable because of HTTP redirects. After a redirect, the
initial parameters will be lost (as well as headers), and you'll need to parse the
parameter out of Referer header. Check out this thread [2] for details.
However, there exists a hack so that you can use "scope" parameter to pass data
reliably, see this thread for details [3].
> For option B: Can the action token flow initiate the OAUTH2 flow and return an
authorization code? Can this flow be easily integrated with the Spring Boot adapter?
Yes, see this [4]. AFAIK for the adapter it should look like an ordinary flow, it
won't even know it had been initiated via action token handler.
[1]
https://github.com/keycloak/keycloak-quickstarts/tree/latest/action-to
ken-authenticator [2]
https://lists.jboss.org/pipermail/keycloak-user/2018-November/016230.h
tml [3]
https://lists.jboss.org/pipermail/keycloak-user/2019-May/018393.html
[4]
https://github.com/keycloak/keycloak-quickstarts/blob/latest/action-to
ken-authenticator/src/main/java/org/keycloak/quickstart/actiontoken/to
ken/ExternalApplicationNotificationActionTokenHandler.java#L89
Good luck,
Dmitry Telegin
Carretti Consulting OÜ | Keycloak Consulting and Training Sepapaja 6,
Tallinn 15551, Estonia | info(a)carretti.pro
> Any input is appreciated.
>
> Thanks
> Manuel
>
> --
> manuel bleichenbacher | senior consultant m +41 79 617 90 01 |
> manuel.bleichenbacher(a)acrea.com
>
> acrea ag | konradstrasse 32 | 8005 zürich
www.acrea.com |
>
blog.acrea.com
>
>
www.nezasa.com - incubated by Acrea
>
>
> _______________________________________________
> keycloak-user mailing list
> keycloak-user(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/keycloak-user