3

I have a spring client with spring rest api's which are protected with keycloak. I am trying to call it using keycloakresttemplate from another client which is a pure java code with no security. I am getting the keycloak access token from java client and setting it in the header of rest url. It is not able to initialize the keycloakresttemplate.

Any view why I am facing this issue.

//Below is the code to hit the spring url using keycloakresttemplate.I have added Dependency of keycloack adapter and added the bean in my java class.

restTemplate.getForObject(<restapiURL>, class1, requestData);

//Below is the code I am using for getting the access token from keycloak

MultiValueMap<String,String> requestMap = new LinkedMultiValueMap<String,String>();
requestMap.add("client_id", "employee-service");
requestMap.add("username", "rachel");
requestMap.add("password", "rachel");
requestMap.add("grant_type", "password");
requestMap.add("client_secret", "cccebf50-3f28-4af2-8716-c4bfcfe6f5e7");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);   
HttpEntity<MultiValueMap<String, String>> requestData = new HttpEntity<>(requestMap, headers);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new FormHttpMessageConverter());
String restApiurl = "http://localhost:8080/auth/realms/dev/protocol/openid-connect/token" ;
return restTemplate.postForObject(restApiurl, requestData, AccessTokenResponse.class);

Keycloak Setup for client: KeycloakSetup

Myworkspace structure Java Client Java Client Structure

Java Client2: REST API app structure

I have added one way ,a s per your suggestion in comment section and the other way,

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;
import javax.ws.rs.InternalServerErrorException;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.TrustStrategy;
import org.keycloak.adapters.springsecurity.client.KeycloakClientRequestFactory;
import org.keycloak.adapters.springsecurity.client.KeycloakRestTemplate;
import org.keycloak.authorization.client.AuthzClient;
import org.keycloak.representations.idm.authorization.AuthorizationResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import com.dbaas.webagent.model.Employee;

public class KeycloakAgentClient {

    @Autowired
    KeycloakRestTemplate restTemplate;


    //RestTemplate restTemplate;
    public static final String REQUEST_URI = "http://localhost:8086/dbaasrest/addressService/getEmployees";
    public static void main(String[] args) throws KeyManagementException, KeyStoreException, NoSuchAlgorithmException {

        AuthzClient authzClient = AuthzClient.create();
        AuthorizationResponse response = authzClient.authorization("rachel", "rachel").authorize();

        String rpt = response.getToken();
        System.out.println("You got an RPT: " + rpt);


        KeycloakAgentClient client = new KeycloakAgentClient();
        List<Employee> list = client.getEmployeeList(rpt, new RestTemplate());
        System.out.println("Employee List:***"+list);

    }

    private List<Employee> getEmployeeList(String accessToken, RestTemplate restTemplate) {

        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer "+accessToken);

        HttpEntity<?> requestEntity = new HttpEntity<>(headers);
        //restTemplate.getInterceptors().add((ClientHttpRequestInterceptor) new BasicAuthentication("rachel","rachel"));
        ResponseEntity<ArrayList> response = restTemplate.exchange(REQUEST_URI, HttpMethod.GET, requestEntity, ArrayList.class);
        System.out.println("****"+response.getBody());
        return response.getBody();
    }

    private List<Employee> callKeycloakProtectedAPI(HttpHeaders headers, RestTemplate restTemplate) {
        UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(REQUEST_URI);
        String url = builder.toUriString();

        //RestTemplate restTemplate = new RestTemplate();
         try {
                HttpEntity<Map<String,String>> requestEntity = new HttpEntity<>(headers);
                ResponseEntity<ArrayList> response = restTemplate.exchange(REQUEST_URI, HttpMethod.GET, requestEntity, ArrayList.class);

                if (response.getStatusCode().is2xxSuccessful()) {
                    return (List<Employee>) response;
                }
                System.out.println("Error response while getting response"+ response);
               throw new InternalServerErrorException("");

            } catch (Exception exp) {
                System.out.println("Exception while getting response"+exp);
               throw new InternalServerErrorException("");
            }


    }

}

3 Answers3

1

Looks the same apart from restTemplate.postForEntity(), not postForObject()

Let me share code we have, with login, logout and refresh token:

