Depurando un error de Permisos Insuficientes en CRM 4.0
Hace unas semanas un compañero del departamento de consultoría nos comentaba que en uno de sus proyectos obtenían un error de permisos insuficientes cuando un usuario se conectaba a CRM por primera vez. La única peculiaridad era que el único rol de seguridad asignado al usuario había sido creado desde cero.
El error obtenido por el usuario era el siguiente:
Proceso de resolución del problema
Para depurar este error bastó con activar la opción DevErros y volver a reproducir el error. En este caso el error obtenido fue el siguiente:
El contenido completo del informe de error era:
Error Description: SecLib::CrmCheckPrivilege failed. Returned hr = -2147220960 on UserId: b1d4add8-54ac-dd11-b383-0003ff1206c7 and PrivilegeId: 588725dd-c878-41c5-a4c3-5efc93cd3ffd Error Details: SecLib::CrmCheckPrivilege failed. Returned hr = -2147220960 on UserId: b1d4add8-54ac-dd11-b383-0003ff1206c7 and PrivilegeId: 588725dd-c878-41c5-a4c3-5efc93cd3ffd Full Stack: [CrmSecurityException: SecLib::CrmCheckPrivilege failed. Returned hr = -2147220960 on UserId: b1d4add8-54ac-dd11-b383-0003ff1206c7 and PrivilegeId: 588725dd-c878-41c5-a4c3-5efc93cd3ffd] at Microsoft.Crm.BusinessEntities.SecurityLibrary.CheckPrivilege(Guid user, Guid privilege, ExecutionContext context) at Microsoft.Crm.BusinessEntities.SecurityExtension.PreUpdateHandlerEntityPrivilegeCheck(Object sender, SecurityTraits traits, SecurityAttributes attributes, ExtensionEventArgs e) at Microsoft.Crm.ObjectModel.BypassAppendAppendToSecurityExtension.PreUpdateHandler(ExtensionEventArgs e, Object sender) at Microsoft.Crm.BusinessEntities.SecurityExtension.PreUpdateHandler(Object sender, ExtensionEventArgs e) at Microsoft.Crm.BusinessEntities.BusinessProcessObject.PreUpdateEventHandler.Invoke(Object sender, ExtensionEventArgs e) at Microsoft.Crm.BusinessEntities.BusinessProcessObject.Update(IBusinessEntity entity, ExecutionContext context) at Microsoft.Crm.ObjectModel.UserSettingsServiceInternal`1.Update(IBusinessEntity usersettings, ExecutionContext context) at Microsoft.Crm.ObjectModel.SystemUserServiceInternal`1.UpdateUserSettings(Guid userId, UserSettings settings, ExecutionContext context) [TargetInvocationException: Exception has been thrown by the target of an invocation.] at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Web.Services.Protocols.LogicalMethodInfo.Invoke(Object target, Object[] values) at Microsoft.Crm.Extensibility.InternalOperationPlugin.Execute(IPluginExecutionContext context) at Microsoft.Crm.Extensibility.PluginStep.Execute(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.Pipeline.Execute(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.MessageProcessor.Execute(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.InternalMessageDispatcher.Execute(PipelineExecutionContext context) at Microsoft.Crm.Extensibility.ExternalMessageDispatcher.Execute(String messageName, Int32 primaryObjectTypeCode, Int32 secondaryObjectTypeCode, PropertyBag fields, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId) at Microsoft.Crm.Sdk.RequestBase.Process(Int32 primaryObjectTypeCode, Int32 secondaryObjectTypeCode, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId) at Microsoft.Crm.Sdk.RequestBase.Process(CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId) at Microsoft.Crm.Sdk.CrmServiceInternal.Execute(RequestBase request, CorrelationToken correlationToken, CallerOriginToken originToken, UserAuth userAuth, Guid callerId) at Microsoft.Crm.Sdk.InProcessCrmService.Execute(Object request) at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.ExecuteInternal() at Microsoft.Crm.Application.Platform.ServiceCommands.UpdateCommand.Execute() at Microsoft.Crm.Application.Platform.DataSource.Update(Entity entity) at Microsoft.Crm.Application.Controls.AppPage.UpdateUserLanguageIfNecessary() at Microsoft.Crm.Application.Controls.AppPage.OnInit(EventArgs e) at System.Web.UI.Control.InitRecursive(Control namingContainer) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) [HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown.] at System.Web.UI.Page.HandleError(Exception e) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest() at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) at System.Web.UI.Page.ProcessRequest(HttpContext context) at ASP.default_aspx.ProcessRequest(HttpContext context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) Other Message: Error Number: 0x80040220 Source File: Not available Line Number: Not available Request URL: https://vjpeiro-dc-sql:5555/default.aspx |
La traducción del error número 0x80040220 es: "The user does not hold the necessary privileges." lo cual concordaba con el mensaje obtenido inicialmente.
Para identificar los privilegios que el usuario no poseía y que causaban el error sólo tuvimos que fijarnos en la descripción del error. En esta sección podemos encontrar tanto en el UserId del usuario que se intenta conectar (b1d4add8-54ac-dd11-b383-0003ff1206c7), como en el PrivilegeId que el usuario no posee (588725dd-c878-41c5-a4c3-5efc93cd3ffd). Una vez que conocimos el identificador del privilegio sólo tuvimos que ejecutar la siguiente consulta de SQL contra la base de datos de la organización:
La etiqueta prvWriteUserSettings se refiere al privilegio de Escritura sobre la entidad Configuración de Usuario. Finalmente el problema se subsanó otorgando este permiso con un nivel de acceso de usuario.
Causa del problema
La configuración de usuario se crea al mismo tiempo que un usuario es dado de alta en CRM; sin embargo esta configuración es modificada la primera vez que dicho usuario se conecta a CRM para establecer el Modo de Búsqueda Avanzada, el Idioma de Interfaz de Usuario y el Idioma de la Ayuda. Es por esto que el usuario debe tener privilegios de escritura sobre la entidad Configuración de Usuario con un nivel de acceso de usuario o mayor en el momento de conectarse a CRM por primera vez.
Este privilegio permitirá también que el usuario pueda modificar su configuración a través de la opción Opciones del menú de Herramientas.
Algunas consideraciones adicionales
En este caso, el error de denegación de permisos fue causado por una acción ejecutada desde el interfaz de usuario y esto permitió usar la opción DevErrors para ampliar la información relativa al error. Sin embargo, en otras ocasiones el error de denegación puede estar causado por un componente de CRM o un desarrollo que no presente un interfaz. En este caso será necesario la captura de trazas de plataforma en el servidor de CRM donde se registrará un error con la misma información que en este caso nos mostraba la opción DevErrors.
Por Nacho Peiro Alba
Comments
Anonymous
November 06, 2008
PingBack from http://www.tmao.info/depurando-un-error-de-permisos-insuficientes-en-crm-40/Anonymous
November 08, 2008
En el anterior post vimos como depurar un determinado tipo de error. En este caso usamos la activaciónAnonymous
January 12, 2009
En el anterior post vimos como depurar un determinado tipo de error. En este caso usamos la activación