Great - thanks. Got it working with a combination of your code and the
admin-client code.
For anyone who wants to do this in future - I just pushed the code to
maven central.
See
https://github.com/realityforge/keycloak-jaxrs-client-authfilter
Thanks again Thomas!
On Mon, May 22, 2017 at 10:13 PM, Thomas Darimont
<thomas.darimont(a)googlemail.com> wrote:
Hello Peter,
have a look at the example below.
The following example obtains an access token from the /token endpoint and
uses it to call the /userinfo endpoint
with the access token in the Authorization header. In real Keycloak
integrations one would use the access token
which is maintained by the Keycloak adapter via the KeycloakSecurityContext.
HTH.
Cheers,
Thomas
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.function.Supplier;
public class JaxRsKeycloakClientExample {
public static void main(String[] args) throws Exception {
String realmName = "token-test";
String tokenPath = "/protocol/openid-connect/token";
String userInfoPath = "/protocol/openid-connect/userinfo";
String authServerBaseUrl = "http://localhost:8081/auth/realms";
/* Dummy accessToken provider - in real Keycloak integrations you'd
extract the current AccessToken
* from the KeycloakSecurity context which is accessible via:
*
httpServletRequest.getAttribute(KeycloakSecurityContext.class.getName());
* or
*
httpServletRequest.getSession().getAttribute(KeycloakSecurityContext.class.getName());
*
* then do KeycloakSecurityContext#getTokenString()
*/
Supplier<String> accessTokenProvider = () -> {
Client keycloakClient = ClientBuilder.newBuilder().build();
WebTarget target =
keycloakClient.target(UriBuilder.fromUri(authServerBaseUrl).path(realmName).path(tokenPath).build());
Form getTokenForm = new Form() //
.param("client_id", "admin-cli") //
.param("client_secret", "") //
.param("username", "tester") //
.param("password", "test") //
.param("grant_type", "password") //
;
Future<Map> response =
target.request(MediaType.APPLICATION_FORM_URLENCODED) //
.accept(MediaType.APPLICATION_JSON_TYPE) //
.buildPost(Entity.form(getTokenForm)) //
.submit(Map.class);
try {
Map map = response.get();
return String.valueOf(map.get("access_token"));
} catch (Exception e) {
throw new RuntimeException(e);
}
};
Client client = ClientBuilder.newBuilder().build();
client.register(new KeycloakAuthRequestFilter(accessTokenProvider));
//Call UserInfo endpoint with AccessToken in Authorization Header
WebTarget target =
client.target(UriBuilder.fromUri(authServerBaseUrl).path(realmName).path(userInfoPath).build());
Response response =
target.request().accept(MediaType.APPLICATION_JSON_TYPE).get();
System.out.println(response.readEntity(Map.class));
}
public static class KeycloakAuthRequestFilter implements
ClientRequestFilter {
private final Supplier<String> accessTokenProvider;
public KeycloakAuthRequestFilter(Supplier<String> accessTokenProvider) {
this.accessTokenProvider = accessTokenProvider;
}
@Override
public void filter(ClientRequestContext requestContext) throws
IOException {
requestContext.getHeaders().putSingle("Authorization", "Bearer
" +
accessTokenProvider.get());
}
}
}
2017-05-22 8:14 GMT+02:00 Peter Donald <peter(a)realityforge.org>:
>
> Hi,
>
> This is a really dumb question and I have tried to google+RTFM but
> still can't seem to find the answer.
>
> I am looking for a simple example where I can use a jaxrs client to
> access a service protected by keycloak. I have only really found
> references to admin-client which seems to be more about admin of
> keycloak and the JaxrsBearerTokenFilterImpl which seems like it may
> work but can't find an example where it is used or how I would go
> about it.
>
> Preferably I would like to do a .register( X ) when creating the jaxrs
> client and have it handled automagically by a filter. I don't have
> resteasy available atm if that makes a difference.
>
> Any hints on where to figure this out?
>
> --
> Cheers,
>
> Peter Donald
> _______________________________________________
> keycloak-user mailing list
> keycloak-user(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/keycloak-user
--
Cheers,
Peter Donald