Jun
28

Moving to the cloud with BPOS – Public Folders

Microsoft Business Productivity Online Standard Suite (BPOS) is a set of messaging and collaboration solutions hosted by Microsoft, and consists of Exchange Online, SharePoint Online, Office Live Meeting, and Office Communications Online.

Unfortunately, public folders are not supported by BPOS. To migrate your old public folders to BPOS, you’ll need to find a workaround.

One of the ways to migrate your old Shared Folders, is by creating a shared mailbox that everybody can access.

The easiest way to set up a Shared Mailbox, is to create a new BPOS account (for example shared@example.com). On a client machine, you can install the Microsoft Online Services Sign In tool, which you can download from http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=5c2ca866-4107-4ae5-98d5-76bf1b18ff87 .

The Sign In Tool will configure your outlook to access the new mailbox. Once your outlook is restored, you can import a PST file containing your public folders to your new mailbox and Outlook will start synchronizing with BPOS. Off course, this will take some time depending on the size of your Public Folders.

Now, we need to give all people access to this new shared mailbox. One way to do this is by right-clicking on the folders and edit the Permissions of the folders as shown in the figures below.

image

This looks like the easiest way, but there’s one problem with this method: setting Permissions on a folder is not recursive, so you will need to set these permissions on all subfolders. If you have a complex folder structure with lots of subfolders, and you need to give some people access to all folders using this method, good luck!

But there is an alternative way: in BPOS, you can give other people Full Access to a mailbox. So by giving all the members of your team Full Access to the shared mailbox, they will automatically have Full Access to all subfolders of your shared mailbox. To do this, you’ll need to have the Migration Tools installed on the client machine, and use some PowerShell.

To grant somebody full-access to the shared mailbox, you can use the Add-MSOnlineMailPermission as described in http://technet.microsoft.com/en-us/library/ee662271.aspx

An example is shown below:

Add-MSOnlineMailPermission -Identity shared@example.com -Credential $cred -TrustedUser admin@example.com –GrantFullAccess True –GrantSendAs True

This will give the user admin@example.com Full Access and SendAs permissions to the shared@example.com mailbox. This is only a basic example, with some coding skills you’ll easily manage to write a PowerShell script to give all users the needed permissions.

To finish the story, the users still need to open the Shared Mailbox. When using Outlook, they can easily open an additional mailbox. To do this, just follow the steps explained on http://office.microsoft.com/en-us/outlook-help/add-another-person-s-mailbox-to-your-account-HP005242139.aspx.

Good luck migrating to BPOS!

Posted by Pieter-Jan Maenhaut | 2 Comments

Jun
23

SharePoint 2010: transparent login with mixed authentication

Authentication in SharePoint 2007

In SharePoint 2007 it was possible to enable forms based authentication next to windows authentication only by extending a web application and basically running two separate applications on the same content database.

side from the problems with forms based authentication in SharePoint 2007, there were also some usability issues.

  • The two sites are accessed by a different url. For internal users the url could be https://intranet, for external users https://intranet.company.com.
    This is especially a problem when sending links to document or pages. The links point to a different site depending on if an internal or external user copied the link. This lead to a lot of confusion and unexpected errors
  • Email alerts sent by SharePoint itself can contain the wrong urls
  • Smartparts and some other customisations need to be deployed twice
  • Changes to the web.config need to be duplicated

Authentication in SharePoint 2010

SharePoint 2010 comes with a nice new feature that aims to solve this problem: Mixed Authentication. It allows for the configuration of multiple authentication providers (Windows authentication, forms authentication, trusted Identity providers) together using the same url, without having to extend the web application. Both external and internal users would access the web site on https://intranet.company.com for example.

By default the user has to choose the authentication method when upon logging in.

image

While this is very nice, and a great improvement over the previous version, the downside is that there is no more transparent authentication in an intranet environment.

With the correct browser settings is it possible to log on automatically when using windows authentication.

In Internet Explorer it can be configured in the security settings of the Local Intranet zone. These settings can also be pushed through group policies.

