带有Spring应用程序的KeycloakRestTemplate

我有一个带有spring rest api的spring客户端,该api被keycloak保护。 我试图从另一个客户端使用keycloakresttemplate调用它,这是一个没有安全性的纯Java代码。我从Java客户端获取keycloak访问令牌,并将其设置在rest url的标头中。它无法初始化keycloakresttemplate。

任何观点我为什么要面对这个问题。

//下面是使用keycloakresttemplate命中spring url的代码。我已经添加了keycloack适配器的Dependency,并在我的java类中添加了bean。

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

//以下是我用于从密钥斗篷获取访问令牌的代码

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设置: KeycloakSetup

Myworkspace结构 Java客户端 Java Client Structure

Java Client2: REST API app structure

根据您在评论部分的建议,我添加了一种方法 另一种方式,

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,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("");
            }


    }

}
hahahahaha2009 回答:带有Spring应用程序的KeycloakRestTemplate

与restTemplate.postForEntity()相似,而不与postForObject()相似

让我分享我们具有登录,注销和刷新令牌的代码:

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,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,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,AccessTokenResponse.class);
            return response.getBody();
        } catch (Exception ex) {
            throw ex;
        }
    } catch (Exception e) {
        throw e;
    }
}

@Override
public void logout(String refreshToken) {
    try {
        MultiValueMap<String,keyCloakConnectionProvider.getResource());
        requestParams.add("client_secret",refreshToken);

        logoutUserSession(requestParams);

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

private void logoutUserSession(MultiValueMap<String,headers);

    String url = keyCloakConnectionProvider.getOpenIdConnectLogoutUrl();

    restTemplate.postForEntity(url,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;
    }
}
,

关于从client1调用client2,请从client1的第一个请求中获取AUTHORIZATION标头,并将其包含在其中以查询client2。喜欢:

// 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("");
    }
}
,

我现在收到401未经授权的错误。请检查以下代码段。 Client2,这是一个Spring Rest API。春季的RestController,这些api受到keycloak的保护。当我从浏览器中访问任何api时,我都会得到一个keycloak登录页面,并且在成功进行身份验证后会返回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;
    }
}

现在,我正尝试使用Java客户端访问它,而不是直接从浏览器访问它。

Client1。(Java客户端)

    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,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(根据您提供的答案)。

    public class KeyCloakServiceImpl implements KeyCloakService{
    private RestTemplate restTemplate;

    //private final KeyCloakConnectionProvider keyCloakConnectionProvider;

    public KeyCloakServiceImpl(/*KeyCloakConnectionProvider keyCloakConnectionProvider,*/
                               /*RestTemp restTemplateBuilder*/) throws KeyStoreException,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,NoSuchFieldException {
       /* try {
            PublicKey publicKey = getPublicKey();
            if (publicKey != null) {
                String realmUrl = keyCloakConnectionProvider.getRealmUrl();
                String realmUrl = "";
                AccessToken token =
                        RSATokenVerifier.verifyToken(
                                accessToken,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,NoSuchFieldException {
        return getAccessToken(accessToken,true);
    }

    @Override
    public AccessToken loadAccessTokenFromRefreshToken(String accessToken) throws TokenNotActiveException,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","");
            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,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 url) {
        try {
            ResponseEntity<AccessTokenResponse> response = restTemplate.postForEntity(url,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,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",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,headers);

       /* String url = keyCloakConnectionProvider.getOpenIdConnectLogoutUrl();*/
        String url = "";
        restTemplate.postForEntity(url,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;
    }
}

现在收到“获取响应org.springframework.web.client.HttpClientErrorException异常:401未经授权” 不确定,即使我正在发送访问令牌,为什么它没有授权用户

本文链接:https://www.f2er.com/3110071.html

大家都在问