Versiones comparadas

Clave

  • Se ha añadido esta línea.
  • Se ha eliminado esta línea.
  • El formato se ha cambiado.

Tabla de contenidos

...

titleEN CONSTRUCCIÓN...

Para obtener un token OIDC con el que poder llamar a APIs OAuth sin necesidad de tener un usuario logeado, necesitamos unas credenciales que pasaremos al CAS para que nos devuelva el token.

...

El client secret es la contraseña, así que por supuesto no se debe subir a gitlab. Para su uso, solicitaremos también (puede ser en el mismo jira) que den de alta las credenciales en Vault y nos den acceso a las mismas. Al ser el CAS el que proporciona las credenciales, telemática será el grupo emisor, y nuestra api será la que consuma dichos secretos de Vault.

...

Habrá que solicitar el token a la URL que corresponda según el entorno, según . Podemos usar estas tres como referencia, pero tendremos que asegurarnos contra qué esté está autenticando la API a la que vayamos a atacar con dicho token.

...

, pues si no obtendremos errores al hacer las peticiones:

EntornoURL CAS

DESARROLLO

https://sso.test.um.es/cas/oidc/accessToken
TESThttps://apitest.um.es/mncs/api-umu/cas/oidc/accessToken
PRODUCCIÓNhttps://entrada.um.es/cas/oidc/accessToken

Tendremos que tener la url correspondiente en nuestro application.properties, la correspondiente al entorno en el que estemos....

Obtención del token

Una vez tengamos las credenciales, obtendremos el token así (poniendo en los @Value el nombre de las properties que corresponda).

En primer lugar configuraremos nuestro WebClient:

Bloque de código
languagejava
@Configuration
@Component
public class FundeWebJSOAuthClientWebClientConfig {

    @Value("${cas.oauth.url}")
    private String casUrlurl;
    @Value("${cas.oauth.clientid}")
    private String clientId;
    @Value("${cas.oauth.clientsecret}")
    private String clientSecret;

    @Bean(name = "webClientTokenAdmin")
    public WebClient webClient(WebClient.Builder webClientBuilder) {
        return webClientBuilder.baseUrl(url).defaultHeader("X-service", "https://micampustest.um.es")
                .defaultHeader("Authorization",
                        "Basic " + Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()))
                .build();
    }

Y después haremos la llamada al CAS así:

Bloque de código
languagejava
@Component
public class FundeWebJSOAuthClient {

    @Value("${cas.oauth.scopes}")
    private String scopes;

    @Autowired
    @Qualifier("webClientTokenAdmin")
    private WebClient webClient;

    public String getClientCredentialsToken() {

        Map<String, String> response = webClient.post()
                .body(BodyInserters.fromFormData("scope", scopes).with("grant_type", "client_credentials")).retrieve()
                .bodyToMono(new ParameterizedTypeReference<Map<String, String>>() {
                })
                .block(Duration.ofSeconds(30));

        return response.get("access_token");
    }
}

Con este método, estamos haciendo un POST a /cas/oidc/accessToken, pasándole el scope en el body e indicando como parámetro en la URL que el grant_type es client_credentials. En la respuesta obtendremos varios campos, y nos quedamos con "access_token", que es el token en cuestión.

Para información más extensa (aunque esté enfocada al entorno de la UmuApp sirve para ver detalles de la api del CAS), podemos ver esta guía: OpenID JWT - Usuario - Backend UMUApp

Uso del token

Para utilizarlo, en la llamada a la API correspondiente tendremos que hacerlo como otros JWTs, pasándolo en el header Authorization como "Bearer <<token>>". Por ejemplo, con WebClient:

Bloque de código
languagejava
webClient.post().headers(h -> h.setBearerAuth(jwt.getTokenValue())). ...

O en el caso de que utilicemos RestTemplate, lo podemos añadir así:

Bloque de código
languagejava
// Preparamos header jwt
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(jwt.getTokenValue());
HttpEntity<String> entity = new HttpEntity<>(headers);
// Llamada
ResponseEntity<LoQueSea> response = restTemplate.exchange(url, HttpMethod.GET, entity,
        new ParameterizedTypeReference<LoQueSea>() {});