2009-06-24 6 views
6

J'ai créé une collection de sites dans une application Web avec l'utilisateur A en tant qu'administrateur de collection de sites. J'ai ajouté un lien dans la page de fonctionnalité du site. Le clic de ce lien, je suis en train de créer un job.Below de minuterie est le code exécuté sur un clic du lienProblème lors de la création d'un travail de minuteur

//Allow unsafe updates. 
SPContext.Current.Web.AllowUnsafeUpdates = true; 

//Get current web application. 
SPWebApplication webApp = SPContext.Current.Site.WebApplication; 

// Create new job. 
ArchiveJob automaticArchiveJob = new ArchiveJob(scheduleDetails.scheduleName, webApp); 

SPHourlySchedule hourlySchedule = new SPHourlySchedule(); 
hourlySchedule.BeginMinute = 0; 
hourlySchedule.EndMinute = 1; 
automaticArchiveJob.Schedule = hourlySchedule; 

//Finally update archival job. 
automaticArchiveJob.Update(); 

Maintenant, quand je me suis connecté avec l'utilisateur A et cliquez sur ce lien à la page « Paramètres du site » , Je reçois une exception de sécurité avec le message "Accès refusé" à la ligne automaticArchiveJob.Update(). Mais si je me suis connecté avec un utilisateur administrateur (je suis également connecté à la machine en utilisant cet utilisateur) et cliquez sur le lien, il crée avec succès le travail. Aussi j'ai fait l'utilisateur Un membre du groupe WSS_ADMIN_WPG mais obtenant toujours le même problème. Y at-il autre chose que je dois faire pour résoudre le problème.

Répondre

23

Le "Accès refusé" est un comportement attendu compte tenu de ce que vous essayez de faire. Permettez-moi d'expliquer.

Lorsqu'une instance de travail de minuteur est créée, elle est conservée dans la base de données de configuration de la batterie. L'accès à cette base de données à des fins d'écriture est une opération privilégiée; En règle générale, seul le compte de service de batterie (c'est-à-dire le compte sous lequel s'exécute OWSTIMER.EXE) ou les comptes disposant explicitement des droits requis pour effectuer une telle opération sur la base de données de configuration (généralement administrateurs) réussiront.

Par défaut, tenter d'instancier un travail du minuteur à partir du contexte de la collection de sites va échouer. Tenter l'opération dans un bloc de privilège élevé (via SPSecurity.RunWithElevatedPrivileges) ne fera qu'utiliser le contexte de compte du pool d'applications de l'application Web à la place du contexte utilisateur actuel; Cela ne réussit que si le compte du pool d'applications a le droit d'écrire dans la base de données de configuration de la batterie. Si cela se produit, c'est généralement parce que (a) le compte de service de batterie est utilisé dans des rôles qui ne doivent pas l'être (pour exécuter des applications web de contenu, par exemple) ou b) des autorisations supplémentaires ont été accordées au pool d'applications Compte. Les deux cas représentent un écart par rapport au modèle d'exploitation des meilleures pratiques.

Les instances de travaux de minuteur sont généralement créées au moment de l'activation de la fonction dans les entités définies au niveau de la batterie ou de la WebApplication. Pourquoi? Parce que ces fonctionnalités sont normalement activées par les administrateurs depuis la ligne de commande (en supposant que l'administrateur possède des droits dans la base de données de configuration de la batterie) ou depuis l'administration centrale (l'activation se fait via le compte de service de la batterie).). Lorsque la fonction est activée et que la méthode FeatureActivated de SPFeatureReceiver est appelée, il est sûr (du point de vue de la sécurité) de configurer le travail du minuteur.

Résoudre votre problème particulier impliquera de tourner le problème sur sa tête un peu. Au lieu d'essayer d'instancier le travail du minuteur à partir de la collection de sites à la demande, je vous recommande de configurer l'équivalent d'un travail de minuterie de «balayage» au moment où votre fonction est activée. Certes, cela nécessite plus de planification et d'efforts que ce que vous essayez de faire, mais votre chemin actuel ne fonctionnera que si la sécurité est en quelque sorte ajustée - et ce n'est pas recommandé. Lorsque j'ai créé ma fonction de vidage de la mémoire cache BLOB (http://blobcachefarmflush.codeplex.com), j'ai dû faire la même chose moi-même.Vous pouvez voir les détails de la façon dont j'ai travaillé à travers la création de travail du minuteur dans la classe FeatureReceiver (BlobCacheFarmFlushSweepJobFeatureReceiver). Le reste du code et la documentation associée peuvent également aider avec certains des autres défis qui se présentent.

N'hésitez pas à utiliser ce que vous trouvez de quelque manière que ce soit; Voilà pourquoi c'est là!

J'espère que cela aide. S'il y a des questions de suivi, lancez-vous et je répondrai du mieux que je peux :-)

+0

Hey Sean Merci pour votre réponse ..... Je l'ai trouvé très utile. Je vais certainement demander des requêtes si je vais avoir .... Merci encore – Anoop

+0

Comment configurer et exécuter ce travail alors? – Evgeny

+0

Je suis administrateur sur mon pc. – Evgeny

-3

J'ai utilisé RunWithElevatedPrivileges

SPSecurity.RunWithElevatedPrivileges (délégué() { });

Ça marche pour moi ..... Est-ce que quelqu'un a une autre solution? Si oui, faites le moi savoir.

+0

Vous pouvez trouver ce utile: http://stackoverflow.com/questions/638314 –

+2

Anoop, voir l'explication ci-dessus de Sean pourquoi vous ne devriez jamais (pouvoir) utiliser la méthode que vous décrivez ici. Sean a fait un excellent travail en expliquant cela clairement. –

0

Essayez de surcharger la méthode SPPersistedObject.HasAdditionalUpdateAccess() et renvoyez true.

protected override bool HasAdditionalUpdateAccess() { return true; }

Questions connexes