image

image

If the intranet is configured correctly, or “detected automatically”, all login attempts will transparently use the windows identity.

Each time a user tries to access the intranet, he is greeted by the “user friendly” choice above. Each time he tries to open a document stored on the intranet, he gets the same login popup.

In an intranet environment, this is simply unacceptable.

The solution for SharePoint 2010

Looking to improve on this situation we found a great blog post by Bryan Porter. By using a custom login page and custom PowerShell snap-in he was able to automatically choose the authentication provider based on the IP address of the user logging in.

The solution consists of two parts

  • A custom PowerShell snap-in that is used to manage the mappings between IP addresses and authentication providers. The mapping is stored in the Hierarchical Object Store, on the level of the Web Application.
  • A custom sign-in page. When the custom sign-in page is loaded it will first check the IP address of the user. Then it will check if the address is mapped to an authentication provider. If it is mapped, the user will be redirected to the sign-in page of that provider. In other words, if the mapping is found the “Select the credentials you want to use to logon to the SharePoint site” step of the sign in process is automated.

In order to use Bryan’s solution we added some features:

  • Wild card mapping. Authentication providers can now be mapped to wildcard IP range, for example 192.168.0.*
  • IPv6 support.
  • Fix the redirection to make “Sign in as a different user” work correctly

After installing the web application can be configured to automatically use Windows Authentication for a certain range of IP’s, and forms authentication for the others.

Update: The project is now available on codeplex: http://spautomaticsignin.codeplex.com/

We are currently using this solution for several customers.

 

Deployment

All commands are executed in the SharePoint 2010 Management Shell

The custom login page is deployed to the SharePoint Root: “C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\IDENTITYMODEL\LOGIN”

The assembly containing the code-behind of the login page and the powershell cmdlet code are deployed to the GAC

  1. Add the solution to the solution store

    stsadm -o addsolution -filename OrbitOne.SharePoint.Claims.SignIn.wsp

  2. Deploy the solution to all web applications

    stsadm -o deploysolution -name OrbitOne.SharePoint.Claims.SignIn.wsp -immediate -allowgacdeployment

    stsadm -o execadmsvcjobs

  3. Register the assembly

    C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\installutil /assemblyname "OrbitOne.SharePoint.Claims.SignIn, Culture=neutral, Version=1.0.0.0, PublicKeyToken=3c7a593397c60142"

Deployment of an updated version

  1. Retract and delete the existing solution

    stsadm -o retractsolution -name OrbitOne.SharePoint.Claims.SignIn.wsp -immediate

    stsadm -o execadmsvcjobs

    stsadm -o deletesolution -name OrbitOne.SharePoint.Claims.SignIn.wsp

  2. Deploy the new solution

    stsadm -o addsolution -filename OrbitOne.SharePoint.Claims.SignIn.wsp

    stsadm -o deploysolution -name OrbitOne.SharePoint.Claims.SignIn.wsp -immediate -allowgacdeployment

    stsadm -o execadmsvcjobs

  3.  

Configuration

In the SharePoint 2010 Management Console:

load the snap-in

Add-PSSnapin ClaimsSignInAdmin

Create a configuration object. Note: the url is the url of your web application

$config = Get-SPSignInConfiguration –webapplication “http://www.website.com”

Mappings can be managed with the following commands

  • View all configured mappings

    $config.ProviderMappings

  • Add a mapping

    $config.ProviderMappings.Add("192.168.20.*","Windows Authentication")

    $config.Update()

  • Remove a mapping

    $config.ProviderMappings.Remove("192.168.20.*")

    $config.Update()

  • Clear all mappings

    $config.ProviderMappings.Clear()

    $config.Update()

 

Configure the custom sign-in page

Configuration of a custom sign-in page is now a fully supported feature. In SharePoint 2007 it was possible to do this in the web.config, in Sharepoint 2010 it is a settings in the Central Administration.

Application Management -> Manage Web Applications

Select one - > Authentication providers –> select the Zone (usually Default)

image

