Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change OWIN Auth Middleware Per Request (Multi-tenant, oauth API keys per tenant)

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?

like image 263
kingdango Avatar asked Aug 19 '14 21:08

kingdango


1 Answers

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");
}
like image 97
Joe Audette Avatar answered Nov 07 '22 04:11

Joe Audette