Serverside Authenticate Keycloak user programmatically in Java with Bearer token
Asked Answered
T

1

6

I want to authenticate a User in my Java REST endpoint using Keycloak and a Bearer token.

The workflow I want to achieve is the following:

  1. The client logs to Keycloak with Username and Password.
  2. Keycloak returns a Bearer token (a JWT one if I'm not wrong, how can I check?).
  3. The client performs an Http request with 'Authorization' : 'Bearer <token>' header.
  4. The REST endpoint (written in Java) checks if the received token is correct and authenticates the User receiving a Principal from Keycloak (if I understand correctly).
  5. Once authenticated, the endpoint will check if User has permission to access that REST api and send back a response.

1, 2, 3 and 5 are already implemented and working but i can't find a way to implement 4.

I have already tried different ways:

  • My Java endpoint is running in a EAR published on WildFly 10.x so I used a security-constraint in my web.xml and configured Keycloak via keycloak.json.
    This works fine but I need to leave some REST endpoints public (accessible even without an 'Authorization' header) in the same web context and as far as I know there is no way to filter only some requests in my security-constraint.

  • I tried implementing a BearerTokenRequestAuthenticator with absolutely no success and even if I could I don't think I would receive a Principal as result of my authentication request.

Right now i have already implemented a way to filter the requests and the ones that require authentication are intercepted by a ServiceSecurityInterceptor class I implemented.

At some point in that class I check if the 'Authorization' header contains a Basic or Bearer :

User loggedUser = null;
if (authorizationType.equals("Basic")) {

    // ... decode Base64 username and password ...

    loggedUser = userManagerBean.login(username, password);

} else if (authorizationType.equals("Bearer")) {

   String token = ...; // Get token from header

   // ... Here is where I need to send the token to Keycloak and receive a Principal with the username ...

   loggedUser = userManagerBean.login(username):

}

I read in some places that I probably need a public key from my Keycloak realm but once I have it, what should I do?

Tasman answered 23/4, 2018 at 10:37 Comment(0)
D
0

A few months ago we have introduced Keycloak. The trick is to let Keycloak do the work for you. I guess you are using OpenId connect? Have a look at these Java-Adapters. Maybe this one could handle the url pattern matching for you.

For my self I prefer to use Spring boot security with keycloak. The Keycloak Spring Boot Adapter integrates well with Java applications. You just have to do some config in the Java app and on Keycloak server. The Authentication process is handled automatically by KeyCloak and Keycloak Adapter. With Spring boot you can als create a ear package for your WildFly Server. The KeyCloakPrincipial is automatically created within Springs security context (SecurityContextHolder.getContext().getAuthentication().getPrincipal())

Derian answered 25/7, 2018 at 17:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.