Thursday, June 10, 2010

HTTP 401.1 and DisableLoopbackCheck

A colleague of mine setup a new WSS Virtual Machine a few days ago, made a website in WSS, configured it to work with a FQDN and when he tried to access the website using Internet Explorer, he got the annoying generic error message from his browser.

We looked at IIS logs and saw one of quite common HTTP errors there. It was HTTP 401.1 again. I remembered of the most common cause of that error, made a workaround on my colleague's VM and thought it would be good to blog about it as it happened so many times to people I know.

The error was generated because of a security feature (or security fix) called loopback security check. The feature is present in Windows Server 2003 SP1 and later (including Windows Server 2008).

I will not write here about how to work around this problem because it was already explained in detail in the following KB article: http://support.microsoft.com/kb/896861.

A nice explanation about loopback check and effects it can have on your WSS or MOSS installation can be found here: http://www.harbar.net/archive/2009/07/02/disableloopbackcheck-amp-sharepoint-what-every-admin-and-developer-should-know.aspx

Tuesday, March 30, 2010

Creating a 2048 bit certificate request from VisualSVN Server

A few days ago we decided not to use self signed certificates with our Subversion Servers anymore and decided to buy a certificate approved by a certificate authority.

I went to VisualSVN Manager, made a certificate request, pasted it into the certificate request form on the website of one of certificate authorities and submitted the form. I was surprised when I saw an error message saying that certificate request has to be generated with a private key with at least 2048 bit encryption. I went back to VisualSVN Manager to find the step where I can specify the type of the key I want to use but I was not able to find such setting in the certificate request wizard.

It took me a few minutes to find a few posts on the net and to combine them into a working solution so I thought it would be nice to share those findings with others.

Here are the steps you need to take in order to generate a 2048 bit certificate request using VisualSVN Manager:
  1. You first need to create a new private key for VisualSVN Manager to use it when creating a request. To do that you should follow the next steps:
    1. Open command prompt
    2. Type the following command:
      openssl.exe genrsa 2048 > private.key
    3. After that you will be able to find a new file called "private.key" in your working folder. Edit the file in a text editor and leave it for now.
    4. Check if your new private key has the right length by executing next command in command prompt:
      openssl.exe rsa -noout -text -in private.key
    5. Check the output of command executed under 1.d. and see if you can find next text in it: "Private-Key: (2048 bit)"

  2. Now you need to update "server.pem" file for your VisualSVN Server. To do that follow the next steps:
    1. Open Windows Explorer and navigate to root folder of your VisualSVN Server installation (it was in "C:\Program Files\VisualSVN Server\" on my server)
    2. Find "server.pem" file (it was in "conf" folder on my server)
    3. Edit "server.pem" file with a text editor
    4. Replace everything between "-----BEGIN RSA PRIVATE KEY-----" and "-----END RSA PRIVATE KEY-----" with the content from "private.key" you generate in step 1.b. and save changes for "server.pem".

  3. You should now re-create the self signed certificate for your VisualSVN Server to be able to use Subversion until you acquire and setup a new signed certificate. To do that follow the next steps:
    1. Open VisualSVN Manager
    2. Select "Action" and then "Properties" in menu
    3. Go to "Certificate" tab and click no "Change certificate..." button
    4. Choose "Create new self-signed certificate" option and click "Next >" button
    5. Click on "Next" and "Finish" buttons until you finish with self-signed certificate creation.
    6. Check if the new self-signed certificate has the right key length by executing next command:
      openssl.exe x509 -noout -text -in server.pem
    7. NB: you will have to put the full path to "server.pem" to be able to see
      results; when you get the output of above command you should look for the
      following text: "RSA Public Key: (2048 bit)" - if it is there then you have
      a 2048 bit key

  4. The only thing you still need to do is to create a new 2048 bit certificate. To do that follow the next steps:
    1. Open VisualSVN Manager
    2. Select "Action" and then "Properties" in menu
    3. Go to "Certificate" tab and click no "Change certificate..." button
    4. Choose "Prepare certificate request" option and click "Next >" button
    5. Fill-in the name of your domain that will be used by Subversion for SSL communication
    6. Click Next and fill-in the other required information
After completing above mentioned steps I was able to request a signed 2048 bit certificate for our Subversion and to use for all existing and new repositories.

Saturday, March 20, 2010

SharePoint Custom Error Page

As you may already know SharePoint come out with "friendly" standard error page that does not give sufficient information about error that occurred. Since SharePoint web application presents ASP.NET 2.0 web application it should be easy to set custom error page by changing the web.config file. Unfortunately applying the changes will not take the effect as you expected like they would in pure ASP.NET 2.0 web application.

Fortunately there is an option to avoid seeing that standard SharePoint "friendly" error page by changing several settings in SharePoint web application web.config file. Depending on settings you may see the custom error page you've built or standard ASP.NET error page with full stack trace. During development it is very handy to see standard ASP.NET error page but from user perspective when it come to other environments (staging, acceptance, production) it is better to have error page that has the same look & feel as entire web application.

If you are building a SharePoint web application that is based on publishing site template than you will not be satisfied with out of the box error page since it will significantly differ from look & feel that you've built and also content on that page cannot be updated. For web applications that are based on team site template you will on the other hand usually keep the standard SharePoint error page because it fits in standard team site look & feel. It is important to mention that changing the look & feel of standard SharePoint error page should not be taken into consideration for several reasons, one is that changes will take effect on whole SharePoint server instance and all web applications that are created within that instance, second is any possible Microsoft update that can overwrite your custom changes.

Although this post is not about explaining of how to setup the standard ASP.NET error page still I must start my explanation with it because it is a good starting point for setting the custom error page and since most of the developers already know this.

Default configuration inside one SharePoint web application web.config file:

SafeMode
<SafeMode MaxControls="200" CallStack="false" DirectFileDependencies="10" TotalFileDependencies="50" AllowPageLevelTrace="false">
CustomErrors
<customErrors mode="On" >

In order to see the ASP.NET default error page with full stack trace apply next changes to appropriate SharePoint web application web.config file:

SafeMode
<SafeMode MaxControls="200" CallStack="true" DirectFileDependencies="10" TotalFileDependencies="50" AllowPageLevelTrace="false">
CustomErrors
<customErrors mode="Off" >

If you just change the CallStack to true you will see the standard ASP.NET error page but without exception details.

In order to see custom error page you've built (i.e. error.aspx) apply next changes to appropriate SharePoint web application web.config file:

SafeMode
<SafeMode MaxControls="200" CallStack="true" DirectFileDependencies="10" TotalFileDependencies="50" AllowPageLevelTrace="false">
CustomErrors
<customErrors mode="On" defaultRedirect="/Pages/Error.aspx">

Conclusion is quite simple, in order to have the ability to define custom errors mode and default redirect as you already have with standard ASP.NET applications simply set CallStack on true and you will be able to configure your custom error page.

Saturday, January 24, 2009

VisualStudio Add-In for templated/skinned Web Parts generation



A new VisualStudio Add-In was recently released on codeplex. The Add-In is used for Web Parts generation based on prepared ASCX controls/templates. We call those ASCX controls "skins" because you can create multiple ASCX controls for a single web part (those controls can have different layout, styles, etc) and choose a different "skin" during runtime.


How to use it


It's very simple to develop web parts using the Add-In and the process goes like this:


  • Create an ASCX control that defines layout of a web part

  • Create a new web parts project

  • Right click on ASCX control, choose "Generate Web Part"

  • Go to generated web part and add your custom code-behind logic

  • Deploy web part by choosing "Deploy" option for web parts project.

A step-by-step tutorial together with Add-In installation is avaialable on codeproject: http://www.codeproject.com/KB/sharepoint/webparts_generator_addin.aspx

Sunday, October 26, 2008

Programmatically uploading master pages to master pages gallery in MOSS 2007

We recently had a requirement to set a custom master page to a blog site when blog site is created in Microsoft Office SharePoint Server (MOSS) 2007. There are couple of things we had to consider:
  • blog is a separate website with its own Master Pages gallery
  • the master page must be uploaded to blog's Master Pages gallery as soon as blog website is created
  • uploaded master page must be assigned to blog as soon as blog website is created
  • regular users (non-administrators) should be able to create blog websites

We decided to use "feature-stapling" mechanism in MOSS to be able to get notified when a new blog website is created and to be able to performed the required operations. I will not write about the feature-stapling mechanism in this blog post because it is fully covered in other blog posts (like in: http://www.sharepointnutsandbolts.com/2007/05/feature-stapling.html).

We made a custom master page, put it in a folder on file system of a MOSS server and added one feature property to hold full path to master page.

Out class that will handle master page uploading and assigning inherits from SPFeatureReceiver class and the method that peforms required operations executes in elevated privileges context.

Next listing shows the code that performs above mentioned operations:




private void UploadMasterPage(string pathToBlogMasterPage, SPWeb web)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite blogSite = new SPSite(web.Site.Url))
{
using (SPWeb blogWeb = blogSite.OpenWeb(web.ID))
{

byte[] contents = null;
using (Stream fStream =
File.Open(pathToBlogMasterPage, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
contents = new byte[fStream.Length];
fStream.Position = 0;
fStream.Read(contents, 0, (int)fStream.Length);
fStream.Close();
}

//We need to extract a server relative URL of current web
string webRelativeUrl = web.Site.ServerRelativeUrl + web.Url.Replace(web.Site.Url, "");
string url = webRelativeUrl + "/_catalogs/masterpage/" + BlogCustomMasterpage;

SPFile currentFile = web.Files.Add(url, contents);
web.MasterUrl = web.MasterUrl.Replace(BlogDefaultMasterpage, BlogCustomMasterpage);
web.CustomMasterUrl =
web.CustomMasterUrl.Replace(BlogDefaultMasterpage, BlogCustomMasterpage);
web.Update();
}
}
});
}