import lombok.extern.slf4j.Slf4j;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.TrustStrategy;
import org.keycloak.RSATokenVerifier;
import org.keycloak.common.VerificationException;
import org.keycloak.exceptions.TokenNotActiveException;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.LinkedHashMap;

@Component
public class KeyCloakServiceImpl implements KeyCloakService {

private RestTemplate restTemplate;

private final KeyCloakConnectionProvider keyCloakConnectionProvider;

public KeyCloakServiceImpl(KeyCloakConnectionProvider keyCloakConnectionProvider,
                           RestTemplateBuilder restTemplateBuilder) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {

    this.keyCloakConnectionProvider = keyCloakConnectionProvider;

    TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
    SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
            .loadTrustMaterial(null, acceptingTrustStrategy)
            .build();
    SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);

    CloseableHttpClient httpClient = HttpClients.custom()
            .setSSLSocketFactory(csf)
            .build();

    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    requestFactory.setHttpClient(httpClient);

    this.restTemplate = restTemplateBuilder
            .requestFactory(requestFactory)
            .messageConverters(new MappingJackson2HttpMessageConverter(), new FormHttpMessageConverter())
            .build();
}

private AccessToken getAccessToken(String accessToken, boolean checkActive) throws VerificationException, NoSuchFieldException {
    try {
        PublicKey publicKey = getPublicKey();
        if (publicKey != null) {
            String realmUrl = keyCloakConnectionProvider.getRealmUrl();
            AccessToken token =
                    RSATokenVerifier.verifyToken(
                            accessToken,
                            publicKey,
                            realmUrl,
                            checkActive,
                            true);

            return token;
        } else {
            log.error("KeyCloakServiceImpl:verifyToken: SSO_PUBLIC_KEY is NULL.");
            throw new NoSuchFieldException("KeyCloakServiceImpl:verifyToken: SSO_PUBLIC_KEY is NULL.");
        }
    } catch (TokenNotActiveException e) {
        throw e;
    } catch (VerificationException e) {
        throw e;
    } catch (NoSuchFieldException e) {
        throw e;
    } catch (Exception e) {
        throw e;
    }
}

@Override
public AccessToken loadAccessToken(String accessToken) throws TokenNotActiveException, VerificationException, NoSuchFieldException {
    return getAccessToken(accessToken, true);
}

@Override
public AccessToken loadAccessTokenFromRefreshToken(String accessToken) throws TokenNotActiveException, VerificationException, NoSuchFieldException {
    return getAccessToken(accessToken, false);
}

/**
 * This method will call keycloak service to user login. after successful login it will provide
 * access token.
 */
@Override
public AccessTokenResponse login(String username, String password) {
    try {
        MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
        requestParams.add("client_id", keyCloakConnectionProvider.getResource());
        requestParams.add("username", username);
        requestParams.add("password", password);
        requestParams.add("grant_type", "password");
        requestParams.add("client_secret", keyCloakConnectionProvider.getClientSecret());
        requestParams.add("scope", "openid");


        AccessTokenResponse keycloakAccessToken = queryKeycloakByParams(requestParams);

        return keycloakAccessToken;
    } catch (Exception e) {
        log.info(e.getMessage(), e);
        throw e;
    }
}

@Override
public AccessTokenResponse refresh(String refreshToken) {
    try {
        MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
        requestParams.add("client_id", keyCloakConnectionProvider.getResource());
        requestParams.add("grant_type", "refresh_token");
        requestParams.add("client_secret", keyCloakConnectionProvider.getClientSecret());
        requestParams.add("refresh_token", refreshToken);

        AccessTokenResponse keycloakAccessToken = queryKeycloakByParams(requestParams);

        return keycloakAccessToken;
    } catch (Exception e) {
        log.info(e.getMessage(), e);
        throw e;
    }
}

private AccessTokenResponse queryKeycloakByParams(MultiValueMap<String, String> requestParams) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(requestParams, headers);

    String url = keyCloakConnectionProvider.getOpenIdConnectTokenUrl();

    AccessTokenResponse keycloakAccessToken = getAccessTokenResponse(request, url);

    return keycloakAccessToken;
}

