2014-06-26 19 views
7

Projemizde OWIN (FB, google, Canlı girişler dahil) kullanan bir beyaz etiket oluşturmaya çalışıyoruz. API kimlik bilgilerini dinamik olarak kurmanın bir yolu var mı, ayarları değiştirecekleri alanı değiştirdiklerini söyleyin.Kurulum OWIN dinamik olarak (etki alanına göre)

Owin yüklerini MVC'den daha erken düşünüyorum? Global.asax (Request) üzerine yükleyebileceğimiz bir yol var mı?

public partial class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     ConfigureAuth(app); 
    } 
} 

GÜNCELLEME: Başka bir deyişle

birçok ve alt alanları (beyaz etiketleme) ev sahipliği yapacak tek Uygulaması.

cevap

5

Bugün aynı şeyleri araştırıyorum. Daha sonra OWIN'in dallanma özelliklerini açıklayan http://aspnet.codeplex.com/SourceControl/latest#Samples/Katana/BranchingPipelines/BranchingPipelines.sln numaralı telefondan güzel bir OWIN örneği buldum. Bu örneği doğru olarak anlarsam, ana bilgisayar başlığı, çerez, yol veya app.Map() veya app.MapWhen() yöntemlerini kullanarak yapılan istek parametrelerine bağlı olarak farklı OWIN yığınlarını yapılandırabilmeniz gerekir.

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 

     app.MapWhen(ctx => ctx.Request.Headers.Get("Host").Equals("customer1.cloudservice.net"), app2 => 
     { 
      app2.UseWsFederationAuthentication(...); 
     }); 
     app.MapWhen(ctx => ctx.Request.Headers.Get("Host").Equals("customer2.cloudservice.net"), app2 => 
     { 
      app2.UseGoogleAuthentication(...); 
     }); 
    } 
} 
1

Bir Microsoft'a üzerinde çalışıyorum:

Diyelim ki farklı giriş yapılandırmasında ile 2 müşterisini temsilen 2 farklı DNS etki var diyelim, ana bilgisayar başlığı değerine bağlı olarak farklı yapılandırmaları kullanmak Owin başlatabilir Bir geliştiricinin owin uygulamalarını enjekte etme yeteneğini desteklemek için AuthenticationOptions'ta (ör. GoogleAuthenticationOptions) çok kiracılığa izin veren .Owin.Security tasarım değişikliği.

İşte Katana proje ekibine benim öneri: https://katanaproject.codeplex.com/discussions/561673

Ben de mevcut Microsoft.Owin.Security altyapı üzerine oturur ve benim tasarım değişikliği önerisi yarar olmayan bir çalışma uygulaması var. Auth Middleware'in kendi sürümünüzün yuvarlanmasını gerektirir (mevcut kopyala yapıştır), ancak tasarım değişikliğimi Microsoft'a uygulayana kadar geçerli bir geçici çözümdür.

https://github.com/kingdango/Owin.OAuth.Multitenant

Sonuçta ben sadece çok kullanıcılı olma desteklemek için her kiracı için birden Owin boru hatlarını geliştirmek için mantıklı sanmıyorum (Bu Sadece bu sabah onu kalkıp, pürüzlü olabilir). Doğru çözüm, genişletilebilir olan middleware'e sahip olmak ve önerdiğim şey bu.

+0

Bu konuyla ilgili birkaç yazıyla karşılaştım. Sadece bununla nasıl gittiğini merak ederek, uygulamadaki appID ve ilişkili sırrı değiştirmem gerekiyor. Owin, zamanın başlangıcında başlatıldığından, denetleyicideki hiçbir şeyi değiştiremiyorum. – user3836415

3

Sadece bunu yapmaya çalışırken bir alıştırma yaptım. Ne yazık ki, başlangıçtan sonra Katana tabanlı bir ana bilgisayara doğrudan middleware enjekte etmenin bir yolu yoktur. Bunun nedeni, middleware'in gerçekte kullanılması için, application delegate'a birlikte oluşturulması gerektiğidir. Katana'nın uygulaması, IAppBuilder.Build(typeof(AppFunc)) numaralı telefonu arayarak, AppFunc uygulama başlatma için belirtilen türde bir takma ad kullanıyor: Func<IDictionary<string,object>, Task> Başlatma tamamlandığında. İşte .Initialize altındaki anahtar çizgi:

AppFunc = (AppFunc)builder.Build(typeof(AppFunc)); 

Eğer ortakatmanını yapılandırmak zorunda tek fırsat yazdığınız başlangıç ​​sınıfında veya web.config tarafından yapılandırma adımı sırasında, bu öncedir.

Sadece eser, böyle bir şey ile deneme değildi ne olacağına dair çok net olması: Bu istisnalar atmak değildir ve hataların belirgin işaretler

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     HomeController.Initialized +=() => ConfigureGoogle(app); 
    } 

    private void ConfigureGoogle(IAppBuilder app) 
    { 
     app.UseGoogleAuthentication(/* stuff */); 
    } 
} 

public class HomeController : Controller 
{ 
    public event EventHandler Initialized; 