Is there a way to do this from Powershell? It would make the deployment a lot faster.

Code

The IP address to Authentication provider mappings are stored in the Hierarchal Object Store associated with a web application. To create a custom Persisted Object for SharePoint all that is needed is to inherit from SPPersistedObject and mark the fields to persist with the “Persisted” attribute.

public class SignInConfiguration : SPPersistedObject
{
    [Persisted()]
    private Dictionary<string, string> m_providerMappings = new Dictionary<string, string>();
    
    public SignInConfiguration(): base()
    { }

    public SignInConfiguration(string name, SPPersistedObject parent): base(name, parent)
    { }

    public SignInConfiguration(string name, SPPersistedObject parent, Guid id): base(name, parent, id)
    { }
    
    public Dictionary<string, string> ProviderMappings
    {
        get { return m_providerMappings; }
    }
}

To add this object to a web application or to get an existing one from a web application a custom PowerShell cmdlet is used

[Cmdlet("Get", "SPSignInConfiguration", DefaultParameterSetName = "DefaultSet")]
public class SPCmdletGetSignInConfigObject : SPCmdlet
{
   private SPWebApplicationPipeBind m_webAppPipeBind;

   protected override void InternalProcessRecord()
   {
       SPWebApplication webApp = m_webAppPipeBind.Read();
       SignInConfiguration sc = webApp.GetChild<SignInConfiguration>("SignInConfig");
        
       if (sc == null)
       {
           sc = new SignInConfiguration("SignInConfig", webApp);
       }

       sc.Update();
       base.WriteObject(sc);
   }

   [ValidateNotNull]
   [Parameter(Mandatory=true, ValueFromPipeline=true, Position=0)]
   [Alias(new string[] { "WebApplication", "WebApp"})]
   public SPWebApplicationPipeBind Identity
   {
       get { return m_webAppPipeBind; }
       set { m_webAppPipeBind = value; }
   }
}

A SignInConfiguration object is returned for the specified web application. If the configuration does not exist yet a new one will be created. This gives us a reference to the SingInConfig object in the Powershell environment. Any changes are persisted after calling the Update() method on the object.

Finally, in the code behind of the login page the mappings are retrieved, the IP address of the request is checked against the mappings, and if an authentication provider is found the user is redirected to the provider’s sign-in page.

protected override void OnLoad(EventArgs e)
{
  if (SPContext.Current == null) return;
  if (SPContext.Current.Site == null) return;
  if (SPContext.Current.Site.WebApplication == null) return;

  SPWebApplication app = SPContext.Current.Site.WebApplication;
  SignInConfiguration config = app.GetChild<SignInConfiguration>("SignInConfig");

  SPAlternateUrl u = app.AlternateUrls[Request.Url];
  SPUrlZone zone = u.UrlZone;

  string components = Request.Url.GetComponents(UriComponents.Query, UriFormat.SafeUnescaped);
  SPIisSettings settings = app.IisSettings[zone];

  string ip = IpNetworking.GetIP4Address();
  ip = Regex.Replace(ip, @"^(?<Prefix>(\d{1,3}\.){3})\d{1,3}$", "${Prefix}*");
  if (config != null && config.ProviderMappings.ContainsKey(ip))
  {
      string targetProvider = config.ProviderMappings[ip];
      foreach (SPAuthenticationProvider provider in settings.ClaimsAuthenticationProviders)
      {
          if (string.Compare(provider.DisplayName, targetProvider, true, System.Globalization.CultureInfo.CurrentUICulture) == 0
              || string.Compare(provider.ClaimProviderName, targetProvider, true, System.Globalization.CultureInfo.CurrentUICulture) == 0)
          {
              string url = provider.AuthenticationRedirectionUrl.ToString();
              if (provider is SPWindowsAuthenticationProvider)
              {
                  components = EnsureReturnUrl(components);
              }
              SPUtility.Redirect(url, SPRedirectFlags.Default, this.Context, components);
          }
      }
  }
  else
  {
      SPUtility.Redirect("/_forms/default.aspx", SPRedirectFlags.Default, this.Context, components);   
  }
  base.OnLoad(e);
}
Posted by Mel Gerats | 14 Comments