private AccessTokenResponse getAccessTokenResponse(HttpEntity<MultiValueMap<String, String>> request, String url) {
    try {
        ResponseEntity<AccessTokenResponse> response = restTemplate.postForEntity(url, request, AccessTokenResponse.class);
        return response.getBody();
    } catch (ResourceAccessException e) {
        log.error("KeyCloak getAccessTokenResponse: " + e.getMessage());
        try {
            ResponseEntity<AccessTokenResponse> response = restTemplate.postForEntity(url, request, AccessTokenResponse.class);
            return response.getBody();
        } catch (Exception ex) {
            throw ex;
        }
    } catch (Exception e) {
        throw e;
    }
}

@Override
public void logout(String refreshToken) {
    try {
        MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
        requestParams.add("client_id", keyCloakConnectionProvider.getResource());
        requestParams.add("client_secret", keyCloakConnectionProvider.getClientSecret());
        requestParams.add("refresh_token", refreshToken);

        logoutUserSession(requestParams);

    } catch (Exception e) {
        log.info(e.getMessage(), e);
        throw e;
    }
}

private void logoutUserSession(MultiValueMap<String, String> requestParams) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(requestParams, headers);

    String url = keyCloakConnectionProvider.getOpenIdConnectLogoutUrl();

    restTemplate.postForEntity(url, request, Object.class);
}

private PublicKey getPublicKey() {
    PublicKey publicKey = keyCloakConnectionProvider.getPublicKey();
    if (publicKey == null) {
        LinkedHashMap publicKeyMap = requestKeyFromKeycloak(keyCloakConnectionProvider.getOpenIdConnectCertsUrl());
        publicKey = KeyCloakRsaKeyLoader.getPublicKeyFromKeyCloak(publicKeyMap);
        keyCloakConnectionProvider.setPublicKey(publicKey);
    }
    return publicKey;
}

/**
 * This method will connect to keycloak server using API call for getting public key.
 *
 * @param url A string value having keycloak base URL
 * @return Public key JSON response string
 */
private LinkedHashMap requestKeyFromKeycloak(String url) {
    try {
        ResponseEntity<LinkedHashMap> response = restTemplate.getForEntity(url, LinkedHashMap.class);
        LinkedHashMap body = response.getBody();

        if (body != null) {
            return body;
        } else {
            log.error("KeyCloakRsaKeyLoader:requestKeyFromKeycloak: Not able to fetch SSO public key from keycloak server");
        }
    } catch (Exception e) {
        log.error("KeyCloakRsaKeyLoader:requestKeyFromKeycloak: Exception occurred with message = " + e.getMessage());
    }
    return null;
}
}


import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.keycloak.adapters.springboot.KeycloakSpringBootProperties;
import org.springframework.stereotype.Component;

import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
@AllArgsConstructor
public class KeyCloakConnectionProvider {

private static final Map<String, PublicKey> cache = new HashMap<>();
public static final String PUBLIC_KEY = "publicKey";

private KeycloakSpringBootProperties keycloakProperties;

public String getAuthServerUrl() {
    return keycloakProperties.getAuthServerUrl();
}

public String getRealmUrl() {
    return getAuthServerUrl()
            + "/realms/"
            + getRealm();
}

public String getOpenIdConnectUrl() {
    return getRealmUrl() + "/protocol/openid-connect";
}

public String getOpenIdConnectTokenUrl() {
    return getOpenIdConnectUrl() + "/token";
}

public String getOpenIdConnectLogoutUrl() {
    return getOpenIdConnectUrl() + "/logout";
}

public String getOpenIdConnectCertsUrl() {
    return getOpenIdConnectUrl() + "/certs";
}

public String getRealm() {
    return keycloakProperties.getRealm();
}

public String getResource() {
    return keycloakProperties.getResource();
}

public String getClientId() {
    return getResource();
}

public String getClientSecret() {
    return String.valueOf(keycloakProperties.getCredentials().get("secret"));
}

public int getConnectionPoolSize() {
    return keycloakProperties.getConnectionPoolSize();
}

public PublicKey getPublicKey() {
    return cache.get(PUBLIC_KEY);
}

public PublicKey setPublicKey(PublicKey publicKey) {
    if (publicKey != null) {
        cache.put(PUBLIC_KEY, publicKey);
    }
    return getPublicKey();
}
}


import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.util.*;
import java.util.Base64.Decoder;

/**
 * Class to fetch SSO public key from Keycloak server using 'certs' HTTP API call.
 */