    [Route("/setup/submit"), AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult SetupSubmit() 
    { 
     /* ... */ 

     Initialized(); 
    } 
} 

- ama işe yaramaz çünkü uygulama temsilcisi zaten bu noktadan oluşuyordu. Katana, uygulama temsilcisini yeniden oluşturmak için size herhangi bir API vermez (ve bunun zaten iyi bir fikir olacağından emin değilim - böyle bir mekanizma tarafından yaratılabilecek sayısız hata olabilir, örneğin; Sunucunun başlatılmasından sonra uygulama temsilcisi yeniden oluşturulduğunda sunucu bir uçuş isteğini işliyor mu?).

Senin alternatifin nedir? DavidFahlander'in yaklaşımı doğru olanı olacak, ancak dinamizme ulaşmak için hala dikkatli olmanız gerekiyor. .MapWhen ne bak:

// put middleware in pipeline before creating branch 
var options = new MapWhenOptions { Predicate = predicate }; 
IAppBuilder result = app.Use<MapWhenMiddleware>(options); 

// create branch and assign to options 
IAppBuilder branch = app.New(); 
configuration(branch); 
options.Branch = (AppFunc)branch.Build(typeof(AppFunc)); 

Birincisi, bu bir MapWhenMiddleware tip app.Use çağırır dikkat edin. Bu, daha önce olduğu gibi aynı sınırlamalarla karşı karşıya olduğunuz anlamına gelir - her şey ön tarafta yapılmalıdır. Başlatma tamamlanmadan önce dallı ara katman da pişirilir: son satırına bakın: branch.Build.

Tek dinamizm umudunuz, yüklemleri amacınıza ulaşacak şekilde kullanmaktır. Bu size orada yol% 100 almaz, ama yakın oldukça lanetlemek alır:

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 

     app.MapWhen(ctx => ClientHasWsFederationConfigured() && ctx.Request.Headers.Get("Host").Equals("customer1.cloudservice.net"), app2 => 
     { 
      app2.UseWsFederationAuthentication(...); 
     }); 
     app.MapWhen(ctx => ClientHasGoogleAuthConfigured() && ctx.Request.Headers.Get("Host").Equals("customer2.cloudservice.net"), app2 => 
     { 
      app2.UseGoogleAuthentication(...); 
     }); 
    } 
} 

sınırlamalar burada bunlar olacak: Sen tüm desteklenen kimlik doğrulama türlerini yapılandırmak zorunda

  • -ön. Uygulama çalışırken yeni bir tane ekleyemezsiniz. Her istekte
  • ClientHasXXXConfigured çalışır. Bu, ne yaptığınıza bağlı olarak, performans bazında kabul edilebilir veya kabul edilmeyebilir.

söz konusu koymak bilgilerden yola, sana ClientHasXXXConfigured (veya eşdeğer) ne hakkında dikkatli konum olarak bu ödünleşmeler sürece muhtemelen Tamam olduğunu düşünüyorum.

0

Bu çalışmayı başarmayı başardım. Sorun, MapWhen'in yürütme sırasının sırasına göre, kişinin nasıl olduğunu düşündüğü gibi çalışmıyor. Unutulması gereken önemli nokta, yapılandırma (yani, MapWhen'in ikinci parametresi) uygulama başlatılırken ve önbelleğe alındığında saklanması gereken önemli bir husustur. Bu nedenle, ihtiyacınız olan konfigürasyonları dikkatlice düşünmek ve her bir benzersiz konfigürasyon için ayrı bir 'app.MapWhen' çalıştırmak önemlidir. Birden çok etki alanı kullanıyorsanız ve her biri aynı yapılandırmayı kullanırsa, bunu yapmanız gerekmez, ancak her yapılandırma etki alanı başına benzersizse, her biri için bir MapWhen çalıştırmanız gerekir. Benim durumumda, OpenIDConnect'in her biri için benzersiz bir AppID gerektirdiğinden, her bir alana benzersiz bir konfigürasyon vermem gerektiğinden bunları bir foreach bloğuna yerleştirmeyi daha kolay buldum.

MapWhen'in ilk parametresi bir koşullu döndüren bir işlevdir. Eğer doğru olarak değerlendirilirse, ilgili konfigürasyonu bu noktada zaten oluşturulacak olan bir önbellekten döndürecektir. Bu her zaman daha önce yanlış olarak döndürülürse ve aniden doğru olarak döndürürse, yeni yapılandırmalar oluşturulmaz. Bu koşullu işlevin istek başına yürütüldüğünden, mümkün olduğunca hızlı ve hafif tutulmalıdır.

var domains = new string[] { "abc.com", "def.com" }; 
var host = HttpContext.Current.Request.ServerVariables["HTTP_HOST"]?.ToLower(); 
foreach (string domain in domains) 
{ 
    if (!ShouldEnableForDomain(domain) continue; 
    app.MapWhen(
     context => host == domain, //if true a config will be used from the cache 
     config => 
     { 
      //This executes once on app startup (per domain) and will be cached - it is not executed in the context of a request 
      Trace.WriteLine(String.Format("Setting up configuration: {0}", domain)); 
      config.UseOpenIdConnectAuthentication(GetOpenIdOptions(domain)); 
     } 
    ); 
}