A veces puede surgir la necesidad hacer que una parte del código se ejecute con un usuario distinto del actual. Se puede dar el caso de que sea necesario impersonar ciertas de acciones de AX, por ejemplo, al recibir informacion desde una aplicación externa (mediante un fichero de texto plano o un web service), también puede ser necesario chequear los permisos de un usuario distinto del actual para acceder a una determinada funcionalidad de AX.

La función RunAs, es una funcionalidad que puede ser de una gran utilidad ya que nos permite impersonar, y ejecutar ciertas funcionalidades con un usuario distinto del actual, esto puede ser muy útil dentro del ámbito de testeo de seguridad, asi como para ejecutar funcionalidades de AX desde aplicaciones externas, no obstante hay que tener cuidado con su uso ya que puede contribuir a vulnerar la seguridad del sistema. La funcionalidad es bastante sencilla de utilizar si se tiene en cuenta los siguientes puntos:

  • Solo pueden invocarse métodos estáticos
  • El método solo podrá enviar y recibir parámetros por medio de contenedores, si no se utilizan correctamente dara un error bastante genérico (y frustrante) diciendo que se ha llamado al método con un parámetro incorrecto
  • Se debe tener mucho cuidado cuando se use dentro de una transacción (ttsbegin, ttscommit) ya que el cambio de usuario a media transacción tendrá consecuencias indeseadas, como que todos los cambios realizados dentro de la transacción previos al RunAs no se vean (cosa logica, dado que hemos cambiado de usuario a todos los efectos)

En el ejemplo que adjunto, se usaba la funcionalidad de AX «RunAs» dentro del marco de una inserción automatizada de datos, para chequear si el usuario que genero dichos datos (y que no es el actual) en la aplicación externa, tenia permisos para confirmar el pedido, también podría usarse para que los campos de auditoria (createdBy, ModifiedBy) se rellenen con el usuario que dio de alta los datos en la aplicación externa.

En primer lugar el método CheckPermission nos indica como ejecutar un método estático mediante la función RunAS, el método RunAs siempre envía y devuelve  parámetros al método invocado mediante un contenedor

Boolean CheckPermissions(string       _extUser)

{

RunAsPermission         perm;

UserId                  runAsUser;

SysUserInfo             userInfo;

Container               Parms;

Boolean                 ret;

;

userInfo = SysUserInfo::find(_extUser);

runasuser = userInfo.Id ? userInfo.Id : curuserid();  //En este caso, si el usuario no existe se usara el actual

perm = new RunAsPermission(runAsUser);

perm.assert();

Parms = runas(runAsUser,classnum(CHAESWSCreateSalesOrder),»CheckPost»);

CodeAccessPermission::revertAssert();

return ret;

}

El siguiente método (que se ha invocado mediante la funcion RunAs), chequea si el usuario actual tiene permisos para acceder a la opción de confirmación de pedidos, este chequeo se hará con el usuario incado en la llamada RunAs

server static container CheckPost(container     _parms)

{

Boolean                 ret;

MenuFunction            menufunction;

container               retval;

;

//Si el usuario tiene permiso para confirmar

menufunction = new  menufunction(menuitemactionstr(SalesFormLetter_confirmation),menuitemtype::Action);

if (menufunction.checkAccessRights())

ret = true;

retval = conpoke(retval,1,ret);

return retval;

}

Como se puede observar, se ha adaptado el metodo explicitamente para funcionar con RunAs, ya que el booleano que normalmente devolveria, se ha introducido dentro de un contenedor,  en caso contrario el RunAs no sabría como tratarlo.

En resumen, la funcionalidad RunAs es una utilidad muy potente que debe usarse con precaución, preferentemente para la invocación de métodos pequeños y/o simples. puede provocar un funcionamiento defectuoso en el ámbito de las transacciones. Por lo demás, yo lo he usado para realizar chequeos de seguridad, pero puede tener muchas otras utilidades.

Comparte este contenido:

0 comentarios

Dejar un comentario

¿Quieres unirte a la conversación?
Siéntete libre de contribuir!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *