Friday, 27 May 2011

SharePoint 2010: 'Hiding' Folders in a Document Library

One challenge we always face when working with clients is to respond to requests that don't use a technical solution exactly as it should be used. Case in point: a client is now working in a new SharePoint 2010 environment we're building out. They're working within a Document Library, and they want to hide a folder from view of (most) users. Not a problem. Use Permissions, right? Wrong. Client doesn't want to hassle with Permissions, but simply wants to hide a folder so only a few people who know about it can upload content to that folder by going directly there via a URL.
Check out the screenshots below.
I met the challenge by:
  • Creating a Folder Content Type called “Special Folder”
  • Creating a Site Column called “Hidden Folder” as a Choice list with “Yes” set as the Default Value
  • Attaching the Site Column “Hidden Folder” to the Content Type “Special Folder” (making it required)
  • Modifying the default View of the Shared Documents Document Library to hide the folder if the Content Type “Hidden Folder” is set to “Yes”.
This nets out to a simple scenario: The client can create a folder called “Special Folder” which will be hidden from being seen in the Document Library. The client can access the folder by opening the Document Library in Explorer view via an exact URL, the folder(s) can be seen and documents can be uploaded into the folder(s) but remain out of sight because the folders are hidden.
Not an ideal solution (Permissions would be a better choice), but it does satisfy the client need. Case closed? I hope not.
 Is there another (EASIER) way to do this?
VIEWS:
Standard Document Library (note there is no folder in view)

Creating the Site Column (Note that "Yes" is the default choice)

Creating the site column

Creating the Custom Content Type called Special Folder

Creating the Content Type

Viewing the Content Type settings (Note that the Site Column Hidden Folder is attached to this Content Type)

Custom Content Type




Creating a new Special Folder (Note that this folder will be hidden and will not appear in the Document Library)

Creating a New Hidden Folder

Creating a new Special Folder (Note that this folder will be hidden and will not appear in the Document Library)

Creating a new folder


