[keycloak-dev] Integration with GuardianKey

Paulo Angelo pa at pauloangelo.com
Sun Feb 17 20:11:15 EST 2019


Thank you Thomas and Alexis!

Another question: In the method "onEvent" of an EventListener, how could I
get the configuration for one specific Authenticator?

When the Authenticator is triggered (authenticate method), I can access its
config using:

    Map<String,String> config =
context.getAuthenticatorConfig().getConfig();

However, the context is not directly available (as expected) when the
"EventListener.onEvent" is triggered.

I could see in the documentation [1] that, inside the EventListener, I can
have access to a KeycloakSession and a KeycloakSessionFactory. But I could
not find the path for one specific Authenticator config. I also saw in docs
that it is possible to save the configuration for the EventListener, but
the attributes are the same used in the Authenticator.

Is it possible to retrieve the configuration of a specific Authenticator in
the flow used by the "event"?

Thank you in advance,

Paulo Angelo

[1]
https://www.keycloak.org/docs/3.3/server_development/topics/providers.html



On Sun, Feb 17, 2019 at 6:25 PM Alexis Almeida <alexis.almeida at gmail.com>
wrote:

> Hi Paulo!
>
> In addition to Thomas suggestion, I usually capture the remote IP like
> this:
>
> String ip = context.getSession (). GetContext (). GetConnection ().
> GetRemoteAddr ();
>
> About login status, I think you must to change your approach to get failure
> login.
>
> In the authentication flow, if you put your authenticator provider before
> "user and password" form this wil not work, because the user is not
> authenticated yet.
> If you put it after "user and passwrd" form, you'll only catch success
> logins.
>
> So I think you could implement the EventListener class to get any event
> type:
>
> public class RealmTeste implements EventListenerProvider, Authenticator {
> ...
>     public void onEvent(Event event) {
>         String ip = event.getIpAddress();
>         if (event.getType().equals("LOGIN_ERROR")) {
>
>         }
>     }
>     public void onEvent(AdminEvent event, boolean includeRepresentation) {
>     }
> ...
>
> Regards
>
> Aléxis
>
>
> Em dom, 17 de fev de 2019 às 17:45, Thomas Darimont <
> thomas.darimont at googlemail.com> escreveu:
>
> > Hello Paulo,
> >
> > in order to get the remote IP address of the request you could either use
> > the information from "ClientConnection" or look manually in the current
> > HttpServletRequest,
> > or HTTP-Headers. This structures can be obtained from the
> > "ResteasyProviderFactory".
> >
> >         // See ResteasyProviderFactory.getContextDataMap() for what's
> > available.
> >
> >         ClientConnection clientConnection =
> > ResteasyProviderFactory.getContextData(ClientConnection.class);
> >         clientConnection.getRemoteAddr();
> >
> >         HttpServletRequest request =
> > ResteasyProviderFactory.getContextData(HttpServletRequest.class);
> >
> > Cheers,
> > Thomas
> >
> > Am So., 17. Feb. 2019 um 19:47 Uhr schrieb Paulo Angelo <
> > pa at pauloangelo.com>:
> >
> >> Hi All,
> >>
> >> The GuardianKey extension for KeyCloak is almost complete! Thank you for
> >> the given directions.
> >>
> >> We have to get the user client IP and the status of the authentication
> >> attempt (failed/success). For this, we implemented the code below.
> >> However,
> >> we are facing Null Pointer exceptions.
> >>
> >> public class GuardianKeyAuthenticator implements Authenticator {  // ...
> >> public void authenticate(AuthenticationFlowContext context) {  // ...
> >>          // *Trying to get the Client IP address*
> >>            clientIP =
> >>
> >>
> context.getSession().sessions().getUserSession(context.getAuthenticationSession().getClient().getRealm(),
> >>
> >> context.getAuthenticationSession().getClient().getId())
> >>                                                      .getIpAddress(); /*
> >> getting null pointer exception */
> >>           // *Trying to get the status for the auth attempt
> >> (failed/success), this Authenticator should be the last in the flow*
> >>              failed = context.getStatus().equals(FlowStatus.SUCCESS); /*
> >> getting null pointer exception */
> >>        // ...
> >> } }
> >>
> >> Any clue about how we can do this?
> >>
> >> Thank you in advance.
> >>
> >> Paulo Angelo
> >>
> >>
> >> On Sun, Feb 3, 2019 at 10:21 PM Paulo Angelo <pa at pauloangelo.com>
> wrote:
> >>
> >> > Dmitry and Aléxis,
> >> >
> >> > Thank you very much for the directions. We are going to work on it.
> >> >
> >> > regards,
> >> >
> >> > Paulo Angelo
> >> >
> >> > On Sun, Feb 3, 2019 at 8:06 PM Dmitry Telegin <dt at acutus.pro> wrote:
> >> >
> >> >> Hello Paulo,
> >> >>
> >> >> To add to Alexis's reply, you can use Script authenticator [1]. It's
> >> >> especially good for prototyping since you don't have to create and
> >> deploy
> >> >> the whole provider module.
> >> >>
> >> >> Also, you'll need an HttpClient instance to be able to perform
> external
> >> >> HTTP requests, see [2] for that.
> >> >>
> >> >> [1] https://www.keycloak.org/docs/latest/server_admin/#executions
> >> >> [2]
> >> >>
> >>
> http://lists.jboss.org/pipermail/keycloak-user/2018-November/016456.html
> >> >>
> >> >> Good luck,
> >> >> Dmitry Telegin
> >> >> CTO, Acutus s.r.o.
> >> >> Keycloak Consulting and Training
> >> >>
> >> >> Pod lipami street 339/52, 130 00 Prague 3, Czech Republic
> >> >> +42 (022) 888-30-71
> >> >> E-mail: info at acutus.pro
> >> >>
> >> >> On Sun, 2019-02-03 at 17:46 -0200, Alexis Almeida wrote:
> >> >> > Hi Paulo,
> >> >> >
> >> >> > IMO the simplest way to do this is with an Authenticator Provider.
> >> >> Please
> >> >> > see here:
> >> >> >
> >> >> >
> >> >>
> >>
> https://www.keycloak.org/docs/latest/server_development/index.html#implementing-an-authenticator
> >> >> > .
> >> >> >
> >> >> > In the authenticate method you can call the GuardianKey and,
> >> depending
> >> >> on
> >> >> > the result, you call a context.success () or context.failure ().
> >> >> >
> >> >> > Like this:
> >> >> >
> >> >> > public void authenticate(AuthenticationFlowContext context) {
> >> >> > ...
> >> >> > if(!GuardianKeyValidation){
> >> >> >    Response challenge = context.form()
> >> >> >                 .setError("something")
> >> >> >                 .createForm("error_page.ftl");
> >> >> >
> >> >> >
> >> context.failureChallenge(AuthenticationFlowError.INVALID_CREDENTIALS,
> >> >> > challenge);
> >> >> >    return;
> >> >> > }
> >> >> > ...
> >> >> > context.success();
> >> >> > }
> >> >> >
> >> >> > Aléxis
> >> >> >
> >> >> >
> >> >> > > Em dom, 3 de fev de 2019 às 15:38, Paulo Angelo <
> >> pa at pauloangelo.com>
> >> >> > escreveu:
> >> >> >
> >> >> > > Hi all,
> >> >> > >
> >> >> > > We are trying to integrate KeyCloak with GuardianKey. However, we
> >> have
> >> >> > > doubts related to the best way to do this and the best point in
> the
> >> >> > > KeyCloak’s code for this integration.
> >> >> > >
> >> >> > > GuardianKey is a service to protect systems against
> authentication
> >> >> attacks.
> >> >> > > It uses Machine Learning and analyses the user's behavior, threat
> >> >> > > intelligence and psychometrics (or behavioral biometrics). The
> >> >> protected
> >> >> > > system (in the concrete case, KeyCloak) must send an event via
> REST
> >> >> for the
> >> >> > > GuardianKey on each login attempt. More info at
> >> >> https://guardiankey.io .
> >> >> > >
> >> >> > > The best way to integrate would be on having a hook in the
> >> procedure
> >> >> that
> >> >> > > process the user credentials submission in KeyCloak (the script
> >> that
> >> >> > > receives the POST), something such as:
> >> >> > >
> >> >> > > if(<POST IN AUTH FORM>) {
> >> >> > >
> >> >> > >  boolean loginFailed =  checkLoginInKeyCloak();
> >> >> > >
> >> >> > >  GuardianKeyEvent event =
> >> >> createEventForGuardianKey(username,loginFailed);
> >> >> > >
> >> >> > >  boolean GuardianKeyValidation = checkGuardianKeyViaREST(event);
> >> >> > >
> >> >> > >  if(GuardianKeyValidation){
> >> >> > >
> >> >> > >     // Allow access
> >> >> > >
> >> >> > >  } else {
> >> >> > >
> >> >> > >     // Deny access
> >> >> > >
> >> >> > >  }
> >> >> > >
> >> >> > > }
> >> >> > >
> >> >> > > Where is the best place to create this integration? Is there a
> way
> >> to
> >> >> > > create a hook for this purpose? Should we create an extension?
> >> >> > >
> >> >> > > Any help is welcome.
> >> >> > >
> >> >> > > Thank you in advance.
> >> >> > >
> >> >> > > Best regards,
> >> >> > >
> >> >> > > Paulo Angelo
> >> >> > > _______________________________________________
> >> >> > > keycloak-dev mailing list
> >> >> > > keycloak-dev at lists.jboss.org
> >> >> > > https://lists.jboss.org/mailman/listinfo/keycloak-dev
> >> >> >
> >> >> > _______________________________________________
> >> >> > keycloak-dev mailing list
> >> >> > keycloak-dev at lists.jboss.org
> >> >> > https://lists.jboss.org/mailman/listinfo/keycloak-dev
> >> >> _______________________________________________
> >> >> keycloak-dev mailing list
> >> >> keycloak-dev at lists.jboss.org
> >> >> https://lists.jboss.org/mailman/listinfo/keycloak-dev
> >> >
> >> >
> >> >
> >> > --
> >> >
> >> > Att,
> >> >
> >> > Paulo Angelo
> >> >
> >>
> >>
> >> --
> >>
> >> Att,
> >>
> >> Paulo Angelo
> >> _______________________________________________
> >> keycloak-dev mailing list
> >> keycloak-dev at lists.jboss.org
> >> https://lists.jboss.org/mailman/listinfo/keycloak-dev
> >
> >
> _______________________________________________
> keycloak-dev mailing list
> keycloak-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/keycloak-dev



-- 

Att,

Paulo Angelo


More information about the keycloak-dev mailing list