@Slf4j
public class KeyCloakRsaKeyLoader {
    private static final String MODULUS = "modulusBase64";
    private static final String EXPONENT = "exponentBase64";
    private static final ObjectMapper mapper = new ObjectMapper();

    /**
     * This method will accept keycloak base URL and realm name. Based on provided values it will
     * fetch public key from keycloak.
     *
     * @param publicKeyMap A string value having keycloak public key as string
     * @return Public key used to verify user access token.
     */
    public static PublicKey getPublicKeyFromKeyCloak(LinkedHashMap publicKeyMap) {
        try {
            Decoder urlDecoder = Base64.getUrlDecoder();
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            if (publicKeyMap != null) {
                Map<String, String> valueMap = getValuesFromMap(publicKeyMap);
                if (valueMap != null) {
                    BigInteger modulus = new BigInteger(1, urlDecoder.decode(valueMap.get(MODULUS)));
                    BigInteger publicExponent = new BigInteger(1, urlDecoder.decode(valueMap.get(EXPONENT)));

                    PublicKey publicKey = keyFactory.generatePublic(new RSAPublicKeySpec(modulus, publicExponent));

                    return publicKey;
                }
            }
        } catch (Exception e) {
            log.error("KeyCloakRsaKeyLoader:getPublicKeyFromKeyCloak: Exception occurred with message = " + e.getMessage());
        }
        return null;
    }


    /**
     * This method will return a map containing values extracted from public key JSON string.
     *
     * @param publicKeyMap Public key map response
     */
    private static Map<String, String> getValuesFromMap(LinkedHashMap publicKeyMap) {
        try {
            Map<String, String> values = new HashMap<>();
            ArrayList keys = (ArrayList) publicKeyMap.get("keys");
            if (keys != null && keys.size() > 0) {
                LinkedHashMap value = (LinkedHashMap) keys.get(0);
                values.put(MODULUS, (String) value.get("n"));
                values.put(EXPONENT, (String) value.get("e"));
            }
            return values;
        } catch (Exception e) {
            log.error("KeyCloakRsaKeyLoader:getValuesFromJson: Exception occurred with message = " + e.getMessage());
        }
        return null;
    }
}
Dmitri Algazin
  • 3,332
  • 27
  • 30
  • Thank you for the above solution.I will implement the same and reply back.Meanwhile I have one query related to this. My client1 is pure java application with main method and client to is spring rest(without spring boot).Client2 is protected by Keycloak. Once I will login, using above code you have given, can I call Client2 api using spring rest or KeycloakRestTemplate.?Currently when I am using spring rest template I am getting 403 forbidden error. – Sai Satyamayee Nov 14 '19 at 12:40
  • What is KeyCloakRsaKeyLoader. and Instead of RestTemplateBuilder can I sue RestTemplate,as I am not using spring boot application – Sai Satyamayee Nov 15 '19 at 07:05
  • I am getting 401 unauthorized error now. Please check below code snippet. Client2, which is a spring rest api. – Sai Satyamayee Nov 15 '19 at 09:25
  • regarding 401, try to call second client from Postman, if that works, when issue is in code, if not, something else – Dmitri Algazin Nov 15 '19 at 14:11
  • When I hit the API from Postman, with user name, password and set the cookie with token string , it responds back with status 200. I am not using SpringBoot, What can I use instead of RestTemplateBuilder – Sai Satyamayee Nov 18 '19 at 10:33
  • I have edited the original question with implementation class and keycloak setup too.Could you please check, what is wrong in this – Sai Satyamayee Nov 18 '19 at 12:13
  • can't check your stuff as you are using different settings and I changed projects. I tell you one think: there are no magic with keycloak:) if you can get it responding in postman, means it works, just debug your code and see what are you getting at each step. use Spring Boot starter project as soon as possible, and reuse code I send you. – Dmitri Algazin Nov 19 '19 at 09:51
  • It is giving me login page with status code-200, OK when I try to hit using Postman.Even from Code also, the same thing. It is not automatically authenticating the user, even I have passed the access token in the header. My client wants it with pure java code with Spring Boot. – Sai Satyamayee Nov 19 '19 at 12:24
  • @Dimitri Algazin, worked out after setup of audience. for the client. https://stackoverflow.com/questions/53550321/keycloak-gatekeeper-aud-claim-and-client-id-do-not-match – Sai Satyamayee Nov 28 '19 at 09:40
