"We need read-only access for anonymous users." Fine.
"We need Forms auth accounts for contributors." No problem.
"We need to redirect users to a secure channel when they log in." OK, this is more challenging.
We can use Web application zones to support multiple access mechanisms, but how do we redirect users between zones when they sign in? This takes a little more trickery.
Let's start with a brief recap on SharePoint zones. Generally, there's a one-to-one mapping between a SharePoint Web application and an IIS Web site. The IIS Web site takes care of user authentication (for Windows auth at least), SSL certificate mapping, and so on. The SharePoint Web application takes care of authorization and serves up content. You can think of the IIS Web site as providing a specific route to the SharePoint Web application, through a specific URL, protocol (http vs. https), and authentication mechanism.
So, what happens if we want to provide more than one route to our SharePoint Web application? In the case of our blog site, we need to provide at least two routes – an http channel for anonymous access, and an https channel for registered users. In other words, we need to map our SharePoint Web application to at least two IIS Web sites. This is where zones come in – when you extend a SharePoint Web application to a new zone, you are effectively mapping it to an additional IIS Web site (with a corresponding configuration file).
In our case, we actually need three zones:
- A default zone that uses Windows authentication to provide search support (more on this later).
- An extranet zone to provide secure, forms-authenticated access to registered users.
- An internet zone to provide read-only access to anonymous users.
So – why the redundant default zone? Because the SharePoint 2007 search service can't use forms authentication for search crawls. If you want to use forms authentication with SharePoint, you must still configure at least one zone for Windows authentication. Furthermore, the Windows authentication zone must be at the top of the list – if you configure the default zone for forms authentication, the search service will try this first and the indexing process will fail. In short, always configure your default zone for Windows authentication.
Now, let's get down to details. I don't want to reinvent the wheel here, so I'm going to assume you can create and configure the default zone and the extranet zone. If you're looking for walkthroughs on zones and forms authentication, the SharePoint Products and Technologies Team Blog has a good post here. In this post, I want to focus on how to redirect users between zones when they sign in.
So, we've got a default zone configured for Windows authentication. Our search service uses this zone to index our blog sites. We've also got an extranet zone configured for forms authentication. Our contributors use this zone to sign in over a secure channel and post content. Next, we need to create an internet zone that:
- Allows anonymous users to read blog entries.
- Redirects users to the extranet zone when they click Sign In.
Number 1 is straightforward. Number 2 gave me a headache. I looked at various ways of redirecting users on sign in. I tried customising the Welcome.ascx control in the Control Templates folder, but I wouldn't recommend opening that particular can of worms. As it turns out, all it requires is a minor change to the configuration file. First, here's a high level overview of how we configured our internet zone:
- Extend the Web application to a new zone, with a host header of http://www.blogs.contoso.com/.
- Configure the policy settings for the new zone to deny write permissions to unauthenticated users.
- In IIS, enable anonymous access and Windows authentication (a temporary measure) for the Web site that corresponds to the internet zone.
- Browse to the site collection using the internet zone URL, sign in, and enable anonymous access at the site collection level.
- Go back to IIS, and clear all authentication types except anonymous access for the site that corresponds to the internet zone.
Change the authentication element to use forms authentication – but don’t add the connection strings, role manager details, membership provider details and so on. Set the login URL for the authentication element to point to the login page for the extranet zone:
<forms loginUrl="https://extranet.blogs.contoso.com/_layouts/login.aspx" />
This provides the behaviour we're looking for. If you access the site anonymously and click Sign In, you’re redirected to the secure URL and authenticated against the membership provider. You’re then redirected back to the same relative URL, but in the secure zone – e.g. if you were browsing http://www.blogs.contoso.com/jasonl, you click sign in and authenticate yourself, and you’re redirected back to https://extranet.blogs.contoso.com/jasonl. Same page, different access mechanism.
How does it work? When the Sign In control redirects you to the login page, it includes the site-relative URL of the page you were visiting as a querystring. When you provide valid credentials, the login page will attempt to send you back to the page you came from – however, because it only has the site-relative URL, it has no idea which zone you came from. As a result, you're redirected to the correct page, but via the secure extranet zone rather than the original internet zone. The end result is you can only access the site anonymously over http, and you can only access the site as an authenticated user over https – perfect.