I am trying to implement some logging in my webpart. I implemented a Custom trace provider implementation which writes Log messages into the 12 hive logs as has been described here:
http://msdn.microsoft.com/en-us/library/aa979522.aspx
I have wrapped the above code into a dll called logging.DLL.
I am referencing this DLL in my webpart.
I am calling the RegisterTraceProvider in the constructor using elevated privileges.
I have declared the Logging DLL as a safe control in the manifest.xml.
But When i try to add the webpart to the page, I get a security exception with message "Request failed." THis error is thrown in the constructor when it tries to call the RegisterTraceProvider method.
Am I missing something here? How can I get this logging to work?
Edit:Both my logging DLL and my webpart DLL are in the GAC.
Since the trace provider uses unmanaged code you should mark the method with:
[SecurityPermission(SecurityAction.Assert, SecurityPermissionFlag.UnmanagedCode)]
This will make sure .NET's security stops checking further in the call stack when this attribute is reached, which allow less trusted code to do unmanaged calls thorugh it. Remember that the logging dll still need permissions to run, so either give it CAS-policies in the manifest.xml or put it in the GAC. If you put it in the GAC, mark it with the following attribute which makes it callable from a non fully trusted dll:
[assembly: AllowPartiallyTrustedCallers]
Then you should be able to call it from a WebPart deployed to the bin directory.
Is your webpart deployed in the GAC or Bin folder?
If it is in the Bin folder, the webpart is not running under Full Trust, so you need to write a Code Access Security Policy for your webpart, allowing it to run call's to the API under Full Trust.
for an example check this out or just Google for Sharepoint + Code Access Security Policies.
I was Doing m RegisterTraceprovider() call inside the constructor. Looks like this was the reason it was failing. I moved my RegisterTraceProvider() call into OnInit() override, and it started working!!
Related
I'm writing a custom .net profiler to rewrite some methods in SharePoint 2013 on the fly.
The Class I'm interested is Microsoft.SharePoint.Utilities.DateOptions.
I've implemented ICorProfilerCallback::JITCompilationStarted and ICorProfilerCallback::JITCachedFunctionSearchStarted in my profiler and am currently just logging all functions being compiled. Also, I've set eventFlags as follows
DWORD eventMask =
COR_PRF_DISABLE_ALL_NGEN_IMAGES |
COR_PRF_DISABLE_INLINING |
COR_PRF_MONITOR_JIT_COMPILATION |
COR_PRF_MONITOR_CACHE_SEARCHES;
The problem is, No matter what I do, no method of DateOptions class will be compiled. I am sure that it should be called, and I've already tested my changes by disassembling, updating code, and reassembling it's DLL. I can see other classes in the same namespace loading and compiling (and can successfully rewrite them) but not this one. The decision to use a profiler for the job is a business decision and can not be reverted.
One point of interest is that this class is used on the code generating the page and its web parts, and I can see no other related classes in this code-path too.
I've enabled my profiler system-wide using system environment variables, and have tried rebooting so it will profile everything from startup to no avail.
Am I missing something here?
Edit: I guess it should be some setting inside IIS or something. I can see all normal classes and namespaces, but nothing that runs while rendering the page in IIS.
I finally solved my problem. It was kind of a dumb mistake I guess, but still I'm putting it here so no one else gets stuck like me!
I was using a specific folder on my C drive for development, and ASP.Net user account did not have read privileges to that folder, and could not load the profiler.
Parts of the process was run using a privileged account so I was able to log and rewrite it's functions, but the web rendering parts were under a limited account.
Copying the dll to System32 folder fixed all my problems.
I've got a classlibrary which defines a couple of helper classes/methods which are used from a classic asp web application. So far, everything works fine. Now I've added a new helper method which signs a PDF file using a third party tool. Using a console application to call this wrapper method, everything works fine. Once I use an asp page to call the exact same method, the call to
X509Certificate2 cert = new X509Certificate2(sigFilePath, sigPassword);
fails with the error "The system cannot find the specified file" (translated from german).
Since the same code works fine called from the console application, i guess the problem must be located somewhere different. Could it be a security issue?
When I wonder if I'm facing a security issue like you do, I just do a quick test : I put the user account the webserver is using in the administrators group, do a quick iisreset, and try again. If it's working know you now it's a security issue. If it's still failing, look somewhere else.
Never forget to then remove the user accoung from the administrators group, and only do that on you own dev machine, not on production servers !!
If it's a security issue, I would then recommend launching Process Monitor (look for procmon in google). It's a Microsoft download. Look for access denied in the result column. You'll then know what's blocking you ...
I've created a user control and added that user control to my webpart. But when i try to add the webpart in a page. i am facing the above stated problem.I ensured that dll was present in GAC.
I've created a user control and added that user control to my class library. I've compiled and signed the dll and have added it to the gac. But when i try to add the webpart in a page i'm getting the below mentioned error.And made necessary changes in web.config file.
I've made sure that dll is there in the gac. But i'm still getting the same error.
" An error occurred during the processing of . Could not load the assembly 'Generate , Version=1.0.0.0, Culture=neutral, PublicKeyToken=e5b42758c1bfd2df'. Make sure that it is compiled before accessing the page. "
please help me.
Make sure the user control inherits
from the solution assembly in the Control tag
Load the control in the CreateChildControls method of the Web Part
Put this user control under the CONTROLTEMPLATES folder
Are you deploying is as a Feature?
To debug locally, check the following in your config file:
* customErrors=off
* Enable Stack Traces by adding CallStack=”true” to the SafeMode tag
* Set the compilation debug attribute to "true"
I created a code behind file for a custom master page in visual studio. I hooked everything up manually; safe control and custom cas policy. Everything works great!
I then wanted to put this into a sharepoint solution using WSPBuilder for better deployment. I created WSP solution, added my class file and changed the output directory to the bin folder. I then built the solution and deployed it, making sure to change the page directives on the master page to reflect the new assembly name.
Now when I go to view the sharepoint site I get an error stating Security Exception error stating
‘Exception Details: System.Security.SecurityException: That assembly does not allow partially trusted callers.’
This has me stumped as it works as a visual studio class file deployed to the bin directory of the website.
However when I put this into a sharepoint solution it breaks! I tried adding
‘[assembly: System.Security.AllowPartiallyTrustedCallers]’
to the AssemblyInfo.cs but this hasn’t helped.
Anyone else experinced this or have any advice?
EDIT: I should also mention that the code behind is trying to access a sharepoint list.
Don´t you still have to include the SafeControls entry in order for it to work, like:
<SafeControl Assembly="[FullAssembly Name]"
Namespace="[YourMasterPageNamespace]"
TypeName="*"
Safe="True" />
or in WSPBuilder config:
<add key="BuildSafeControls" value="True" />
Never seen this.. but I suspect not many people have created codebehinds to the master pages in SharePoint (Microsoft doesn't too!).
I don't know what you are trying to build but I'd probably implement it using a server control that is included on the master page.
AllowPartiallyTrustedCallers has always fixed it for my server controls.
What is the trust in your web.config file set to? Try Full.
Are you calling a third party assembly?
I ran into a situation recently that I was using a third party assembly and it did not have AllowPartiallyTrustedCallers in its code. When I tried to use the assebmly, it would fail.
Are you sure that the assembly has been deployed to bin and no to GAC by accident? If there are two assemblies the one in GAC takes precedence.
You might try checking that you are using the fully qualified five part name including the correct public key token and namespace for your assemblies.
Is it possible to successfully deploy an assembly containing event handlers for a custom SharePoint list feature (thus, classes that depend on the Microsoft.SharePoint assembly) to a web application's bin instead of the GAC?
The option to do so certainly appears to be present in the XML markup in my feature's manifest.xml file. However, I've seen several references that deploying CAS policies for the assembly are a must with little instruction on how to successfully achieve this for an assembly that requires privileges like access to the SharePoint object model. I've also seen discussion suggesting that the GAC is nearly a requirement because of difficulties/issues with CAS.
I have been able to actually deploy the assembly to the folder. The security issues however, have been a big impediment. The only way I've been able to get my assembly to run (instead of simply erroring out with exceptions) is by elevating the web.config's trust level to <trust level="Full" originUrl=""> which won't fly in my environment. I'm hoping to verify that what I'm trying to do is possible before I continue to further wrestle with CAS.
If this is possible, if anyone has guidance or resources that would assist me in modifying my feature to deploy my event handlers in this fashion, I'd appreciate it.
Don't elevate the web.config's trust level - pretty large hammer for a tiny problem. You must package up a custom CAS policy in your WSP to grant your assembly higher privileges that the web.config bestows on it.
-Oisin
One way to approach this is to crank up the logging, record the various exceptions that are thrown and then write a CAS policy manually. This is a very probabalistic approach and rather painful.
It seems likely that all of the permission demands for any given method or class are known up front. If so, it should be possible to write a tool to statically analyse your code and dependant assemblies and compose the required CAS file. Unfortunately, I'm not aware of any tool that does this.
For what it's worth, GAC'ing your assembly seems much "lighter" than upping the trust level.
If I got your question right, you want to deploy a list event receiver to the web application's BIN directory.
This is not possible within SharePoint 2010, but I don't know if it was supported on MOSS 2007 (i guess it wasn't supported either).
This behavior is by design, because SharePoint internally uses the System.Reflection.Assembly.Load() Method to load the event receiver assembly. The Load() method does only work with fully qualified assembly names, thus requiring the assembly to reside in the global assembly cache.