0

Regarding calling client2 from client1, take AUTHORIZATION header from client1 first request and include that in to query to client2. Like:

// Client 1
@RequestMapping(value = "/some-api", method = RequestMethod.POST) // or GET
public ResponseEntity<SomeDto> processSomething(@RequestHeader(HttpHeaders.AUTHORIZATION) String authHeader) {

    HttpHeaders headers = new HttpHeaders();
    if (authHeader != null) {
        headers.add(AUTHORIZATION_HEADER, authHeader);
    }

    SomeDto dto = someService.processSomething(headers);

    return ResponseEntity.ok(dto);
}


// client1 someService
RestTemplate restTemplate = new RestTemplate();

public List<YourDto> getBla(HttpHeaders headers) {

    String path = "/client2/api";
    UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(path);
    String url = builder.toUriString();

    try {
        HttpEntity<?> requestEntity = new HttpEntity<>(headers);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);

        if (response.getStatusCode().is2xxSuccessful()) {
            return objectMapper.readValue(response.getBody(), new TypeReference<List<YourDto>>() {}).apply(response);
        }
        log.error("Error response while getting blabla", response);
        throw new InternalServerException("");

    } catch (HttpRestClientException | ResourceAccessException exp) {
        log.error("Exception while getting blabla", exp);
        throw new InternalServerException("");
    }
}
Dmitri Algazin
  • 3,332
  • 27
  • 30
0

I am getting 401 unauthorized error now. Please check below code snippet. Client2, which is a spring rest api. RestController of spring, these api's are protected by keycloak.when I hit any of the api from browser, I get a keycloak login page and on successful authentication, it gives back response.package com.dbaas.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

    @RestController
    public class DBaaSRestController {

    @RequestMapping(value="/",method=RequestMethod.GET)
    public String getHomePage(){
        return "This is the home page";
    }

    @RequestMapping(value="/login",method=RequestMethod.GET)    
    public String getMessage(){
        return "admin";
    }

    @RequestMapping(value="/addressService/getEmployees",method=RequestMethod.GET,headers="Accept=application/json")
    public List<Employee> getAllEmployees() throws IOException{


        //getClientDetails();

        List<Employee> employeeList = new ArrayList<Employee>();
        employeeList=createEmployees();
        return employeeList;
    }

    @RequestMapping(value = "/addressService/getEmployee/{id}", method = RequestMethod.GET,headers="Accept=application/json")
    public Employee getCountryById(@PathVariable int id)
    {
        List<Employee> employeesList = new ArrayList();
        employeesList=createEmployees();

        for (Employee emp: employeesList) {
            if(emp.getId()==id)
                return emp;
        }

        return null;
    }

    public List<Employee> createEmployees()
    {
        Employee emp1=new Employee(1, "E1");
        Employee emp2=new Employee(4, "E2");
        Employee emp3=new Employee(3, "E3");
        Employee emp4=new Employee(2, "E4");

        List<Employee> employeeList = new ArrayList<Employee>();
        employeeList.add(emp1);
        employeeList.add(emp2);
        employeeList.add(emp3);
        employeeList.add(emp4);
        return employeeList;
    }
}

Now instead of accessing it directly from browser, I am trying to access it using a java client.

Client1.(Java Client)

    public class KeycloakAgentClient {

    RestTemplate restTemplate;
    public static final String REQUEST_URI = "http://localhost:8086/dbaasrest/addressService/getEmployees";
    public static void main(String[] args) throws KeyManagementException, KeyStoreException, NoSuchAlgorithmException {
        KeycloakAgentClient client = new KeycloakAgentClient();
        KeyCloakServiceImpl impl = new KeyCloakServiceImpl();
        AccessTokenResponse accessTokenResponse = new AccessTokenResponse();
        accessTokenResponse = impl.login("rachel", "rachel");
        String accessToken = accessTokenResponse.getToken();
        List<Employee> list = client.getEmployeeList(accessToken);
        System.out.println("Employee List:***"+list);
    }

    private List<Employee> getEmployeeList(String accessToken) {

        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer "+accessToken);

        List<Employee> empList= callKeycloakProtectedAPI(headers);

        return empList;
    }

    private List<Employee> callKeycloakProtectedAPI(HttpHeaders headers) {
        UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(REQUEST_URI);
        String url = builder.toUriString();
        RestTemplate restTemplate = new RestTemplate();
         try {
                HttpEntity<Map<String,String>> requestEntity = new HttpEntity<>(headers);
                ResponseEntity<ArrayList> response = restTemplate.exchange(REQUEST_URI, HttpMethod.GET, requestEntity, ArrayList.class);

                if (response.getStatusCode().is2xxSuccessful()) {
                    return (List<Employee>) response;
                }
                System.out.println("Error response while getting response"+ response);
               throw new InternalServerErrorException("");

            } catch (Exception exp) {
                System.out.println("Exception while getting response"+exp);
               throw new InternalServerErrorException("");
            }       
    }
}

