Stefan Goßner

Senior Escalation Engineer for SharePoint (WSS, SPS, MOSS, SP2010) and MCMS

Blogs

HttpModule to solve glitches when using a posting as login form (updated: 29-04-2005)

  • Comments 10
  • Likes

When designing a MCMS website where forms authentication is the option to go to authenticate users it is very common that the login dialog should be included in a posting.

This will require that guest account is enabled for the site - otherwise the channel holding the posting that holds the login form could not be displayed. Something like a dog biting in its own tail.

After enabling guest account and creating a posting with the login form you need to configure the web.config to point to the URL of the posting. That will work fine till the authentication token expires. When this happens access to all CMS items is denied till either the user has logged out or has logged in again using a valid MCMS user.

In this situation the posting holding the login form cannot be displayed.

To solve this it we need to implement our own authorization module that replaces the module from MCMS and that rebuilds the functionality of the original module.
The Url of the login page has to be configured in the appSettings section of the web.config:

<
configuration>
   
<appSettings>
      
<add key="LoginUrl" value="/loginchannel/loginpage" />
   
</appSettings>
   ...
</configuration>

To install the http module below you need to compile it as C# class library project and replace the reference to the CmsAuthorizationModule in the web.config with the reference to this module.

using System;
using System.Web;
using System.Configuration;
using Microsoft.ContentManagement.Publishing;
using Microsoft.ContentManagement.Web.Security;

namespace
StefanG.HttpModule
{
   
public class EnhancedCmsAuthorizationModule: IHttpModule
   
{

       
public virtual void Init(HttpApplication application)
       
{
           
if (application == null)
           
{
               
throw new ArgumentNullException("HttpApplication == null");
           
}

            // register new Authorization handler

           
application.AuthorizeRequest += 
                        
new EventHandler(this.OnAuthorizeRequest);
       
}

       
public virtual void Dispose()
       
{
            // nothing to do
       
}

       
private void OnAuthorizeRequest(object source, EventArgs e)
       
{
            HttpApplication httpApplication = (HttpApplication)source;

            try
           
{
                // lets try to retrieve the current CmsHttpContext
               
CmsHttpContext cmsContext = CmsHttpContext.Current;

                // ok, we got the context. Now lets see if we have permission 
                // to access the current item. 
                // I
f not, lets present the login page to the user
               
if (!cmsContext.UserHasRightToBrowse())
               
{
                   
redirectToLoginPage(httpApplication);
               
}
                if (!cmsContext.ChannelItemIsVisible())
               
{
                    // Lets dispose the context if the item is shown on one of the
                    // admin pages to avoid problems.
                   
cmsContext.Dispose();
               
}
           
}
           
catch (CmsAccessDeniedException)
           
{
                // ok, no luck accessing the context. Access denied. 
                // We need to logout and redirect to login page
               
redirectToLoginPage(httpApplication);
           
}
       
}

        private void redirectToLoginPage(HttpApplication application)
       
{
            // throw away old authentication token to allow access 
            // to logon posting as guest user
            CmsFormsAuthentication.SignOut();

            // get the URL to the login posting from the appSettings section of 
            // the Web.Config
            string loginUrl = ConfigurationSettings.AppSettings["LoginUrl"];

            // we need to call the login page with the ReturnURL to the item we 
            // tried to access 
if possible we will use the friendly URL
           
string ReturnURL = HttpUtility.UrlEncode
                  (application.Context.Request.QueryString["NRORIGINALURL"]);
           
if (ReturnURL == null
               
ReturnURL = HttpUtility.UrlEncode
                  (application.Context.Request.Url.AbsolutePath+
                   application.Context.Request.Url.Query);

            // ok, now lets redirect to the login page

           
application.Context.Response.Redirect(loginUrl+"?ReturnUrl="+
                  ReturnURL);
           
application.CompleteRequest();
       
}
    }
}


If your application is using custom query strings and you need to ensure that these querystrings are preserved using the solution above you need to ensure that the following MCMS hotfix is installed on your system:

836895 - The query string arrays are not correctly passed to the posting

Comments
  • I had a problem while using this module...

  • Problem corrected in above code. Added the

    if (!cmsContext.ChannelItemIsVisible())
    ...

    check to solve the problems with the approval assistant.

  • Its fine now.

  • Hi,

    I have just started using cms from last month, i have a basic doubt here.

    I have a website which we need to convert their content pages to mcms templates. even their home page. But as far as i have looked i am unable to view the home page as normal internet user because i have to login.

    So can u help me where i just need to show the site as normal to anyone who hits my web site and have a seperate page where web authors can login to do their tasks.

    Thank u,
    Kiran

  • Hi Kiran,

    check out how to enable guest access in MCMS in the MCMS documentation.

    Cheers,
    Stefan

  • When using this solution, what does your authentication node in the web.config file look like?  do you still have a loginUrl there?

  • Hi Jim,

    have a look at the article. At the beginning is the web.config entry.

    Cheers,
    Stefan

  • What I meant was the authorization node in web.config.  do you have a forms authentication node there and, if so, do you specify a loginUrl there also?

  • The authorization node is the same as always when using forms authentication. No modification required. The loginUrl property of the authorization node is ignored.

  • PingBack from http://www.keyongtech.com/361208-user-verify

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment