Estoy intentando conseguir un portador a través de un símbolo webclient
con la siguiente configuración para una prueba de integración de un servidor de recursos asegurado en una aplicación de servlet.
spring:
security:
oauth2:
client:
registration:
idp:
clientId: id
clientSecret: secret
authorization-grant-type: client_credentials
scope: read
provider:
idp:
authorization-uri: myidp/authorization.oauth2
token-uri: myidp/token.oauth2
user-info-uri: myidp/userinfo.openid
user-name-attribute: name
Y frijoles,
@Bean
WebClient webClient(ClientRegistrationRepository clientRegistrations,
OAuth2AuthorizedClientRepository authorizedClients) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServletOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations, authorizedClients);
// (optional) explicitly opt into using the oauth2Login to provide an access token implicitly
// oauth.setDefaultOAuth2AuthorizedClient(true);
// (optional) set a default ClientRegistration.registrationId
// oauth.setDefaultClientRegistrationId("client-registration-id");
return WebClient.builder().apply(oauth.oauth2Configuration()).build();
}
y Autowiring la webclient a una prueba y decir que es como tal,
webClient.get().uri("http://localhost:" + port + "/web/it")
.attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId("idp")).retrieve()
.bodyToMono(String.class).block();
Es mi suposición de la función de intercambio, ya sea conseguiría un token de acceso si está disponible, o hacer una llamada para obtener uno nuevo desde el IDP. Sin embargo, siempre se producirá un error como el HttpSessionOAuth2AuthorizedClientRepository
que el HttpServletRequest
es nulo.
Con la prueba general que parece, esto alimenta en una configuración automática para configurar algunos granos para un proveedor de IDP.
@SpringBootTest(classes = WebITApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith(SpringExtension.class)
@ActiveProfiles("web-it")
class WebJwtIt {
@LocalServerPort
private int port;
@Autowired
private WebClient webClient;
@Test
void testIdpJwt() {
String response = webClient.get().uri("http://localhost:" + port + "/web/it")
.attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId("ping")).retrieve()
.bodyToMono(String.class).block();
assertThat(response).isEqualTo("pass");
}
@RestController
@SpringBootApplication
@ImportAutoConfiguration(IdpAutoConfiguration.class)
static class WebITApplication implements IdpSecurityAdapter {
@Bean
WebClient webClient(ClientRegistrationRepository clientRegistrations,
OAuth2AuthorizedClientRepository authorizedClients) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServletOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations, authorizedClients);
// (optional) explicitly opt into using the oauth2Login to provide an access token implicitly
// oauth.setDefaultOAuth2AuthorizedClient(true);
// (optional) set a default ClientRegistration.registrationId
// oauth.setDefaultClientRegistrationId("client-registration-id");
return WebClient.builder().apply(oauth.oauth2Configuration()).build();
}
public static void main(String args[]) {
new SpringApplicationBuilder().profiles("web-it").build().run(WebITApplication.class, args);
}
@GetMapping
public String secured() {
return "secured";
}
@GetMapping("/web/it")
public String securedOne() {
return "pass";
}
@Override
public void configure(final HttpSecurity httpSecurity) throws IdpSecurityAdapterException {
try {
httpSecurity.oauth2Client();
} catch (Exception e) {
throw new IdpSecurityAdapterException("Failed to Configure Oauth2Client", e);
}
}
@Override
public IdpProvider getIdpProvider() {
return IdpProvider.MyIdp;
}
}
¿Hay alguna forma para un cliente Web para obtener el token para mí y añadirlo a la solicitud? Sé que esto era posible con el spring-security-oauth:OAuthRestTemplate
y la lectura de la documentación pensé que era posible con un cliente web.
El problema aquí es que usted no está de instancias el cliente Web de la manera correcta.
Como usted está en el lado del cliente , usted no tiene acceso a una OAuth2AuthorizedClientRepository
. Este bean se supone que debe estar vinculada a una Sever recurso en el que se acceda a utilizar la .oauth2Login()
declaración de método en la HttpSecurity
configuración. Estos detalles se explican en la primavera de Seguridad 5 OAuth2 de sesión .
Una vez más, usted está en el lado del cliente por lo que lo que necesita es una función de filtro de intercambio, lo que disparará una solicitud a un servidor de autorización para obtener un token JWT. Se puede utilizar el ServerOAuth2AuthorizedClientExchangeFilterFunction
lugar.
Es mejor utilizar una WebClientCustomizer
para agregar la función de filtro de intercambio en el filtro de cliente Web. Por qué ? Simplemente porque la inyección en la aplicación de un resorte WebClient.Builder
le permitirá acceder a las métricas nativos vinculados a los intercambios web.
Por lo tanto, se va a construir su cliente Web utilizando una nueva instancia de un UnAuthenticatedServerOAuth2AuthorizedClientRepository
grano de la siguiente manera:
// Use injection to get an in-memory reposiroty or client registrations
@Bean
WebClient webClient(ClientRegistrationRepository clientRegistrations) {
// Provides support for an unauthenticated user such as an application
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations, new UnAuthenticatedServerOAuth2AuthorizedClientRepository());
// Build up a new WebClientCustomizer implementation to inject the oauth filter
// function into the WebClient.Builder instance
return new WebClientSecurityCustomizer(oauth);
}
Como usted está en el lado del cliente , no asocia a un usuario para su proceso, por eso no se puede utilizar cualquier repositorio cliente instanciation frijol autorizado. Compruebe en la documentación de la primavera de Seguridad: documentación de la primavera de Seguridad: Clase UnAuthenticatedServerOAuth2AuthorizedClientRepository .
Traté de resumir un caso de demostración en el siguiente proyecto de GitHub: GitHub - escenario de la primavera de Seguridad OAuth2 de máquina a máquina .
Espero que esto le da más puntos de vista sobre la configuración del cliente Web. Por favor, pregunte si tiene alguna pregunta.