Change OWIN Auth Middleware Per Request (Multi-ten

2019-02-02 19:21发布

问题:

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:

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");
}