2016-06-20 3 views
3

У меня есть приложение с несколькими арендаторами, где каждый арендатор может определять свои собственные MetaData URl, ClientId, Authority и т. Д. Для WsFed или OpenIdConnect (Azure) или Shibboleth (Kentor). Все жильцы, хранятся в таблице БД и зарегистрирован в OwinStartup, как показано ниже:Аутентификация с несколькими арендаторами с использованием OWIN-конвейера

 // 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; 
     } 
    } 

Когда несколько orgnaizations от одного поставщика (ADFS, Azure или Shibboleth) включены в Дб, я получаю ошибки. Я попробовал «app.Map», чтобы расширить его. Но безуспешно. Кроме того, я использую ниже код для выхода из системы для всех поставщиков (ADFS и Azure), но выход из системы также выходит из строя.

Провайдер уникален Тип аутентификации, который я использую в разных организациях.

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

Ищет помощь/руководство. Примечание: всякий раз, когда новый арендатор добавляется, отлично подходит для утилизации appdomain, не требуется динамическая перестройка трубопровода, чтобы сделать вещи сложными.

ответ

0

Средство промежуточного программного обеспечения Kentor.AuthServices поддерживает несколько экземпляров, но для каждого из них вам необходимо назначить конкретный ModulePath. Без этого первое промежуточное ПО Kentor.AuthServices будет обрабатывать все входящие запросы и выдавать ошибки для сообщений от IdentityProviders, которые настроены с другими экземплярами.

Я знаю, что некоторые другие поставщики Katana имеют похожие «скрытые» конечные точки, которые используются во время обратного вызова, но я не знаю, как они ведут себя, если загружаются несколько экземпляров промежуточного программного обеспечения.

В качестве альтернативы промежуточное программное обеспечение Kentor.AuthServices также поддерживает наличие нескольких поставщиков удостоверений, зарегистрированных одним экземпляром. Затем вы можете добавлять и изменять экземпляры IdentityProvider во время выполнения до KentorAuthServicesAuthenticationOptions и вступать в силу немедленно. Однако это может быть не идеальным решением, если вы используете одно промежуточное ПО для каждого арендатора для других протоколов.

+0

Вы можете показать некоторый фрагмент о том, как добавить путь к модулю – Saravanan

+0

Это свойство в 'SPOptions' –

+0

Для разных провайдеров мне нужно предоставить соответствующие авторизации здесь из IDP? – Saravanan

0

Не было бы возможно создать различные Owin трубопроводы за арендатором на основе условия в app.MapWhen («tenant1», CTX => ctx.configureSpecificTenant)

MapWhen также принимает функцию, так что вы могли бы основать его на каком-то другом условии, таком как субдомен с итерацией foreach в списке.

+0

Вы можете поделиться рабочим фрагментом. tenant1 может быть идентифицирован только по URL-адресу. т. е. http: //......../tenant1. Поэтому, основываясь на том, что мне нужно сопоставить параметры конвейера, которые у меня есть, и загрузить их – Saravanan

+0

У меня нет рабочего фрагмента, но я бы попробовал что-то вроде: var tenants = new Список () {new Tenant() {Subdomain = новый субдомен («organisation2»)}}; var tenantFromContextParser = новый TenantFromContextParser(); Еогеасп (вар арендатором жильцов) { portalApp.MapWhen (CTX => tenant.Subdomain == tenantFromContextParser.ParseFromHost (CTX) .OrganisationPart, perTenantApp => { perTenantApp.configurePerClient (.....); }); } –

 Смежные вопросы

  • Нет связанных вопросов^_^