ASP.NET 4.0 Single sign on betwen parent website and child web-application fails
Asked Answered
C

2

2

I've got the following structure

www.website.com --> ASP.NET 4.0 Web-site

www.website.com/blog --> NET 4.0, Web-Application

Both do form-authentication against the same SQL database and use the framework ASP.NET memberships and roles. I can log into each portion just fine (same user/password) but the authentication doesn't carry over i.e. if I log into / and then click a link to /blog/, /blog/ thinks I'm Anonymous and prompts for login again. I've done the basics

i.e.

  1. Identical <authentication mode="Forms"> in both the site as well as app web.configs
  2. Identical <machineKey> section (yes, identical validationKey and decryptionKey)

So I then inspected the cookies generated and noticed that website and the web application seem to be working on different cookies.

Cookies created by website.com/blog

  • .ASPXFORMSAUTH-27604f05-86ad-47ef-9e05-950bb762570c
  • .ASPXROLES

Cookies created by website.com

  • .ASPXFORMSAUTH

I think this is the problem, although I see it despite having identical <authentication> sections which looks like

<authentication mode="Forms">
    <forms timeout="30" slidingExpiration="true" name=".ASPXFORMSAUTH" enableCrossAppRedirects="true" protection="All" cookieless="UseCookies"/>
</authentication>

I did read several other posts like Single Sign On with Forms Authentication as well as http://msdn.microsoft.com/en-us/library/eb0zx8fc.aspx

There were also a few other posts I can't recall now. I've gone through them (all?) but am still stuck. I can gladly supply more debug data if needed.

Would really appreciate any tips someone might have! I think I'm hitting a wall on this one!

Crafton answered 8/10, 2011 at 2:4 Comment(0)
C
2

Ok, so I was able to answer my own question after beating around it for longer.

Basically, BlogEngine.NET 2.5 (my web-app) seems to be overriding the .NET 4.0 framework way of doing things. There are a couple of things you need to fix, all within BlogEngine.Core\Security\Security.cs (download the BlogEngine.NET source code)

Part 1: Fix cookie name

In there is a method FormsAuthCookieName which I changed as follows:

File: BlogEngine.Core\Security\Security.cs
Method: FormsAuthCookieName()
// return FormsAuthentication.FormsCookieName + "-" + Blog.CurrentInstance.Id.ToString();
return FormsAuthentication.FormsCookieName;

This ensures that the cookie names are the same. One hurdle down ...

Part 2: Avoid web-app/BlogEngine.NET's login page/controls/code

Instead of directing users log into the BlogEngine.Net's login.aspx (www.website.com\blog\account\login.aspx), I pointed all login links to my main website's login.aspx page (www.website.com\login.aspx). In case you're wondering how to implement you own site-wide authentication, this is a super-quick guide

msdn.microsoft.com/en-us/library/ff184050.aspx. 

I also had to add something like this to both the website web.config as well as the web-app web.config, so anytime a protected resource is accessed (from website or web app) my own global /login/aspx is used.

<authentication mode="Forms">
<forms timeout="30" loginUrl="/login.aspx" blah blah />
</authentication>

Now, my own generic, site-wide user login controls will be creating the (.NET framework standard) authentication cookies and the (user) role cookies. By avoiding the BlogEngine.NET's login.aspx we're cleaner plus we avoid calling this code which is problematic.

File: BlogEngine.Core\Security\Security.cs
Method: AuthenticateUser(string username, string password, bool rememberMe)

Details:That code adds a "blog instance" into the cookie, so so if you have multiple blogs on the same domain, this prevents user1 authenticated on blog instance 1 from NOT being automatically authenticated on blog instance 2. I'm guessing most will only have one blog per domain (www.domain.com\blog!), so this is unnecessary. More importantly, that check breaks our single sign-on.

Two hurdles down ...

Part 3: Fix Per-access authorization check

Now, our site wide, standardized login.aspx doesn't add the specific BlogEngine.NET instance ID (see above). This would have been ok, except that there is still some BlogEngine.NET code that specifically looks for that. We don't need that check either, so lets remove that offending check...

File: BlogEngine.Core\Security\Security.cs
Method: void Init(HttpApplication context)
// Comment line below to revert to only-framework/default processing
//context.AuthenticateRequest += ContextAuthenticateRequest;

So at this point you should have

  • All logins handled by a single, site wide login.aspx
  • All authentication cookies and user role cookies created by the above site wide login.aspx
  • All such cookies encrypted and protected per of both the website & web-app web.configs (which should match!)

Which in turn allows single sign on :) !! Hooray !

Crafton answered 11/10, 2011 at 5:51 Comment(1)
I'd suggest seeing if you can't make your changes configuable and get it accepted by the maintainers. Seems to me that it's mainly a trade off between multiple engines on the same domain, and single sign on -- you might have to choose one or the other, but users shouldn't have to debug in order to get it working...Rowboat
N
1

In addition: in both web.configs you must insert machinekey with the same validationKey and the same decryptionKey.

Nonparticipation answered 6/1, 2013 at 20:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.