LWC falla de repente: «You don’t have access to APEX class…»

Este artículo también está disponible en: English (Inglés)

Si algunos de tus Lightning Web Components han empezado a fallar de una manera sutil (o no sutil), y tu consola de Chrome está arrojando errores 500 a tus usuarios, es probable que te estés enfrentando a este problema.

¿Y esto ahora por qué?

Con ahora me refiero a septiembre-octubre de 2020. Y esto coincide con la última actualización Winter ’21 de Salesforce. En caso de que te lo pasaras por alto, entre las actualizaciones críticas de Summer ’20, Salesforce incluyó esto (que hace referencia al cambio en cómo APEX se ejecuta en relación con @AuraEnabled):

Pero también indica que lo han pospuesto para la actualización de Winter 21, que es lo que nos ha reunido aquí hoy a todos.

Antes de esta actualización, las clases de APEX estaban aplicando el régimen de permisos «not sharing» como predeterminado. Y ahora, están aplicando el régimen «sharing» por defecto en su lugar. Lo que causa todo este embrollo, en caso de que no lo hayas tenido en cuenta cuando desarrollaste tus componentes en primer lugar.

¿Y esto qué significa?

Grosso modo, significa que todos los componentes que usan controladores APEX decorados con @AuraEnabled deben indicar expresamente si la clase es accesible de acuerdo a los permisos del usuario que ejecuta. O si, por el contrario, debería correr en contexto de sistema sin considerar ninguna limitación de permisos.

La forma de conseguir esto es utilizando el «with sharing» (con restricciones de permisos) o el «without sharing» (sin restricciones de permisos) cuando declaramos una nueva clase. Por ejemplo:

public with sharing class IdeasHelper { //Enforcing the sharing rules
 @AuraEnabled
    public static void createVote(String IdeaId){
    
        try {
            sonn_Idea_Vote__c newVote = new sonn_Idea_Vote__c();
            newVote.sonn_Idea__c = IdeaId;

            insert newVote;
        } catch (Exception e) {

            String errorMsg = e.getMessage();
            String pureErrorMsg = errorMsg.substringAfter('_EXCEPTION,');
            pureErrorMsg = pureErrorMsg.Substring(0, (pureErrorMsg.length()-4));
            throw new AuraHandledException(pureErrorMsg);
        }

    }
}

Cuando indicamos «with sharing» significa que la clase será ejecutada teniendo en cuenta y considerando los permisos concedidos al usuario que la ha ejecutado.Así que si un usuario clica en el botón «Vote» pero su perfil no tiene acceso específico a la clase «Ideas Helper», fallará. Y puede hacerlo de diferentes maneras:

Esto es así, obviamente, por motivos de seguridad. Para no exponer información delicada a usuarios que no deban verla. Especialmente en servicios web.

Resumidamente, puedes solucionar esto de tres maneras:

  1. Usando ‘without sharing’ cuando declares la clase. Esto significa que la clase ignorará por completo los permisos del usuario ejecutor y correrá en contexto de sistema (como omnipotente). Cuando decidas aplicar esta regla, sé consciente de las implicaciones que ésto tiene para seguridad de tu código y tu organización, y quién podrá acceder potencialmente a la información.
  2. Usando ‘with sharing’ y concediendo permisos específicamente para ella. Aquí no hay misterios. Cuando despliegas tu controlador APEX, debes también desplegar los permitos para los perfiles de usuarios o permission sets. O bien, una vez desplegada, otorgar los permisos ya en producción. Para más detalles, pasa al siguiente punto «Otorgando acceso a una clase de APEX»
  3. Creando un «permission set» específico y desplegándolo en el meta XML de tu LWC. Echa un vistazo a este magnífico post donde indica cómo hacer esto.

Otorgando acceso a una clase de APEX

Ésta es la forma más fácil y rápida de garantizar acceso a través de la interfaz de usuario a un perfil específico:

  1. Clica en el icono del engranaje en la esquina super derecha y selecciona «Setup».
  2. Abre el menú de «APEX Classes» desde el buscador y localiza la clase a la que tienes que otorgar acceso.

3. Pincha en la clase y seguidamente en el botón de «Seguridad»

4. Otorga el acceso a los perfiles de usuarios que consideres que van a utilizar esta clase. Por defecto, sé tan restrictivo como puedas concediendo permisos.

5. Pincha en «guardar» y ya está.

Algo de documentación sobre esto

Para ampliar tu conocimiento sobre esta cuestión y cómo funciona, recomiendo consultar los siguientes enlaces:

Peace and Code!

Nadine.