Circule por esta guía con precaución. Gracias.


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.

Solicitud de credenciales para el CAS

Tendremos que solicitar que se de den de alta las credenciales correspondientes en los tres entornos poniendo un Jira a Telemática (DJ-AT-SIST-TELEMATICA) indicando el client id (será la api que lo vaya a utilizar, por ejemplo "portal-api") y el scope, que nos lo debe indicar la API a la que vayamos a hacer peticiones con el token que obtengamos.

Con esto darán de alta el servicio y tendremos:

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. 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.

Para más información, ver esta guía: MNCS - Uso de Vault

Una vez dados de alta los secretos, tendremos que solicitar la creación de política para acceso a dichos secretos (es decir, que nuestra api tenga permisos para acceder a ellos), como se indica aquí: Procedimiento para solicitud de acceso a secretos con Vault

URLs del CAS según entorno

Habrá que solicitar el token a la URL que corresponda según el entorno. Podemos usar estas tres como referencia, pero tendremos que asegurarnos contra qué está autenticando la API a la que vayamos a atacar, pues si no obtendremos errores al hacer las peticiones:

EntornoURL CAS

DESARROLLO

https://entrada.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:

@Configuration
public class WebClientConfig {

    @Value("${cas.oauth.url}")
    private String url;
    @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í:

@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:

webClient.post().headers(h -> h.setBearerAuth(jwt.getTokenValue())). ...