En spring-security-oauth2:2.4.0.RELEASE
clases como OAuth2RestTemplate
, OAuth2ProtectedResourceDetails
y ClientCredentialsAccessTokenProvider
todas han sido marcadas como obsoletas.
Desde el javadoc en estas clases, apunta a una guía de migración de seguridad de primavera que insinúa que las personas deben migrar al proyecto central de spring-security 5. Sin embargo, tengo problemas para encontrar cómo implementaría mi caso de uso en este proyecto.
Toda la documentación y ejemplos hablan sobre la integración con un proveedor de OAuth de tercera parte si desea que las solicitudes entrantes a su aplicación se autentiquen y desea usar el proveedor de OAuth de terceros para verificar la identidad.
En mi caso de uso, todo lo que quiero hacer es hacer una solicitud con un RestTemplate
servicio externo protegido por OAuth. Actualmente creo un OAuth2ProtectedResourceDetails
con mi ID de cliente y secreto que paso a un OAuth2RestTemplate
. También tengo una costumbre ClientCredentialsAccessTokenProvider
agregada a la OAuth2ResTemplate
que solo agrega algunos encabezados adicionales a la solicitud de token que requiere el proveedor de OAuth que estoy usando.
En la documentación de spring-security 5, encontré una sección que menciona la personalización de la solicitud de token , pero nuevamente parece estar en el contexto de autenticar una solicitud entrante con un proveedor de OAuth de terceros. No está claro cómo usaría esto en combinación con algo como a ClientHttpRequestInterceptor
para garantizar que cada solicitud saliente a un servicio externo primero obtenga un token y luego se agregue a la solicitud.
También en la guía de migración vinculada anteriormente hay una referencia a una OAuth2AuthorizedClientService
que dice que es útil para usar en interceptores, pero nuevamente parece que depende de cosas como la ClientRegistrationRepository
que parece ser donde mantiene registros para proveedores de terceros si desea usar que proporcionan para garantizar que se autentique una solicitud entrante.
¿Hay alguna forma de utilizar la nueva funcionalidad en spring-security 5 para registrar proveedores de OAuth y obtener un token para agregar a las solicitudes salientes de mi aplicación?
fuente
WebClient
se use un interceptor (o para lo que sea la nueva terminología ) o algo similar para obtener un token OAuth de un proveedor de OAuth personalizado (ninguno de los que admite OoTB como Facebook / Google) para agregarlo a una solicitud saliente. Todos los ejemplos parecen centrarse en autenticar las solicitudes entrantes con otros proveedores. ¿Tienes alguna sugerencia para algún buen ejemplo?WebClient
con el tipo de concesión de credenciales del cliente.La respuesta anterior de @Anar Sultanov me ayudó a llegar a este punto, pero como tuve que agregar algunos encabezados adicionales a mi solicitud de token OAuth, pensé que proporcionaría una respuesta completa sobre cómo resolví el problema para mi caso de uso.
Configurar detalles del proveedor
Agregue lo siguiente a
application.properties
Implementar personalizado
ReactiveOAuth2AccessTokenResponseClient
Como se trata de comunicación de servidor a servidor, necesitamos usar el
ServerOAuth2AuthorizedClientExchangeFilterFunction
. Esto solo acepta aReactiveOAuth2AuthorizedClientManager
, no lo no reactivoOAuth2AuthorizedClientManager
. Por lo tanto, cuando usamosReactiveOAuth2AuthorizedClientManager.setAuthorizedClientProvider()
(para darle el proveedor para que lo use para hacer la solicitud OAuth2) tenemos que darle un enReactiveOAuth2AuthorizedClientProvider
lugar de no reactivoOAuth2AuthorizedClientProvider
. Según la documentación de referencia de Spring-Security, si utiliza un elemento no reactivoDefaultClientCredentialsTokenResponseClient
, puede utilizar el.setRequestEntityConverter()
método para alterar la solicitud del token OAuth2, pero el equivalente reactivoWebClientReactiveClientCredentialsTokenResponseClient
no proporciona esta función, por lo que tenemos que implementar el nuestro (podemos hacer uso de LaWebClientReactiveClientCredentialsTokenResponseClient
lógica existente ).Mi aplicación se llama
UaaWebClientReactiveClientCredentialsTokenResponseClient
(aplicación omite ya que sólo muy ligeramente altera lasheaders()
y losbody()
métodos de la estándarWebClientReactiveClientCredentialsTokenResponseClient
para añadir algunas cabeceras extra / campos del cuerpo, que no cambia el subyacente de autenticación de flujo).Configurar
WebClient
El
ServerOAuth2AuthorizedClientExchangeFilterFunction.setClientCredentialsTokenResponseClient()
método ha quedado en desuso, por lo tanto, siguiendo los consejos de desuso de ese método:Esto termina con una configuración similar a la siguiente:
Usar
WebClient
como de costumbreEl
oAuth2WebClient
bean ahora está listo para ser utilizado para acceder a los recursos protegidos por nuestro proveedor de OAuth2 configurado de la misma forma en que haría cualquier otra solicitud utilizando aWebClient
.fuente
ClientRegistration
s con los detalles requeridos y pasarlos al constructor paraInMemoryReactiveClientRegistrationRepository
(la implementación predeterminada deReactiveClientRegistrationRepository
). Luego usa eseInMemoryReactiveClientRegistrationRepository
bean recién creado en lugar de mi autoconectadoclientRegistrationRepository
que se pasa aloauthFilteredWebClient
métodoClientRegistration
en tiempo de ejecución, ¿verdad? Según tengo entendido, necesito crear un beanClientRegistration
en el inicio.application.properties
archivo. La implementación de la suya propia leReactiveOAuth2AccessTokenResponseClient
permite realizar cualquier solicitud que desee para obtener un token OAuth2, pero no sé cómo podría proporcionarle un "contexto" dinámico por solicitud. Lo mismo ocurre si implementa su filtro completo. Todo esto le daría acceso a la solicitud saliente, así que a menos que pueda inferir lo que necesita a partir de ahí, no estoy seguro de cuáles son sus opciones. ¿Cuál es su caso de uso? ¿Por qué no conocería los posibles registros al inicio?La respuesta de @matt Williams me pareció bastante útil. Aunque me gustaría agregar en caso de que alguien quisiera pasar programáticamente clientId y secret para la configuración de WebClient. Así es como se puede hacer.
fuente
Hola, tal vez sea demasiado tarde, sin embargo, RestTemplate todavía es compatible con Spring Security 5, para la aplicación no reactiva RestTemplate todavía se usa, lo que debe hacer es configurar la seguridad de Spring correctamente y crear un interceptor como se menciona en la guía de migración
Use la siguiente configuración para usar el flujo de credenciales de cliente
application.yml
Configuración a OauthResTemplate
Interceptador
Esto generará access_token en la primera llamada y cada vez que expire el token. OAuth2AuthorizedClientManager gestionará todo esto para usted
fuente