KeycloakServiceImpl as per answer provided by you.

    public class KeyCloakServiceImpl implements KeyCloakService{
    private RestTemplate restTemplate;

    //private final KeyCloakConnectionProvider keyCloakConnectionProvider;

    public KeyCloakServiceImpl(/*KeyCloakConnectionProvider keyCloakConnectionProvider,*/
                               /*RestTemp restTemplateBuilder*/) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {

        //this.keyCloakConnectionProvider = keyCloakConnectionProvider;

        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
        SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
                .loadTrustMaterial(null, acceptingTrustStrategy)
                .build();
        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);

        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(csf)
                .build();

        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);

        this.restTemplate = new RestTemplate();/*restTemplateBuilder
                .requestFactory(requestFactory)
                .messageConverters(new MappingJackson2HttpMessageConverter(), new FormHttpMessageConverter())
                .build();*/
    }


    private AccessToken getAccessToken(String accessToken, boolean checkActive) throws VerificationException, NoSuchFieldException {
       /* try {
            PublicKey publicKey = getPublicKey();
            if (publicKey != null) {
                String realmUrl = keyCloakConnectionProvider.getRealmUrl();
                String realmUrl = "";
                AccessToken token =
                        RSATokenVerifier.verifyToken(
                                accessToken,
                                publicKey,
                                realmUrl,
                                checkActive,
                                true);

                return token;
            } else {
                System.out.println("KeyCloakServiceImpl:verifyToken: SSO_PUBLIC_KEY is NULL.");
                throw new NoSuchFieldException("KeyCloakServiceImpl:verifyToken: SSO_PUBLIC_KEY is NULL.");
            }
        } catch (TokenNotActiveException e) {
            throw e;
        } catch (VerificationException e) {
            throw e;
        } catch (NoSuchFieldException e) {
            throw e;
        } catch (Exception e) {
            throw e;
        }*/
        return null;
    }

    @Override
    public AccessToken loadAccessToken(String accessToken) throws TokenNotActiveException, VerificationException, NoSuchFieldException {
        return getAccessToken(accessToken, true);
    }

    @Override
    public AccessToken loadAccessTokenFromRefreshToken(String accessToken) throws TokenNotActiveException, VerificationException, NoSuchFieldException {
        return getAccessToken(accessToken, false);
    }

    /**
     * This method will call keycloak service to user login. after successful login it will provide
     * access token.
     */
    @Override
    public AccessTokenResponse login(String username, String password) {
        try {
            MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
           /* requestParams.add("client_id", keyCloakConnectionProvider.getResource());*/
            requestParams.add("client_id", "employee-service");
            requestParams.add("username", username);
            requestParams.add("password", password);
            requestParams.add("grant_type", "password");
            requestParams.add("client_secret", "cccebf50-3f28-4af2-8716-c4bfcfe6f5e7");
            requestParams.add("scope", "openid");


            AccessTokenResponse keycloakAccessToken = queryKeycloakByParams(requestParams);

            return keycloakAccessToken;
        } catch (Exception e) {
           System.out.println("login **** "+e.getMessage());
            throw e;
        }
    }

    @Override
    public AccessTokenResponse refresh(String refreshToken) {
        try {
            MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
          /*  requestParams.add("client_id", keyCloakConnectionProvider.getResource());*/
            requestParams.add("client_id", "");
            requestParams.add("grant_type", "refresh_token");
           /* requestParams.add("client_secret", keyCloakConnectionProvider.getClientSecret());*/
            requestParams.add("client_secret", "");
            requestParams.add("refresh_token", refreshToken);

            AccessTokenResponse keycloakAccessToken = queryKeycloakByParams(requestParams);

            return keycloakAccessToken;
        } catch (Exception e) {
            /*log.info(e.getMessage(), e);*/
            System.out.println("refresh**** "+e.getMessage());
            throw e;
        }
    }

    private AccessTokenResponse queryKeycloakByParams(MultiValueMap<String, String> requestParams) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(requestParams, headers);

        /*String url = keyCloakConnectionProvider.getOpenIdConnectTokenUrl();*/
        String url = "http://localhost:8080/auth/realms/dev/protocol/openid-connect/token";

        AccessTokenResponse keycloakAccessToken = getAccessTokenResponse(request, url);

        return keycloakAccessToken;
    }

    private AccessTokenResponse getAccessTokenResponse(HttpEntity<MultiValueMap<String, String>> request, String url) {
        try {
            ResponseEntity<AccessTokenResponse> response = restTemplate.postForEntity(url, request, AccessTokenResponse.class);
            return response.getBody();
        } catch (ResourceAccessException e) {
            /*log.error("KeyCloak getAccessTokenResponse: " + e.getMessage());*/
            System.out.println("KeyCloak getAccessTokenResponse: " + e.getMessage());
            try {
                ResponseEntity<AccessTokenResponse> response = restTemplate.postForEntity(url, request, AccessTokenResponse.class);
                return response.getBody();
            } catch (Exception ex) {
                throw ex;
            }
        } catch (Exception e) {
            throw e;
        }
    }

    @Override
    public void logout(String refreshToken) {
        try {
            MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
            /*requestParams.add("client_id", keyCloakConnectionProvider.getResource());
            requestParams.add("client_secret", keyCloakConnectionProvider.getClientSecret());*/
            requestParams.add("client_id", "");
            requestParams.add("client_secret", "");
            requestParams.add("refresh_token", refreshToken);

            logoutUserSession(requestParams);

        } catch (Exception e) {
            /*log.info(e.getMessage(), e);*/
            System.out.println("KeyCloak logout: " + e.getMessage());
            throw e;
        }
    }

    private void logoutUserSession(MultiValueMap<String, String> requestParams) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(requestParams, headers);

       /* String url = keyCloakConnectionProvider.getOpenIdConnectLogoutUrl();*/
        String url = "";
        restTemplate.postForEntity(url, request, Object.class);
    }

    /*private PublicKey getPublicKey() {
        PublicKey publicKey = keyCloakConnectionProvider.getPublicKey();
        PublicKey publicKey = keyCloakConnectionProvider.getPublicKey();
        if (publicKey == null) {
            LinkedHashMap publicKeyMap = requestKeyFromKeycloak(keyCloakConnectionProvider.getOpenIdConnectCertsUrl());
            LinkedHashMap publicKeyMap = requestKeyFromKeycloak("");
            publicKey = KeyCloakRsaKeyLoader.getPublicKeyFromKeyCloak(publicKeyMap);
            keyCloakConnectionProvider.setPublicKey(publicKey);
        }
        return publicKey;
    }*/

    /**
     * This method will connect to keycloak server using API call for getting public key.
     *
     * @param url A string value having keycloak base URL
     * @return Public key JSON response string
     */
    private LinkedHashMap requestKeyFromKeycloak(String url) {
        try {
            ResponseEntity<LinkedHashMap> response = restTemplate.getForEntity(url, LinkedHashMap.class);
            LinkedHashMap body = response.getBody();

            if (body != null) {
                return body;
            } else {
                /*log.error("KeyCloakRsaKeyLoader:requestKeyFromKeycloak: Not able to fetch SSO public key from keycloak server");*/
                System.out.println("KeyCloakRsaKeyLoader:requestKeyFromKeycloak: Not able to fetch SSO public key from keycloak server");
            }
        } catch (Exception e) {
           /* log.error("KeyCloakRsaKeyLoader:requestKeyFromKeycloak: Exception occurred with message = " + e.getMessage());*/
            System.out.println("KeyCloakRsaKeyLoader:requestKeyFromKeycloak: Exception occurred with message =  " + e.getMessage());
        }
        return null;
    }
}

Now getting "Exception while getting response org.springframework.web.client.HttpClientErrorException: 401 Unauthorized" not sure, even if I am sending the access token, why it is not authorizing the user