3
votes

I'm just getting started with Umbraco and the idea is to have a site (running under Umbraco) with documentation for another site. But the requirement is that you can't see anything on the documentaion site unless you are logged in at the main site.

So on my main site, when you login you get an .ASPXAUTH cookie. What do I need to do on the Umbraco side to be able to read that and check it's validity (really, knowing the data embedded in the cookie, for example the user's identity isn't actually important right now) and if not valid (or not present) it should redirect you to the main site to login (I don't want to recreate the same login process in Umbraco).

What's the right way to approach this? I've seen links about creating a MembershipProvdier in Umbraco, but I don't want to recreate the whole thing. I just need to know that you have the cookie and it is a legimate one created by the main site.

I can put both sites on the same domain, so all I really need the Umbraco side to do is read the cookie and confirm that it's valid and only show a certain page of content if that is true. I can create my own MembershipProvider that would let me implement ValidateUser, but I need to hook the process sooner. I need to hook into where Umbraco decides if a user is signed in or not.

Edit: I might be making some progress here, but I'm not quite there. I created a controller that inherits from RenderMvcController and added a custom AuthorizeAttribute:

public class CustomUmbracoDefaultController : Umbraco.Web.Mvc.RenderMvcController
{
    [TestAuthorize]
    public override ActionResult Index(RenderModel model)
    {
        return base.Index(model);
    }
}

public class TestAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        return base.AuthorizeCore(httpContext);
    }
}

And I added a startup handler to set the default controller type:

public class StartupHandler : ApplicationEventHandler
{
    protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    {
        DefaultRenderMvcControllerResolver.Current.SetDefaultControllerType(typeof(Controller.CustomUmbracoDefaultController));
    }
}

and then in the settings:

<authentication mode="Forms">
  <forms loginUrl="http://localhost:6550/account/Login" protection="All" path="/" />
</authentication>

Where localhost:6550 is my other application (the one that actually does the login).

When I start up my Umbraco application (http://localhost:7539) it redirects to the login page (great!) but after logging in and getting the .ASPXAUTH any attempt to go back to localhost:7539 is still going to redirect me back to the login page.

So what am I still missing? Where can I get it to see the .ASPXAUTH cookie and accept it?

Edit: Just for fun I tried this:

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    var cookie = httpContext.Request.Cookies[".ASPXAUTH"];
    if (cookie == null)
    {
        return base.AuthorizeCore(httpContext);
    }
    return true;
}

When I first come in cookie is null as expected and you are kicked to the login page (on a different port). After login I can see the .ASPXAUTH cookie is set (still on port 6550). When I then put the port for Umbraco back in, I when it hits AuthorizeCore, the .ASPXAUTH cookie is still null? So it will loop back to the login page again. If I skip the null check and just return true, my Umbraco page loads and looking in my browser I can see the .ASPXAUTH cookie is there. So why couldn't I see it in AuthorizeCore?

1
You won't be able to share cookies across sites, unless perhaps they exist in the same domain. - DavidG
@DavidG: Yeah, I'm aware they'd need to be in the same domain to share cookies. Or else I need some other way to communicate between them. - Matt Burland
If however you want single sign-in across sites, even across domains, you may want to use something like Identity Server. - DavidG
You could expose your Umbraco data through WebAPI and query it from your site. That way you could keep you Membership validation on you site and create a service to connect to the Umbraco API. To secure the Umbraco API you would just need to create a internal login process between your two sites, either token or user and password. - Mario Lopez
@MarioLopez: API might be usable, but I need to be able to get it to spit out the rendered page that I can then display to the user on my site. The UmbracoCms.RestApi package doesn't seem to do that. - Matt Burland

1 Answers

0
votes

Ok, the missing ASPXAUTH cookie part I solved. I had to match the machineKey entries in my original project and my Umbraco project. I guess if it can't decode the cookie, it'll just be ignored.

So now is that fact that a cookie exist that is able to be decoded with my machine key enough to confirm that the user is logged in? For the Umbraco side I absolutely don't care who is logged in, just that they are logged in.