This blog post relates a successful CASification of Outlook Web Access.
This new method can help you to CASify Outlook Web Access. Changed must be made in CAS, minor change in OWA.
CAS and OWA at Azusa Pacific University
History
At the beginning of this year the systems engineering group at APU was charged with migrating our 15,000 student mail accounts from Cyrus IMAP to an Exchange OWA solution. As Senior Systems Engineer at that time, I was the one who had to make it all happen. At the beginning of the summer the project was suddenly put into an indefinite hold when our CIO declared it a mandatory strategic priority that no applications require re-authentication when linked from uportal. This decree was aimed specifically at OWA. At first the task of resolving this issue was assigned to our development staff, however their workload and inexperience with Win32 programming seemed an insurmountable hurdle to clear before the August implementation timeframe. Foolishly I took it upon myself to resolve the issue, and press on with the project.
Solution, Part 1: The CAS ISAPI authentication filter
IIS allows for extension via the ISAPI protocol. There is a fair quantity of examples and information on both ISAPI filters and extensions online as well as existing CAS ISAPI filters from IU and CCCI, so finding a solution to this portion was not difficult. I actually decided to write my own CAS authentication filter using these examples both to simplify the code for my purposes, and as an exercise in writing VC++ (my first attempt at this). Ultimately, an ISAPI filter will never fulfill the authentication needs of OWA by itself, however.
Problem: OWA authentication architecture
OWA itself uses IIS authentication, however Microsoft Exchange does not... really. OWA is structured around a front-end back-end authentication scheme with IIS providing front-end authentication, but with real access control residing on the back-end exchange server. Even with authentication disabled, or granted to anonymous, in IIS the user is still required to have a proper Kerberos ticket, or to re-enter username and password in order to access the mail store.
Ideally CAS authentication to OWA would use protocol transition and constrained delegation to create a ticket on the user's behalf and then authenticate to the back-end. After looking into this a little I realized it was over my head as a part-time relief programmer, and I did not pursue it further.
Somehow... meaning I don't know exactly how... the back-end server will recognize certain front-end authentication. Specifically, basic authentication to IIS will get passed through to the back-end server. Because I already knew how an IIS ISAPI filter worked I figured I could do some HTTP manipulation to exploit this characteristic.
Solution, Part 2: The cas2owa ISAPI filter
This is where it turns into a hack!
There was no way for me to know every users password, in order to stuff it into the HTTP authorization header, and so I would have to use an account where I could know the credentials. An account with administrator access to the mail stores, and the Exchange permissions to read all mailboxes would suffice. The permissions to read all are not given by default even to exchange administrators, and so have to be specifically added to the account. Using this account I created a filter that intercepts requests to OWA and after verifying CAS authentication inserts an authorization string for this account into the HTTP request. And that's really all that's happening.
Process
1. All http traffic to the OWA server is subjected to CAS authentication through the CAS ISAPI filter. When successfully authenticated the filter drops a session cookie where the value is equal to the authenticated username.
2. All http traffic to the OWA server mailboxes is subjected to the cas2owa filter. The filter looks for the CASIIS cookie and either denies access or retrieves the valid username.
3. The filter checks the username against the URL. If the requested mailbox in the URL https://exchange.server.edu/exchange/requestedmailbox equals the username from the cookie the request proceeds, otherwise the request is redirected to the user's appropriate mailbox. I this way no one can request a mailbox other than the one that matches their username.
Surprisingly this works...
Problems
There were various problems with my code that had to be fixed at first as well as one issue with a link in OWA that was peculiar from all the others, but I fixed those quickly.
Long term problems obviously revolve around having one "proxy user" instead of each individual account authenticating to the server.
1. Public folder permissions see only one user and permissions can not be applied to different groups or users. I have disallowed public folder viewing for students (This was requested anyway) but we have had to provide a different OWA server that uses standard OWA authentication for the Faculty and Staff to view public folders (They mostly use outlook anyway).
2. Not that windows logs are all that great, but there are no records for each individual user.
I implemented this "solution" on Exchange 2003 and Windows 2003 Enterprise Server with Visual Studio .NET Academic Edition.
I hope these quick notes help a little. I certainly don't find this solution elegant or even satisfactory, but everyone else in my department does so ... Good Luck!
If you dare, you can download the source here: http://home.apu.edu/~jbeekman/cas2owa/
- Jarod Beekman, Azusa Pacific University
I don't know where to post my solution, so I post it here and hope someone reads the comment. First, you need to have the OWA server in forms login mode.
I've developed my own CAS server in Java, which is a standalone server using simpleweb java HTTP server to serv any users. It was pure java until I found some kind of bug in Java5 SSL which now forces me to tunnel all connections with "stunnel".
Anyway, my solution to OWA is a real hack:
1) For each ticket granting cookie that is alive, I keep an internal database of usernames and passwords connected to that cookie.
2) For validation requests from the OWA login page, I have an extended response that:
2.1) logs in to OWA in the background with the stored username password
2.2) retrieves the cookie 'sessionid' and 'cadata'
2.3) returns these cookies as two extra items in the CAS 1.0 response:
yes
username
sessionid=asdkjaskdjsakdjasdsa
cadata=kldfmsfseifsiefneifnsef
3) On the OWA server I have the standard CAS 1.0 ASP redirect code, with this modification:
var resp=http.responseText.split('\n'); // Lines become array members
if (resp[0]=="yes") // Logon successful
greeting=resp[1]; // get userid for message
Response.AddHeader("Set-Cookie",resp[2]);
Response.AddHeader("Set-Cookie",resp[3]);
Response.Redirect("https://owaserver.domain.com/exchange/");
This sets the correct cookies (which contains an encrypted username/password pair) from the OWA server, but transparently to the user.
Sparse info, but i hope someone can get some idea from this.
/Martin
Thanks for sharing your experience. I'm also interested in CASifying OWA and I really need to send the proper user credentials to Exchange in order to access the calendars and public folders properly. So I'm really interested by your solution but unfortunately, I'm afraid that it is not detailed enough to be exploited. For example, you say that for each ticket, you "keep an internal database of usernames and passwords". How do you perform that? Is it at the login page or using an external user database or LDAP directory?
Thanks for any complementary information.
We did run into an issue with public folders after implementing this. Also with Windows Mobile devices that connected to exchange. In the end we limited cas authentication to requests that originally called the url http://server.apu.edu/cas, and let all other requests use basic auth. This worked for us because most public folder users went straight to the url http://server.apu.edu without ever logging into the campus portal. This did prevent, however, thier logging into the portal without a password after ending their owa session.
We got it working, with Cosign http://www.umich.edu/~umweb/software/cosign/. I never had success with CAS and a MIT KDC, seems to be based on encryption and developement for Microsoft KDC. So I used Cosign for Cookie creation and adapted the cas2owa.dll to cosign.
Thanks for posting this DLL !
Chris