NB: pathToBlogMasterPage is extracted from SPFeatureReceiverProperties instance and web is an instance of SPWeb that represents the newly created blog website.

Sunday, October 19, 2008

Paste formatted C# source code into blogger posts

I recently found a very good online tool that allows C# (and other) source code to be pasted into blogger posts as formatted and colorized text: C# code format.

It is very simple to use:

  • copy source code from your IDE (like VisualStudio)
  • paste source code into the source code box on this website: http://www.manoli.net/csharpformat/
  • click on "format my code" button
  • click on the "select all" button
  • copy the HTML code
  • go to your blog post
  • switch to HTML mode (click on "Edit Html" tab)
  • paste copied HTML code

There is one more thing you should do. Either add a link to "csharp.css" file (the file is available for download on the website) to template of your blogger blog or select "embed stylesheet" option before clicking on "format my code" button.

NB: You should be able to use the same tool with other blog engines or any other HTML pages.

Properly disposing SPWeb.Webs items

A while ago I read a great article by Roger Lamb that shows how to properly use and dispose SPSite and SPWeb instances: SharePoint 2007 and WSS 3.0 Dispose Patterns by Example.

One of dispose patterns that he showed is about SPWeb.Webs items disposal. He first showed one of the wrong ways you can use SPWeb.Webs collection:


void WebsLeak()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
foreach (SPWeb innerWeb in outerWeb.Webs)
{
// SPWeb innerWeb leak
}
} // SPWeb object outerWeb.Dispose() automatically called
} // SPSite object siteCollection.Dispose() automatically called
}

Then he showed the right way to handle SPWeb.Webs collection:


void WebsBestPractice()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
foreach (SPWeb innerWeb in outerWeb.Webs)
{
innerWeb.Dispose();
}
} // SPWeb object outerWeb.Dispose() automatically called
} // SPSite object siteCollection.Dispose() automatically called
}

You can see on line 9 that "innerWeb" is disposed as it should be. The thing is that Roger didn't show that innerWeb instance must be used in either "using" block or in "try" block with disposal in "finally" block. If "innerWeb" is not used in "using" block (or in "try & finally") then it may happen that an exception is thrown before innerWeb.Dispose method is called.

I didn't think it is significant and assumed developers will recognize this as a potential leak and will always use "innerWeb" in "using" block. After some time I saw this mistake in source code of web parts being used in production environment and I instructed developers who wrote the code to fix the potential issue. Then I saw the same bug a few days ago on a lecture called "MOSS 2007 for developers - how to avoid mistakes" on a Microsoft conference I attended in Novi Sad.

I thought I should blog about this and point other developers to this issue. Next code shows one of the proper ways SPWeb.Webs should be used and disposed:


void WebsBestPractice()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb outerWeb = siteCollection.OpenWeb())
{
SPWebCollection innerWebs = outerWeb.Webs;
if (innerWebs != null && innerWebs.Count > 0)
{
foreach (SPWeb innerWeb in innerWebs)
{
using (innerWeb)
{
//use innerWeb here
}
}
}
} // SPWeb object outerWeb.Dispose() automatically called
} // SPSite object siteCollection.Dispose() automatically called
}

You can see in line 12 that "innerWeb" is used in "using" block. No matter if an exception happens in line 14, the "innerWeb" will be disposed.