Login to Keycloak using API

62,829

Solution 1

You are effectively asking your users to trust that Application1 will manage their keycloak credentials securely. This is not recommended because

  1. better security is achieved if the user is redirected to keycloak to enter their credentials. In an ideal world no client application should be handling or have access to user credentials.
  2. It defeats the purpose of single sign in where a user should only need to enter their credentials for the first application they need to access (provided their session has not expired)

But if you control and can trust Application1 and need to do this due to legacy or other reasons then you can enable the Resource Owner Credentials Flow called "Direct Access" on the Keycloak Client Definition, and then POST the user's credentials as a form-urlencoded data type to

https://<keycloak-url>/auth/realms/<realm>/protocol/openid-connect/token

The paramaters will be

grant_type=password
client_id=<Application1's client id>
client_secret=<the client secret>
username=<the username>
password=<the password>
scope=<space delimited list of scope requests>

The response will be a valid JWT object or a 4xx error if the credentials are invalid.

Solution 2

If I got your question correctly you are trying to call a bearer-only service through another application that's already logged in, you also didn't mention if you are using Spring Boot or another framework like it, so I'll suppose that you are using the Spring Boot for your server-side application.

The following example reflects into a simple call of an authenticated API to another one, both using Spring Boot:

import org.keycloak.KeycloakPrincipal;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

@Component
public class AnotherServiceClient {
    public TypeOfObjectReturnedByAnotherService getFromAnotherService() {
        RestTemplate restTemplate = new RestTemplate();
        String endpoint = "http://localhost:40030/another/service/url";
        String bearerToken = getAuthorizationToken();

        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "bearer " + bearerToken);

        HttpEntity entity = new HttpEntity(headers);

        ResponseEntity<TypeOfObjectReturnedByAnotherService> response = restTemplate.exchange(endpoint, HttpMethod.GET, entity, TypeOfObjectReturnedByAnotherService.class);

        return response.getBody();
    }

    private String getAuthorizationToken() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        SimpleKeycloakAccount details = (SimpleKeycloakAccount) authentication.getDetails();

        KeycloakPrincipal<?> keycloakPrincipal = (KeycloakPrincipal<?>) details.getPrincipal();

        RefreshableKeycloakSecurityContext context = (RefreshableKeycloakSecurityContext) getPrincipal().getKeycloakSecurityContext();

        return context.getTokenString();
    }
}

By that way is possible to send the actual valid token generated by your origin service to another service.

Solution 3

YES- You can login to the Application-1 with out using keycloak login interface.

Various client adapters are available for achieving this. here you didn't mentioned your application frame work.

To know more about the keyclaok client adapters : click here

For example if you are choosing Node.js adapter then you can follow the link : node.js adapter

keycloak implementation with node.js adapter, details about the REST api's and token validation mechanism are well explained in this link click for example

Share:
62,829
Akhil Prajapati
Author by

Akhil Prajapati

Updated on May 19, 2021

Comments

  • Akhil Prajapati
    Akhil Prajapati almost 3 years

    I have 2 different applications: say Application1 and Application2.

    1. I have integrated Application2 with keycloak and I am able to login to this application using Keycloak's login page.

    2. Now what I want is, if I login to my Application1 (without keycloak), I should be able to call some API of keycloak to login to application2 (without rendering keycloak's login page).

    It is feasible? If yes, how?

    Any help will be highly appreciated.

    Thanks

  • Akhil Prajapati
    Akhil Prajapati over 6 years
    Thanks shonky. I was able to get a response from the REST service you just mentioned. I am getting access token, refresh token and few other parameters. However, I am still not able to login directly to the keycloak server. Am I missing something?
  • Anunay
    Anunay over 6 years
    The above api will give you an access token, which you can use to make a call to your application2. If you have access token and are getting 401 check if you are passing it correctly (Bearer AccessToken) and if so check the logs on the app2 side. if you are getting 403 issue is with the roles and access list. Just to point out the above approach will not give you access to Keycloak server (if you want that then perhaps you need to elaborate more on the use case)
  • Akhil Prajapati
    Akhil Prajapati over 6 years
    @Anunay Thanks for your valuable response. But my doubt still persists. I am asking how do I make a call to Application2 using the access token that I have got.
  • Anunay
    Anunay over 6 years
    If you are making a rest call, in the authorization header pass the token curl http://localhost:8080/service/secured -H "Authorization: bearer $TOKEN" Refer Obtain Token and invoke service
  • Akhil Prajapati
    Akhil Prajapati about 6 years
    I am using Java.
  • Gerros
    Gerros almost 5 years
    for me just using the params grant_type, client_id, username, password worked as well
  • Gerros
    Gerros almost 5 years
    @Anunay for rest calls yes, but what do I have to do to load a web app? Just giving Authorization header still directs me to the login page
  • Anita Nagori
    Anita Nagori about 4 years
    Hello there , by this i am getting below error { "error": "invalid_request", "error_description": "Missing form parameter: grant_type" }
  • Honza Zidek
    Honza Zidek over 2 years
    Could you please have a look at my Keycloak-related question stackoverflow.com/q/70376766/2886891 ? Thanks.