10
votes

I have a multi-tenant application. Each tenant can authenticate its users using OAUTH-2 with Facebook, Twitter, Google, etc. Each tenant has its own API keys for the aforementioned services.

The typical way to setup the OWIN pipeline is to "use" auth providers in Startup but this sets the API keys at app start. I need to be able to change which keys are used with each oauth API for each request.

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            Provider = cookieAuthProvider,
            CookieName = "VarsityAuth",
        });

        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        app.UseMicrosoftAccountAuthentication(
            clientId: "lkjhlkjkl",
            clientSecret: "kjhjkk");

I need to be able to change these settings per request based on the tenant. How can I do this?

1
So far I've hit a roadblock. It seems the typical implementation of AuthenticationOptions (e.g. FacebookAuthenticationOptions) is marked internal and the Facebook auth middleware uses FacebookAuthenticationOptions (instead of an interface). Thus, it's not possible to override the AppId and AppSecret properties of FacebookAuthenticationOptions and therefore I've had to roll my own almost identical version of the Facebook Auth middleware. :( (sad panda)kingdango
Hello, I just asked a similar question where I need to use multiple OpenIdConnect configurations depending on who the tenant is. If you could share some code snippets on how you are handling this, that would be awesome! For your reference, is my question: stackoverflow.com/questions/25417620/…Anup Marwadi
Hi kingdangoless, please share your solution. The community will be ever grateful.MichaelS

1 Answers

9
votes

Edit - I can now confirm this solution is working for me.

I'm investigating this problem for my own project which needs to support multi tenants based on either the host name or the first folder segment of the request depending on configuration.

I have not yet tested this but I'm thinking code something like this in startup might do the trick:

for example I want to use a different auth cokie name per tenant, and I'm thinking code in startup something like this might work:

// for first folder segment represents the tenant
app.Map("/branch1", app1 =>
{
    app1.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider
       {
            OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<SiteUserManager, SiteUser>(
            validateInterval: TimeSpan.FromMinutes(30),
            regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
    },

        CookieName = "branch1-app"
    });

});

// for when the host name of the request identifies the tenant
app.MapWhen(IsDomain1, app2 =>
{
    app2.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider
        {
            OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<SiteUserManager, SiteUser>(
            validateInterval: TimeSpan.FromMinutes(30),
            regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
        },

        CookieName = "domain1-app"
    });

});

private bool IsDomain1(IOwinContext context)
{
    return (context.Request.Host.Value == "domain1");
}