2

I have an application that supports subdomains. Each subdomain represents a company and thus each subdomain potentially looks and feels like an extension of their own website.

This is done using a companyId which is obtained by this method:

/// <summary>
/// Get our company based from the URI host
/// </summary>
/// <returns>A company</returns>
public Company GetTenant()
{
    var host = ConfigurationManager.AppSettings["domain"];
    var currentHost = HttpContext.Current.Request.Headers["HOST"];
    var defaultUri = GetUriFromUrl(host);
    var currentUri = GetUriFromUrl(currentHost);

    foreach (var company in this.GetAll("Settings"))
        if (CheckCompanyByUri(company, currentUri))
            return company;

    if (!currentUri.IsLoopback && !CompareUrls(currentUri, defaultUri))
        throw new Exception("The URL you have specified is not in our systems: " + currentUri.Host);

    return null;
}

So, I have now built an api and want to use OAuthAuthorizationServerOptions but the problem is that the Users for each company are different and are obtained by using the CompanyId.

static Startup()
{
    using (var uow = new UnitOfWork<SkipstoneContext>())
    {
        var service = new CompanyService(uow, null);
        var company = service.GetTenant(); // HttpContext is not available at this point (so getting the url is impossible)


        if (company != null)
        {
            var companyId = company.Id;

            UserService = new UserService(uow, null, companyId);
            PublicClientId = companyId;

            OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = new ApplicationOAuthProvider(PublicClientId, UserService),
                AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                AllowInsecureHttp = true
            };
        }
    }
}

I don't have access to HttpContext from the Startup class, so is there anyway I can actually get access to the current requested URL from startup?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
r3plica
  • 13,017
  • 23
  • 128
  • 290
  • possible duplicate of [Is it possible to make an ASP.NET MVC route based on a subdomain?](http://stackoverflow.com/questions/278668/is-it-possible-to-make-an-asp-net-mvc-route-based-on-a-subdomain) – Iain Ballard Feb 25 '14 at 08:50

2 Answers2

1

This isn't available at startup. You will either need to setup separate Virtual Directories in IIS (if you're using it) and have actual different apps handling each virtual directory.

Otherwise you will need to filter on each individual request (most webframeworks have some kind of routing engine for this).

Iain Ballard
  • 4,433
  • 34
  • 39
  • I can't use Virtual Directories because a company can be set up at anytime with any subdomain. The filter you mention, how will that solve my issue? – r3plica Feb 24 '14 at 11:13
  • the entire Url being requested is only available at request time. If you can tell me what web framework you are using, I may be able to help further. – Iain Ballard Feb 24 '14 at 12:08
  • In that case, this is probably a duplicate of ( http://stackoverflow.com/questions/278668/is-it-possible-to-make-an-asp-net-mvc-route-based-on-a-subdomain ), which has been answered. – Iain Ballard Feb 25 '14 at 08:50
  • I don't think routing is the issue here. I have already handled routing for my subdomains. The problem is that I need the company Id when I try to instantiate the UserService – r3plica Feb 25 '14 at 12:46
  • If the subdomains are being added at run time, you're going to have to instantiate a UserServer at request time -- there is just no way of knowing at startup what might be called later on. – Iain Ballard Feb 25 '14 at 13:30
  • Shame, I am going to have to see if I can rework the .net OAuth stuff then. Because I need access to the company collection...... – r3plica Feb 25 '14 at 13:58
0

Startup runs, as its name points out, on startup of your application. It's the entry point of the web application. It sets up the stack of middleware, including your application as the last item in the stack. This means, there is not necessarily any request at that stage.

What you want is to write a middleware that you will plug at the begining of the OWIN pipeline.
In that middleware, you can intecept the request, analyze any parameters you want, and redirect your user before you hit any of you application code.

Is that of any help?

EDIT

pseudo code example :

 public class MyMiddleware : OwinMiddleware
 {
    public MyMiddleware(OwinMiddleware next)
        : base(next) { }

    public override Task Invoke(IOwinContext context)
    {
        //Analyze the request. 
        //find the client id
        //RedirectToClientSpecificUrl?
    }
 }

in startup :

 app.Use<MyMiddleware>();

But you will probably find more relevant examples with some quick google fu :
Here he deals with authentication, and has a redirect in the middleware : http://blog.tomasjansson.com/owin-middleware/

Stéphane
  • 11,755
  • 7
  • 49
  • 63
  • Is there any example you can point me towards? If there is such an example that may help me write something :D – r3plica Feb 28 '14 at 16:21