Hi,
Thank you for providing this example!
The problem I'm having now is how to provide the frontend application with
the OAuth 2 bearer token? Is it possible to generate a token on behalf of
the user without knowing the user's password?
The flow right now is like this:
1. User makes a request to my custom keycloak rest endpoint to get the
magic link
2. User paste the link in the browser
3. My custom keycloak authenticator, which is first in the browser flow
chain, marks the AuthenticationFlowContext as successfull and sets the user
property.
4. User is redirected to my frontend app
To be able to continue the flow I need to obtain a OAuth2 bearer token that
I can use in each request to my backend application. Is there a way of
doing that?
ons 19 apr. 2017 kl 08:17 skrev Ilya Korol <llivezking(a)gmail.com>:
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/au...
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(a)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(a)gmail.com>
>>>> To: keycloak-user(a)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(a)lists.jboss.org
>>>>>
https://lists.jboss.org/mailman/listinfo/keycloak-user
>>>>>
>>>> _______________________________________________
>>>> keycloak-user mailing list
>>>> keycloak-user(a)lists.jboss.org
>>>>
https://lists.jboss.org/mailman/listinfo/keycloak-user
>>>>
>>> _______________________________________________
>>> keycloak-user mailing list
>>> keycloak-user(a)lists.jboss.org
>>>
https://lists.jboss.org/mailman/listinfo/keycloak-user
>> _______________________________________________
>> keycloak-user mailing list
>> keycloak-user(a)lists.jboss.org
>>
https://lists.jboss.org/mailman/listinfo/keycloak-user
>>
_______________________________________________
keycloak-user mailing list
keycloak-user(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-user