Jun
09

OData and WCF Data Services

This week we started investigating OData and WCF data services as a way to easily expose and query a remote database.

OData, the Open Data Protocol is a protocol for querying and updating data over using Http and AtomPub

Visual studio 2010 and .NET 4.0 come with rich support to both produce and consume data using the Open Data Protocol.

This post is a tutorial on how to set up a web service that exposes OData, and how to query it from a client application.

Prerequisites

  • Visual Studio 2010
  • .NET 4.0  Framework or the Data Services update for Microsoft .NET Framework 3.5 Service Pack 1

Exposing data as Odata

 

Create a new ASP.NET Web application

image

 

Create the Entity Data Model for the Northwind database

The Entity Data Model will be the base for the WCF Data Service that will expose the Northwind data in the OData format

image

image

image

Here we can choose which Tables, Views and Stored Procedures will be exposed

Finish creates the Entity Data Model for the Northwind database

image

 

Create a new WCF Data Service

image

 

image

 

The NorthwindService inherits from the DataService with as generic parameter the EntityDataModel we want to expose, in this case the NorthwindEntities we just created.

By default noone can do anything, we first need to set access rules for our entities.

The easyest way to do this is to expose all entities with read-all rights:

config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);

If the Entity Data Model is in a different assembly you’ll need to add a reference, and make sure the connectionstring is in the web.config of the referencing project

 

Visiting the service now shows the exposed data:

image

 

 

Consuming the data

To use the data exposed by the web service we create a client application.

Add a Service Reference to the web service.

For testing, there is always a public Northwind web service available on http://services.odata.org/Northwind/Northwind.svc/

image

This generates a web service proxy.

New is that this also generates a DataServiceContext.

Using the DataServiceContext we can query the data service through a linq provider.

The following extremely simple example print a list with the Name and Unit Price of all available products.

 

class Program
{
   static void Main(string[] args)
   {
       string url = "http://localhost:40171/NorthwindService.svc/";
       var context = new NorthwindEntities(new Uri(url));

       var someProducts = from p in context.Products
                          where !p.Discontinued
                          select p;

       foreach (var product in someProducts)
       {
           Console.Out.WriteLine("{0} - {1}",product.ProductName,product.UnitPrice);
       }
       Console.Read();
   }
}

image

Download the sample code:

http://www.orbitone.com/SiteCollectionDocuments/Northwind%20OData%20Service%20Sample.zip

 

More information, samples, articles and tutorials can be found on http://www.odata.org/

Some more links to get you started:

Posted by Mel Gerats | 2 Comments

Jun
02

How to motivate knowledge workers, developers, creative people?

Thanks to a colleague of mine Voicu Matei I came across this very interesting presentation about what actually motivates people:

Giving money rewards works very well to motivate people doing simple, straightforward tasks.

But surprisingly, it has the opposite effect for more complicated tasks that require some conceptual, creative thinking! For these kind of tasks, such as software development, 3 factors lead to better performance & personal satisfaction:

1. Autonomy: the desire to direct our own lives. Self-direction leads to engagement.

2. Challenge and Mastery: the urge to get better at stuff and making a contribution.

3. Purpose: more and more organisations feel that having a transcendent purpose/ motive helps people set higher goals and achieve better results.

This research is completely in-line with the concepts of The New World of Work. We at Orbit One strongly believe in a flexible working environment resulting in people feeling better, and organization being more productive.

See blog post about The New World of Work: http://www.orbitone.com/en/blog/archive/2010/05/03/the-new-world-of-work-het-nieuwe-werken-orbit-one.aspx

Posted by Thijs ter Beek | Leave your feedback

Orbit One on LinkedIn
Contact us - Raas Van Gaverestraat 83, 9000 Gent, Belgium - Tel. +32 (9) 330.15.00 - Privacy Statement - Sitemap - Sign In Developed with Microsoft Office SharePoint Server 2007