OWA Custom Authentication

Hello,

I am attempting to develop an IIS Authentication Module using C# code (testing on Windows SBS 2011).

The sole purpose of the module is to perform authentication using a custom HTTP header.

Based on the contents of this custom header, a user is authenticated by creating a Principal and assigning it to the "User" attribute of the current HttpContext.

My current code actually works perfectly fine against a helloworld-type test web app : I send a HTTP request using the previously-mentioned custom HTTP Header, the module produces a Principal and the webapp can access it through System.Web.HttpContext.Current.User.Identity.Name and System.Web.HttpContext.Current.User.Identity.IsAuthenticated (which returns true).

Surprisingly, when using the same module for Outlook Web Access (OWA), an error is reported by OWA in the web page : "Outlook Web App didn't initialize. If the problem continues, please contact your helpdesk.", with no additional information. Windows event viewer on the server shows no message relating to this.

Information about the code

Initialization is very simple, I just attach my methods to the "AuthenticateRequest" and "EndRequest" events:

        // Init (IHttpModule Implementation)
        public void Init(HttpApplication ctx)
        {
            // Register Events
            ctx.AuthenticateRequest += new EventHandler(this.Authenticate);
            ctx.EndRequest += new EventHandler(this.IssueAuthChallenge);
        }

The code for the authenticate  method is as follows :

// Authenticate User public void Authenticate(Object src, EventArgs e) { // Acquire Source and Context HttpApplication app = (HttpApplication)src; HttpContext ctx = app.Context; // Acquire Client Certificate HttpClientCertificate client_cert = ctx.Request.ClientCertificate; String client_cn = client_cert.Get(ClientCert_SubjectCN); // Acquire Authentication Headers String username = ctx.Request.Headers[HttpHeader_AuthUsername]; // Drop Invalid Requests if((username == null) || (!(client_cert.IsPresent))) { return; } // Check Client Certificate CN if(client_cn != AllowedClientCN) { return; } // Check Group Membership if(!(AD.isMemberOf(ActiveDirectoryDomain, username, AuthGroup))) { return; } // Authentication Passed - Register User Principal

IPrincipal principal = new GenericPrincipal(new GenericIdentity(username), new String[] { AuthGroup });

HttpContext.Current.User = principal;
            ctx.User = principal;
            Thread.CurrentPrincipal = principal;

}

EndRequest event is handled as follows :

        // Issue Auth Challenge
        public void IssueAuthChallenge(Object src, EventArgs e)
        {
            // Acquire Source and Context
            HttpApplication app = (HttpApplication)src;
            HttpContext ctx = app.Context;

            // Issue Authentication Header
            ctx.Response.AddHeader(HttpHeader_AuthRequired, "Authentication Required");

            // Drop WWW-Authenticate Header
            ctx.Response.Headers.Remove(HttpHeader_WWWAuthenticate);

            // Redirect to Authentication Area
            ctx.Response.StatusCode = HttpStatusCode_Found;
            ctx.Response.AddHeader(HttpHeader_Location, AuthLocation);
        }

Finally, here are the global definitions referenced throughout the code :

        // Active Directory Domain
        public const String ActiveDirectoryDomain = "FOODOM";

        // Allowed Client CN (Reverse-Proxy)
        public const String AllowedClientCN = "FooCertName";

        // Authentication Authorized Group
        public const String AuthGroup = "FooAuthAllowed";

        // Authentication Custom HTTP Header Base
        public const String HttpHeader_AuthBase = "X-FooAuth";

        // HTTP WWW-Authenticate Header
        public const String HttpHeader_WWWAuthenticate = "WWW-Authenticate";

        // HTTP Location Header
        public const String HttpHeader_Location = "Location";

        // Client Certificate Fields
        public const String ClientCert_SubjectCN = "SUBJECTCN";

        // Authentication Custom HTTP Headers
        public const String HttpHeader_AuthRequired = HttpHeader_AuthBase + "-Required";
        public const String HttpHeader_AuthUsername = HttpHeader_AuthBase + "-Username";

        // HTTP Status Codes
        public const int HttpStatusCode_NotAuthorized = 401;
        public const int HttpStatusCode_Found = 302;

        // Authentication Area
        public const String AuthLocation = "/FooAuth";

After spending many hours fiddling with the IIS settings (mostly authentication and SSL options) I simply do not understand why OWA throws an error when my test app works fine. Are there any specifics that need to be performed to allow OWA to authenticate ?




  • Edited by Void.Ptr Monday, July 20, 2015 9:51 AM
July 20th, 2015 8:51am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics