4

各テナントが WsFed または OpenIdConnect(Azure) または Shibboleth(Kentor) の独自のメタデータ URl、ClientId、Authority などを定義できるマルチテナント アプリケーションがあります。すべてのテナントは DB テーブルに格納され、以下のように OwinStartup に登録されます。

        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        // Configure the sign in cookie

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            //  CookieName = "Kuder.SSO",
            LoginPath = new PathString("/Account/Login-register"),
            Provider = new CookieAuthenticationProvider
            {
                //Enables the application to validate the security stamp when the user logs in.
                //This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });

        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

    OrganizationModel objOrg = new OrganizationModel();
    var orgList = objOrg.GetOrganizationList();
    foreach (OrganizationModel org in orgList)
    {
        switch (org.AuthenticationName)
        {
            case "ADFS":
            WsFederationAuthenticationOptions objAdfs = null;
             objAdfs = new WsFederationAuthenticationOptions
                {
                    AuthenticationType = org.AuthenticationType,
                    Caption = org.Caption,
                    BackchannelCertificateValidator = null,
                    MetadataAddress = org.MetadataUrl,
                    Wtrealm = org.Realm,
                    SignOutWreply = org.Realm,
                    Notifications = new WsFederationAuthenticationNotifications
                    {
                        AuthenticationFailed = context =>
                        {
                            context.HandleResponse();
                            Logging.Logger.LogAndEmailException(context.Exception);
                            context.Response.Redirect(ConfigurationManager.AppSettings["CustomErrorPath"].ToString() + context.Exception.Message);
                            return Task.FromResult(0);
                        }
                    },
                    TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false },
                };
             app.UseWsFederationAuthentication(objAdfs);
                break;
            case "Azure":
                OpenIdConnectAuthenticationOptions azure = null;
                azure = new OpenIdConnectAuthenticationOptions
                {
                    AuthenticationType = org.AuthenticationType,
                    Caption = org.Caption,
                    BackchannelCertificateValidator = null,
                    Authority = org.MetadataUrl,
                    ClientId = org.IDPProvider.Trim(),
                    RedirectUri = org.Realm,
                    PostLogoutRedirectUri = org.Realm, 
                    Notifications = new OpenIdConnectAuthenticationNotifications
                    {
                        AuthenticationFailed = context =>
                        {
                            context.HandleResponse();
                            Logging.Logger.LogAndEmailException(context.Exception);
                            context.Response.Redirect(ConfigurationManager.AppSettings["CustomErrorPath"].ToString() + context.Exception.Message);
                            return Task.FromResult(0);
                        }
                    },
                    TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false },
                };
                app.UseOpenIdConnectAuthentication(azure);
                break;
            case "Shibboleth":
                var english = CultureInfo.GetCultureInfo("en-us");
                var organization = new Organization();
                organization.Names.Add(new LocalizedName("xxx", english));
                organization.DisplayNames.Add(new LocalizedName("xxx Inc.", english));
                organization.Urls.Add(new LocalizedUri(new Uri("http://www.aaa.com"), english));

                var authServicesOptions = new KentorAuthServicesAuthenticationOptions(false)
               {
                   SPOptions = new SPOptions
                   {
                       EntityId = new EntityId(org.Realm),
                       ReturnUrl = new Uri(org.Realm),
                      Organization = organization,
                   },
                   AuthenticationType = org.AuthenticationType,
                   Caption = org.Caption,
                  SignInAsAuthenticationType = "ExternalCookie",
               };
                authServicesOptions.IdentityProviders.Add(new IdentityProvider(
                new EntityId(org.IDPProvider), authServicesOptions.SPOptions)
                 {
                     MetadataLocation = org.MetadataUrl,
                     LoadMetadata = true,
                    SingleLogoutServiceUrl = new Uri(org.Realm),
                 });
                app.UseKentorAuthServicesAuthentication(authServicesOptions);
                break;
            default:
                break;
        }
    }

Db で同じプロバイダー (ADFS、Azure、または Shibboleth) の複数の組織が有効になっていると、エラーが発生します。「app.Map」を拡張してみました。でも失敗しても。また、以下のコードを使用してすべてのプロバイダー (ADFS および Azure) をログアウトしますが、ログアウトも失敗します。

プロバイダーは、組織全体で使用する独自の認証タイプです。

HttpContext.GetOwinContext().Authentication.SignOut(provider, Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie, DefaultAuthenticationTypes.ExternalCookie);

ヘルプ/ガイダンスを探しています。注: 新しいテナントが追加されるたびに、appdomain を再利用しても問題ありません。複雑にするためにパイプラインを動的に再構築する必要はありません。

4

2 に答える 2

0

Kentor.AuthServices ミドルウェアは複数のインスタンスをサポートしていますが、ModulePathそれぞれに固有のものを割り当てる必要があります。それがないと、最初の Kentor.AuthServices ミドルウェアがすべての受信リクエストを処理し、他のインスタンスで構成された IdentityProviders からのメッセージでエラーをスローします。

他の一部の Katana プロバイダーには、コールバック中に使用される同様の「隠し」エンドポイントがあることは知っていますが、複数のミドルウェア インスタンスがロードされた場合にそれらがどのように動作するかはわかりません。

別の方法として、Kentor.AuthServices ミドルウェアは、1 つのインスタンスに複数の ID プロバイダーを登録することもサポートしています。次に、実行時に IdentityProvider インスタンスを に追加および削除して、KentorAuthServicesAuthenticationOptionsすぐに有効にすることができます。ただし、他のプロトコル用にテナントごとに 1 つのミドルウェアを使用している場合、これは理想的なソリューションではない可能性があります。

于 2016-06-21T07:31:58.390 に答える
0

app.MapWhen("tenant1", ctx=> ctx.configureSpecificTenant) の条件に基づいて、テナントごとに異なる owin パイプラインを作成することはできませんか?

MapWhen は関数も受け入れるため、リストに foreach 反復があるサブドメインなど、他の条件に基づいて関数を作成することもできます。

于 2016-06-29T07:56:35.270 に答える