[keycloak-user] Get magic link for users to login

Ilya Korol llivezking at gmail.com
Wed Apr 19 02:12:22 EDT 2017


Hi. I implemented custom REST endpoint for Keycloak Admin REST API, 
where link will be constructed.

For example if you go to keycloak account client you will see in browser 
address bar something like:

http://localhost:8081/auth/realms/test-modules/protocol/openid-connect/auth?client_id=account&redirect_uri=%2Fauth%2Frealms%2Ftest-modules%2Faccount&state=41dacfb3-fa49-499e-9797-2137c618a8a8&response_type=code&scope=openid

so authenticator will play his game if you will follow similar link with 
format:

${default_authentication_link}&userId=bla&marker=blabla


So construction of this link is pretty simple:

     private String generateActivationLink(UserModel user, String 
targetClientId) {
         ClientModel client = realm.getClientByClientId(targetClientId);

         user.setSingleAttribute(ATTR_EXPIRATION, 
String.valueOf(computeExpirationTime(realm)));
         user.setSingleAttribute(ATTR_MARKER, UUID.randomUUID().toString());

         try {
             URIBuilder linkUri = new URIBuilder(String.format(
                     "%srealms/%s/protocol/openid-connect/auth", 
uriInfo.getBaseUri().toString(), realm.getName()
             ))
                     .addParameter("client_id", client.getClientId())
                     .addParameter("redirect_uri", client.getBaseUrl())
                     .addParameter("state", UUID.randomUUID().toString())
                     .addParameter("response_type", "code")
                     .addParameter("scope", "openid")
                     // Add additional params
                     .addParameter("user", user.getUserId())
                     .addParameter("marker", 
user.getFirstAttribute(ATTR_MARKER));

             return linkUri.build().toString();
         } catch (URISyntaxException e) {
             logger.error("Unable to construct activation link");
             return null;
         }
     }


Expiration of link or any other restriction could be implemented as 
adding attributes to UserModel while constructing the link and checking 
their values during authentication.


The only thing that bother me now how secure is this approach, so it 
would be great if someone point me to any potential security drawbacks. 
As for me this is not less secure than standard reset credentials flow


On 19.04.2017 15:59, Ulrik Lejon wrote:
> Hi
>
> Sounds like a good idea!
> Out of curiosity, how do you create the links? Also, will the links ever
> expire?
>
> BR,
> Ulrik
>
> On Wed, 19 Apr 2017, 04:02 Ilya Korol, <llivezking at gmail.com> wrote:
>
>> Hi recently i implemented almost same feature for our environment. I've
>> done it via custom Authenticator implementation. This authenticator is
>> injected in browser authentication flow as alternative execution just
>> before cookie execution, and check request link whether he should
>> authenticate user by this link. Here some snippet:
>>
>>
>>       @Override
>>       public void authenticate(AuthenticationFlowContext context) {
>>           MultivaluedMap<String, String> queryParams =
>> context.getHttpRequest().getUri().getQueryParameters();
>>
>>           // If uri doesn't contain appropriate query params this flow is
>> not applicable,
>>           // so we pass it by to other flow chain
>>           if (!(queryParams.containsKey("marker") &&
>> queryParams.containsKey("userId"))) {
>>               context.attempted();
>>               return;
>>           }
>>
>>           // Extract params from request
>>           String userId = queryParams.getFirst("userId");
>>           String marker = queryParams.getFirst("marker");
>>
>>           RealmModel realm = context.getSession().getContext().getRealm();
>>           UserModel user =
>> context.getSession().users().getUserById(userId, realm);
>>
>>           // If user state doesn't match requirements this flow is not
>> applicable,
>>           // so we pass it by to other flow chain
>>           if (checkConditions(user, marker, otherStruff)) {
>>
>>               // User could be authenticated
>>
>>               context.setUser(user);
>>               context.success();
>>           } else {
>>               context.attempted();
>>           }
>>       }
>>
>>
>>
>> On 18.04.2017 19:09, Martin Johansson wrote:
>>> Hi!
>>>
>>> We want to achieve the following:
>>>
>>> Expose a REST endpoint where an authenticated client can retrieve a magic
>>> login link for a specific user. We have an ID in the attributes for the
>>> user which enables us to get the correct user.
>>>
>>> The reason for this is that we need to expose the possibility to send
>>> e-mails from other systems than Keycloak. We have other ways of composing
>>> the e-mails.
>>>
>>> So wanted final state is that a user can click a link in his e-mail
>> client
>>> and be redirected to our app and be logged in.
>>>
>>> BR,
>>> Martin
>>>
>>> ---------- Forwarded message ----------
>>>> From: Ilya Korol <llivezking at gmail.com>
>>>> To: keycloak-user at lists.jboss.org
>>>> Cc:
>>>> Bcc:
>>>> Date: Fri, 14 Apr 2017 15:59:10 +1000
>>>> Subject: Re: [keycloak-user] Get magic link for users to login
>>>> Hi, could you explain more detailed what you want to achieve? As for my
>>>> team we also implemented custom rest endpoint, which send customized
>> emails
>>>> to users. Check out org.keycloak.services.resources.admin.UsersResource
>>>> for details of default link constructing. (methods:
>> resetPasswordEmail(),
>>>> executeActionsEmail(), sendVerifyEmail())
>>>>
>>>>
>>>> On 13.04.2017 17:54, Martin Johansson wrote:
>>>>
>>>>> Is it possible to retrieve the magic link that are sent by e-mail via
>> the
>>>>> Java
>>>>> API? We have implemented an SPI with a REST interface and would like to
>>>>> get
>>>>> the link for usage in custom e-mails.
>>>>> Any hints which provider to be used is much appreciated.
>>>>>
>>>>> Regards,
>>>>> Martin
>>>>> _______________________________________________
>>>>> keycloak-user mailing list
>>>>> keycloak-user at lists.jboss.org
>>>>> https://lists.jboss.org/mailman/listinfo/keycloak-user
>>>>>
>>>> _______________________________________________
>>>> keycloak-user mailing list
>>>> keycloak-user at lists.jboss.org
>>>> https://lists.jboss.org/mailman/listinfo/keycloak-user
>>>>
>>> _______________________________________________
>>> keycloak-user mailing list
>>> keycloak-user at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/keycloak-user
>> _______________________________________________
>> keycloak-user mailing list
>> keycloak-user at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/keycloak-user
>>



More information about the keycloak-user mailing list