Opening the Document Library in Explorer View (Note that we still don't see the new Hidden Folder)

Open with Explorer View

Hidden folder in Explorer view (Note that documents copy/pasted into this folder will not be visible in the Document Library view)

Hidden Folder in Explorer View

Friday, 20 May 2011

SharePoint Search

Create and Configure a Scope to Only Return Documents in a Search Result


It is evident that SharePoint can index content in web sites, file shares, exchange public folders, or any other content that has a URL. However, many users like to execute a search which is restricted to a specific type of content such as Tasks, Announcements, Events, Documents, Blogs etc or a content source such as a document workspace or a team site or a file share etc. On a similar note I would like to quote what one of our customers who was evaluating our search product Longitude for SharePoint asked for.
"We are most concerned with documents and to us, most of the other items that come up that may contain the search string are clutter and it would be nice to easily filter them out"
The customer basically wanted a provision to narrow down search to documents only and was not interested in the announcements, events, and wiki pages etc that came up in the resutls.Typically when the requirement is about being able to execute a search restricted to a content type or a content source, SharePoint Search scope is the way to go.
In this article, we will go through all those configurations required to create a search scope that will be dedicated to return only documents. Before we start with the configurations required, let's take a look at the basics of SharePoint search scope.
In an enterprise, gigs and terabytes of data is crawled from various content sources on a regular basis. The crawls create a single content index representing all the content sources. SharePoint provides search scopes as a way to filter the content index to define a subset of it. By effectively defining a section of the content index a head of the query time, search scopes facilitate to limit the results that are returned from the index. Search scopes are pre-compiled and efficient.
SharePoint has two types of search scopes.
The Contextual scopes are created automatically based on the context of the site area user is currently working on such as a web or a list etc. In a SharePoint site, these scopes read like "this site", "this list" etc.
The Custom Scopes are the ones that an administrator can create to target a specific type of content. Two types of custom scopes can be created:
  • SSP Level Scopes are global and shared across all the site collections that are associated with the SSP. The SSP level scopes are managed at the SSP level by a farm administrator.
  • Site collection level scopes are local to a site collection and are managed by the site collection administrator.
Create a scope to return only documents in search
In the steps outlined below, we will be creating a SSP level scope called "All Documents" and add a rule to include only documents.
Step1: Create a all documents scope
  • Browse to the central administration site and Click on the SSP.
  • Click on search settings and then Click on view Scopes.
  • Click on new scope link.
  • Enter title as "All Documents" and leave other details blank and Click OK.
Step2: Allow the "IsDocument" property to be used in scopes
IsDocument is a managed property provided by SharePoint and is true for all documents only. Therefore, before adding a scope rule to the scope "All Documents", we must ensure that this property can be used in scope. Follow the steps to allow the property to be used in scopes.
  • Browse to the central administration site.
  • Click on the Shared Service Provider (SSP).
  • Click on Search settings
  • Click on metadata property mappings.
  • Find the managed property IsDocument and set "Use in Scope" property to true and Click Ok.
Step3: Add scope rule
  • Browse to the central administration site.
  • Click on the Shared Service Provider (SSP) for the site.
  • Click on Search settings
  • Click on View Scopes.
  • Click on Edit Properties and rules for the scope "All Documents".
  • Click on New Rule.
  • Add a property query rule where the property IsDocument=1 and set the scope behavior to require and click OK.
Step4: Add the scope to a scope display group
A scope display group is used to organize a list of scopes. The scope display group is then assigned to a search box to be able to search on those scopes. To add the scope "All Documents" to a scope display group, follow the steps below:
  • Browse to the site collection for your search center (This is the site collection which has your search page).
  • Select Site actions>Site settings>Search scopes. You will notice that the scope "All Documents" has no scope display group assigned at this time. We can either create a new display group and add or add it to an existing group.
  • Click on the scope display group "Search Dropdown" and Select the scope "All Documents".
Step5: Using the scope display group for a search box web part
The scope display group "Search Dropdown" has our scope included in it. In this step, we will ensure that our search box webpart uses this scope display group.
  • Browse to the search page and select site actions>edit page.
  • Select edit>modify shared webpart on the search box web part.
  • On the properties pane, expand the section miscellaneous and check the property value for the property scope display group and make sure that it is "Search Dropdown" as selected at #Step4.
Step6: Update the scope
Unless the scope is updated, it will not appear on the scopes dropdown of the search box webpart. To update the scope, follow the steps below.
  • Browse to the central administration site and Click the SSP for the site collection.
  • Click on search settings and then Click on Start update now.
We are done. The scope "All Documents" must be available on the scopes dropdown of the search box webpart. If it does not, you would want to make sure that show scope dropdown option is selected for the webpart.
Finally, some frequently asked business requirements questions from our customers where search scopes have been used.
1) I have a content source (cs1) which is an archive of past projects and is static and I have another content source (cs2) which has all active projects with dynamic content. I crawl cs1 once a week and crawl cs2 once a day. However, I want to be able to search results from both content sources at one place in a Global Search Center.
  • Create a scope say "Global Scope".
  • Add an include rule by selecting cs1 as the content source.
  • Add another include rule by selecting cs2 as the content source.
  • Use the scope "Global Scope" in your Global Search Center to be able to view results from both the site collections at one place.
2) How do I get only PDF documents in my search results?

  • Create a scope say "PDF Documents"
  • Add a property query based rule where FileExtension is equal to pdf.
  • Set the scope rule behavior to include.
  • Update the scopes.
  • Search using the scope "PDF Documents".
3) I want to search on only those documents that have been tagged as "Legal Documents".
This requirement has got two aspects of it:

  • Results must be documents not a blog posts or wiki pages or a list item etc
  • Results must have only those documents which have been tagged as Legal documents.
Here you will have to create a document with two scope rules. The first would be to include all the documents from the content index and the second would be to ensure that only Legal documents are included. Assuming that you have a managed property called "Tag" mapped to the column that stores the tags for the documents, follow the steps below to create a scope to search against.

  • Create a scope say "Legal Documents"
  • Add a property query based rule where IsDocument is equal to 1 and Set the scope rule behavior to include.
  • Add another property query based rule where Tag is equal to "Legal" and Set the scope rule behavior to require.
  • Update the scopes.
  • Search using the scope "Legal Documents".
4) I want to search on only those documents that have been tagged as "Legal Documents" and are not authored by Martin.
As opposed to the requirement #3, this one has got three aspects of it:

  • Results must be documents not a blog posts or wiki pages or a list item etc
  • Results must have only those documents which have been tagged as Legal documents.
  • Results must not have those documents which are authored by Martin.
