Cómo autenticar un back-end-to-back-end con la primavera de arranque / Keycloak

programmingFox:

Estoy tratando de implementar la autenticación a través de mis servicios de back-end de una aplicación orientada a microService usando Keycloak primavera y de arranque con la primavera de Seguridad y JWT-tokens (portador de ajuste de sólo en Keycloak).

Tengo un servicio de back-end que requiere autenticación para acceder a los puntos finales REST. Este servicio proporciona datos para una interfaz de usuario web y también toma los datos a almacenar en la base de datos para que pueda ser procesada más tarde. Autentificación del usuario en la interfaz de usuario y la interfaz de usuario en contra de que el servicio de back-end ya tanto trabajo.

Luego, hay otro servicio de back-end que ejecuta en segundo plano, el cálculo de los valores que deben estar presentes también en el servicio de back-end mencionado en primer lugar. A medida que uno requiere autenticación, el servicio de hacer los cálculos primero hay que recuperar un token de acceso de Keycloak para la autenticación en el otro servicio de back-end para el puesto de trabajo HTTP.

Estoy tratando de hacer el cargo HTTP con el KeycloakRestTemplate, pero cuando llamo el método .postForObject, me sale una excepción:

Caused by: java.lang.IllegalStateException: Cannot set authorization header because there is no authenticated principal
    at org.keycloak.adapters.springsecurity.client.KeycloakClientRequestFactory.getKeycloakSecurityContext(KeycloakClientRequestFactory.java:70)
    at org.keycloak.adapters.springsecurity.client.KeycloakClientRequestFactory.postProcessHttpRequest(KeycloakClientRequestFactory.java:55)
    at org.springframework.http.client.HttpComponentsClientHttpRequestFactory.createRequest(HttpComponentsClientHttpRequestFactory.java:160)

Parece que el servicio de cálculo no recupera el token de autenticación de forma automática antes de llamar a otro servicio REST. Hice un montón de investigación sobre Google en todas esas clases específicas Keycloak, pero no me entero de lo que tengo que hacer.

¿Puede alguien por favor, dame una pista? Asimismo, no sé qué partes de la configuración de la primavera son relevantes aquí, pero voy a proporcionarles si los necesita.

EDITAR

Mis application.properties de las miradas de servicios de cálculo como esta:

keycloak.auth-server-url=https://localhost/auth
keycloak.realm=myrealm
keycloak.bearer-only=true
keycloak.resource=backend-service2
keycloak.principal-attribute=preferred_username
keycloak.cors=true
keycloak.realm-key=<PUBKEY>
keycloak.credentials.secret=<SECRET_UUID_STYLE>
keycloak.use-resource-role-mappings=true

ACTUALIZAR

Gracias @Sai prateek y @Xtreme motorista. Esto me parece conducir a la dirección correcta.

He aplicado esta solución, pero sigo teniendo una excepción, creo que la configuración keycloak está mal. Tengo tres clientes en keycloak ahora: WebUI, backend-service1, backend-service2.

El webui se configura como: Tipo de acceso: public

El backend-service1 se configura como: Tipo de acceso: sólo portador

El backend-service2 se configura como: Tipo de acceso: sólo portador

La excepción es:

2019-02-18 11:15:32.914 DEBUG 22620 --- [  restartedMain] o.s.web.client.RestTemplate              : POST request for "http://localhost:<PORT>/auth/realms/<REALM_NAME>/protocol/openid-connect/token" resulted in 400 (Bad Request); invoking error handler

Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: error="access_denied", error_description="Access token denied."
    at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport.retrieveToken(OAuth2AccessTokenSupport.java:142)
    at org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider.obtainAccessToken(ClientCredentialsAccessTokenProvider.java:44)
    at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:148)
    at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:121)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:105)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:683)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:644)
    at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:399)
[STRIPPED]


    ... 5 more
Caused by: error="invalid_client", error_description="Bearer-only not allowed"
    at org.springframework.security.oauth2.common.exceptions.OAuth2ExceptionJackson2Deserializer.deserialize(OAuth2ExceptionJackson2Deserializer.java:80)
    at org.springframework.security.oauth2.common.exceptions.OAuth2ExceptionJackson2Deserializer.deserialize(OAuth2ExceptionJackson2Deserializer.java:33)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3072)
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:237)
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readInternal(AbstractJackson2HttpMessageConverter.java:217)
    at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:198)
    at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport$AccessTokenErrorHandler.handleError(OAuth2AccessTokenSupport.java:237)
    at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:730)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:688)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:654)
    at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport.retrieveToken(OAuth2AccessTokenSupport.java:137)
    ... 18 more

También tenga en cuenta que he cambiado el keycloak.auth-server-urlque http://localhost:<PORT>/auth(sin HTTPS) para la validación de certificados no falla debido a la auto certificado firmado en el desarrollo.

programmingFox:

OK, encontrado la solución a mí mismo: que necesitaba para establecer el botón del interruptor "Las cuentas de servicio habilitadas" en ON en la configuración del cliente para "back-end-service2" dentro de keycloak.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=180255&siteId=1
Recomendado
Clasificación