In addition to the two rules as mentioned #3, we would also need a third rule to exclude those documents where Martin is the author. Therefore, assuming that you have a managed property called "Tag" mapped to the column that stores the tags for the documents, follow the steps below to create a scope to search against.

  • Create a scope say "Legal Documents"
  • Add a property query based rule where IsDocument is equal to 1 and Set the scope rule behavior to include.
  • Add another property query based rule where Tag is equal to "Legal" and Set the scope rule behavior to require.
  • Add another property query based rule where Author is equal to "Martin" and Set the scope rule behavior to exclude.
  • Update the scopes.
  • Search using the scope "Legal Documents".
5) I have many blog sites which are spread over different site collections. How do I have a search scope that returns only blogs related results.
This requirement is to include content specific i.e. blog related items in the search scope that can be search against. We must see if there is a property which represents a specific type of content. Fortunately, contentclass is one such property that distinguishes content from one another. Therefore follow the steps below to create a scope.
  • Create a scope say "Blogs"
  • Add a property query based rule where contentClass is equal to "sts_listitem_posts" and Set the scope rule behavior to include.
  • Add another property query based rule where contentClass is equal to "sts_listitem_comments" and Set the scope rule behavior to include.
  • Update the scopes.
  • Search using the scope "Blogs".
Note: Just like "sts_listitem_posts" and "sts_listitem_comments", there are other pre-defined values Sharepoint assigns to the property contentClass to represent different types of content. The table below has most of them.

STS_Document

STS_List_Comments

STS_List_300

STS_List_Contacts

STS_List_850

STS_List_DiscussionBoard

STS_List_Announcements

STS_List_DocumentLibrary

STS_List_Categories

STS_List_Events

STS_List_GenericList

STS_list_Links

STS_List_PictureLibrary

STS_List_Posts

STS_List_Tasks

STS_ListItem_300

STS_ListItem_850

STS_ListItem_Announcements

STS_ListItem_Categories

STS_ListItem_Comments

STS_ListItem_Contacts

STS_ListItem_DiscussionBoard

STS_ListItem_DocumentLibrary

STS_ListItem_Events

STS_ListItem_GenericList

STS_ListItem_Links

STS_ListItem_Posts

STS_Site

STS_Web


Wednesday, 18 May 2011

Automating Variation

This help you to automate the Site Variation in SharePoint 2010
Set the variation settings, create variation labels and create a site hiearchy by activating a feature.

Welcome to this project which is made to create a multi-language SharePoint site a bite more easier.

Through the feature properties in the feature.xml you can configure how you want your variation settings and variation labels.
After activation of the feature it will:
set the variation settings
create the variation labels
create the site hierarchies

http://autovariation.codeplex.com/

Site Template vs Site Definition

Site Definitions
  • A site definition is the core definition of what a site is in SharePoint.
  • A site definition is installed on file system of web front ends, located at ..\12\Template\SiteTemplates. This directory is language-neutral.
  • A site definition consists of .aspx pages and .xml files with Collaborative Application Mark-up Language (CAML).
  • A major benefit is that the Page and List definition is read locally from the file system, not from Content Database.

    Site Template
    • A site template (*.stp file) is created through the user interface or through implementation of the object model.
    • The site template package is a package containing a set of differences and changes from a base site definition.
    • The site template package is stored as a CAB-based file that can be downloaded or uploaded to site collections by users with the appropriate rights. 
    When choosing whether to create a site template or a site definition, first consider the following issues:

    Are the changes you need to make simple or complex? If, for example, you need to make only minor changes in the look of certain pages and add a few fields in particular lists, you should create a custom site template.

    However, if you need to create new content types, add new Web Part definitions, and significantly restructure sites, you should create a custom site definition.

    Can you deploy changes to the front-end Web server? If you do not have access to the file system of the computers running Windows SharePoint Services, you have no choice but to create a custom site template.

    Site definition (Advantages):
    • Data is stored directly on the Web servers, so performance is typically better.
    • A higher level of list customization is possible through direct editing of a Schema.xml file.
    • Certain kinds of customization to sites or lists require use of site definitions, such as introducing new file types, defining view styles, or modifying the Edit menu.

    Site definition (Disadvantages):
    • Customization of site definition requires more effort than creating custom templates.
    • Editing a site definition after it has been deployed is difficult.
    • Doing anything other than adding code can break existing sites.
    • Users cannot apply a SharePoint theme through a site definition.
    • Users cannot create two lists of the same type with different default content.
    • Customizing site definitions requires access to the file system of the front-end Web server.

    Site Templates (Advantages):
    • Custom templates are easy to create.
    • Almost anything that can be done in the user interface can be preserved in the template.
    • Custom templates can be modified without affecting existing sites that have been created from the templates.
    • Custom templates are easy to deploy.


    Site Templates (Disadvantages):
    • Custom templates are not created in a development environment.
    • Custom templates are less efficient in large-scale environments.
    • If the site definition on which the custom template is based does not exist on the front-end server or servers, the custom template does not work.

    Tuesday, 3 May 2011

    Impersonation in Asp.Net

    Several questions have come up about accessing resources while executing an ASP.Net web request. I decided to create a review of the different configuration options and how that affects the identity ASP.Net uses to process a request. Choosing the correct security model to use is extremely important in making a website secure and the implications of those decisions needs to be understood to avoid common programming pitfalls.
    For setting the appropriate permissions it is essential to know which account to set. Hopefully this will clear up some of the confusion about account information. ASP.Net supports the following authentication modes, None, Windows and Forms. None as it's name implies does not perform any type of authentication and runs under the default identity. Windows supports both basic and integrated authentication. Forms supports the ASP.Net forms authentication. I will not be covering Forms authentication as that falls into the realm of custom authentication. I'm also not going to cover Passport as it is rarely used.
    As part of the ASP.Net request life cycle, we can capture the AuthenticateRequest event when a request is received. This event always fires and is raised by the Application. It can be handled in the Global.asax. This event is also handy for capturing the actual user's identity and replacing the users principal with our own. This will be covered.The areas we will be looking at are the AuthenticateRequest event, the web.config setting for setting up the identity and how IIS interacts with the settings.
    I will not be reviewing how to secure a website. I will also not be focusing on how to change the identity the process runs under. There are many excellent references on these topics already.Determining IdentityTo determine the identity used for the request I set up a single aspx page that writes out the three most common ways of getting the current identity from a web application. These are the Page.User.Identity, System.Security.Pricipal.WindowsIdentity.GetCurrent() and system.Threading.Thread.CurrentPrincipal.Identity. The code for the Page_Load event is displayed in Listing 1. The IIS Security Settings dialog can be seen in Figure 1. This displays the options available for configuring web security with IIS.
    Listing 1.
    private void Page_Load(object sender, System.EventArgs e)

    {
    dlblUser.Text = Page.User.Identity.Name;
    lblWindow.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
    lblThread.Text = System.Threading.Thread.CurrentPrincipal.Identity.Name;
    }



    Anonymous Access


    If we are setting a public informational website, we may not need the users to be identified. This is known as anonymous access. In this case IIS will authenticate using a pre-determined account and the request will use the default ASP.Net account. Anonymous is set in IIS by selecting the Anonymous Access. Once this is set, no authentication will be made against the user regardless of any other selected authentication modes. The only mode available in the web.config with this authentication is Forms. The identities can be seen in Figure 2. As you can see the only item populated is the Windows identity running as ASPNET. This is the default account for IIS 5.x.




    So what does this mean? This indicates that if you are using anonymous access then the ASPNET account will have to have the appropriate permissions to access the files that are needed on the server. It also means that if you are planning on using Integrated Security on SQL Server, this account must have the appropriate permission in SQL Server.

    Now, if you wanted to perform your own custom security, including Forms authentication, you could create a GenericIdentity and GenericPricipal to use in place of the default Page.User. this allows you to send the user's information to your middle tier without depending on using the HttpContext. The code to perform this is shown in Listing 2. You can find many good examples of how to implement this in your own application. The results of this change can be seen in Figure 3. As you can see we are still making the actual resource requests using the ASPNET account.

    Listing 2.

    System.Security.Principal.GenericIdentity id = new System.Security.Principal.GenericIdentity("Darth Vader");

    System.Security.Principal.GenericPrincipal p = new System.Security.Principal.GenericPrincipal(id, new string[]{"Dark Side", "Sith"});

    HttpContext.Current.User = p;





    Authenticated Requests


    If we want authenticated request to obtain the user's actual identity, we need to deselect the Allow Anonymous with IIS. We then have to select one of the authentication methods. the two most commonly used selection are Basic and Windows Integrated. The Basic authentication will prompt the user to enter a user name and password which are sent in the http header. Windows integrated security only works with Internet Explorer. It does not prompt the user but takes the current user's credentials they used to log onto their machine and tries to authenticate. If that fails, then it will ask for a user name and password. Unlike Basic authentication, it does not send the password in plain text, it send the password hash. This is more secure then Basic but typically should be limited to intranet scenarios. Both of these methods can be used over the internet using https.

    If we set the mode attribute of the authentication element in the web .config to None while requiring authentication in IIS you can see in Figure 4 we have the same result as allowing anonymous in IIS. If we change the mode to Windows we have a different result as we can see in Figure 5. Now, even though we are actually capturing the authentication, our request are still being made under the ASPNET account.




    To get the request to run under our identity, we need to add an additional element to our web.config file to tell the .Net runtime to impersonate the actual requester. This is the identity element. We set the impersonate attribute to true to set up the impersonation as in Listing 3. The effect of this change on our identity can be seen in Figure 6. We are now impersonating the actual requestor. This does deserve some additional discussion as it can lead to some permissions errors. This account will be used to access the appropriate resources on the host machine. This works regardless of whether we are using Basic or Windows Integrated authentication as we are authenticated against the server. If we try to access remote resource we see an important difference. Since Windows integrated authentication only passes the hash of the password, the server cannot authenticate us against any other servers, the delegation ends at the web server. If we try and connect to any remote resources we will see a failure in the authentication. This is known as the "double-hop" issue. This is not an issue with Basic authentication since we have been passed the password in plain text. This allows the server to further authenticate against any other server on our behalf.

    An interesting anomaly is when using Windows Integrated authentication with impersonation on an application and running from the local machine. This avoids the double hop since it can obtain your user credentials from the Windows logon. It will then forward those credentials and be able to connect if you have permission. This sometimes confuses developers and leads to those famous words when the application is moved to production, "It works on my machine."

    Listing 3.

    <identity impersonate="true" />




    Now if we want to run under a fixed account for accessing resources on the server and connecting to say SQL Server using Windows Integrated authentication. You could use Basic authentication but this is considered very insecure even on an intranet. We could also use Basic over https but this could lead to performance issues. I have experienced increases in the request time of up to 30% with https. ASP.Net allows the application to run under a separate account by adding the userName and password attributes of the identity element in the web.config. The new identity element is shown in Listing 4 with the results shown in Figure 7. For this to be successful, the user account must be granted full control of the ASP.Net Temporary Files folder in order to create the shadow copy. Also note that we have the actual user that made the request while any resource requests will be made using the application account. We can also run with these settings under Allow Anonymous within IIS. We would still be making the requests under our application account but we would lose the identity of the actual requestor. This is still useful for allowing Integrated authentication against remote resources and SQL Server.

    Listing 4.

    <identity impersonate="true" userName="joe" password="joeuser" />



    Security Issues

    It is essential in any security configuration that care be taken. Too often we grant excessive permission to an account because "it's easier to work with". One of the keys to good security is understanding what access is needed and only providing the minimal amount. If an account is compromised, then we need to limit the amount of damage an attacker can do. You can follow this link to determine what permissions are required for an ASP.Net application account, Process and request identity in ASP.Net.

    A concern with using application accounts is the fact that you have to place the user name and password in the web.config file. Even though .config files are prevented from being served by the runtime this does not mean the file is secure. A misconfigured server could allow someone to see the web.config and the account being used. This can create an unacceptable risk. Microsoft has incorporated a means of encrypting the user name and password and placing them in the registry. The details of the procedure can be found at How to use the ASP.Net utility to encrypt credentials and session state connection strings.

    Differences in IIS 6.0


    IIS runs under what is know as application pools. Each pool can use a different user name and password for processing the request. The name that is specified in the pool will be the default account for your application. All the other information presented here behaves the same.